When root privileges are not enough

I’ve stumbled across an article recently describing an implementation of the traceroute utility in Go.

Interesting thing about it is that it is based on the raw sockets, allowing us to construct packets “by hand”. Running that freshly built traceroute utility on some1 of Linux distributions will fail instantly on socket creation with an error “operation not permitted” (EACCES), and even sudo won’t help.

Now section 2 of manpages describes the “socket” syscall but doesn’t provide much info about permissions; section 7 though (miscellaneous) says some interesting thing:

The typical use case is for a privileged process to set up a raw socket (an operation that requires the CAP_NET_RAW capability) …

Manpage also pointed me at the capabilies(7) which unfolded the truth - even the root account/processes/threads/files might restricted by boundaries, first making appearance back in 2.2 kernel.

The capability that is of a particular interest in this case is CAP_NET_RAW - it allows to use RAW and PACKET sockets. To read or set file capabilities getcap(8) or setcap(8) utilities might be used:

sudo setcap cap_net_raw=ep ./traceroute

=ep parameter setting is best described at the cap_from_text(3) manpage; in this case it is sufficient to know that = operator resets capabilities to the list provided2 and ep flags designate “Effective” and “Permitted” values respectively.

Setting these options allowed me to use underlying raw sockets even without superuser privileges.

  1. my home gentoo and debian computers did that; default fedora install seems to be tuned differently (probably because of overlapping selinux permissions) and sudo is sufficient there to use raw sockets. ↩︎

  2. it can be + for adding or - for removing flags, similar to the chown(1) ↩︎