I developed another sniffer and find myself executing testcase through sudo. While something bad not happen, I decided to look through capabilities functionality in Linux kernel. Very interesting things written in the manual:

man capabilities

My testcase started service in privileged port range and listened on loopback interface. In the other thread tcpreplay was started to generate test traffic. So my testcase executable need the following capabilities:


and tcpreplay need only CAP_NET_RAW. Capabilities can be set and removed with setcap utility:

sudo setcap 'CAP_NET_RAW+eip' /usr/bin/tcpreplay
sudo setcap 'CAP_NET_RAW+eip CAP_NET_BIND_SERVICE+eip' ~/devel/sniffer/build/testcase

Now I can launch testcase as a regular user.

Removing capabilities:

sudo setcap -r /usr/bin/tcpreplay

Getting capabilities:

sudo getcap /usr/bin/tcpreplay

And what about this strange 'eip'... It is effective, inheritable nad permitted. Suppose you have some program, that starts another program. These keys helps to control capabilities of the child process. Let's look into concrete example. I want to launch my testcase in the CLion IDE debug session. At this point I would face the same problem - lack of privileges. I need to change capabilities to the every chain link:


Note, that CLion provide it's own JVM and GDB (my CLion is in /opt/clion, choose your's):

    -> /opt/clion/jre/bin/java
        -> /opt/clion/bin/gdb/bin/gdb
            -> /bin/bash

sudo setcap 'CAP_NET_RAW+eip CAP_NET_BIND_SERVICE+eip' /opt/clion/bin/clion.sh
sudo setcap 'CAP_NET_RAW+eip CAP_NET_BIND_SERVICE+eip' /opt/clion/jre/bin/java
sudo setcap 'CAP_NET_RAW+eip CAP_NET_BIND_SERVICE+eip' /opt/clion/bin/gdb/bin/gdb
sudo setcap 'CAP_NET_RAW+eip CAP_NET_BIND_SERVICE+eip' /bin/bash

But, wait... bash, java? Really? It can be even dangerous, than invoking sudo. You will call 'sudo' only once, but capabilities will stay here until you call 'setcap -r'. You choose...


comments powered by Disqus