Is there a correct way to open raw sockets without setuid?

For executables that work with raw sockets (like `mtr' for example), is there a preferred existing mechanism to use it without setuid?
(in some way something like cap_net_raw on Linux to open socket for raw access)
 
Not sure what qualifies as a socket protocol (can ICMP be considered one?), but yes, in this case programs like ping/traceroute/mtr use socket API which usually requires additional privileges. The goal is to delegate minimum permissions rather than all (i.e. granular permissions for net raw access instead of full root access with setuid).
 
1. Privileged Ports (0–1023)

Programs must have root privileges to bind a socket to any port number below 1024.

  • Protocols affected: Both TCP and UDP.
  • Purpose: This restriction prevents unprivileged users from impersonating standard system services like HTTP (80), SSH (22), or SMTP (25).

2. Raw Sockets (SOCK_RAW)

Creating a "raw" socket requires root privileges.

  • Protocols affected: ICMP (used by ping), OSPF, IGMP, and custom IP-layer protocols.
  • Capabilities: Raw sockets allow a program to bypass the standard transport layers (TCP/UDP) and construct its own IP headers or interact directly with other network layer protocols.
  • System Restriction: By default, FreeBSD Jails further restrict raw socket access even for root users within the jail unless explicitly enabled via allow.raw_sockets
When privileges are NOT needed

You can send and receive UDP data as a normal user if:

  • Unprivileged Ports: You are binding to or sending from a local port number between 1024 and 65535.
  • Standard Sockets: You use a standard datagram socket (SOCK_DGRAM).
 
> IIRC freebsd ping sandboxes

I thought a bit about sandboxing with Capsicum. Let’s look at it: a setuid'ed program drops all privileges ASAP after starting (i.e. it opens raw sockets and drops suid privileges in the case of setuid, drops all extra capabilities in the case of cap_net_raw, or enters sandbox mode with cap_enter()). This is more or less the same approach: dropping extra permissions immediately upon startup. The main difference (for a binary that needs raw sockets) is that in the case of setuid+Capsicum the executable remains a setuid binary, whereas in the case of cap_net_raw it is not.
If it's described correctly, then a need-raw-socket-executable-file is still setuid'ed even using Capsicum for further sandboxing.
 
Back
Top