I got two network interfaces (ethernet and wlan). Now I found a little script on github (https://github.com/Intika-Linux-Firewall/App-Route-Jail) which seems to allow me to route specific applications through the none default gateway to loadbalance the traffic a little bit.
The script is using the following call:
setsockopt(sd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
As I found out via an strace I got: ‘-1 EPERM Permission denied’ (as show on http://man7.org/linux/man-pages/man7/capabilities.7.html this command needs cap_net_admin rights) The tool works when I use “sudo” infront of the command the socket is created with the none default gateway and works like intended (e.g. wget a file)
Example:
MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me
uses the default gateway (so not what I wanted)
sudo MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me
returns the IP of the none default gateway (what I want but without using sudo)
Some things I found on the internet and tried:
- Setting File Capabilities (setcap cap_net_admin+eip) (still requires root somehow)
- Using SUID Bit (chmod u+s) (no change at all)
I expect the command to run without root privileges, so every application can use the none default gateway, but currently I need to use sudo
to gain enough permissions to run the command on the correct interface.
What am I missing to archive my goals?
Advertisement
Answer
You are looking to your problem from the wrong angle. Instead of marking the packets, you should try to force the application to bind to the correct interface in the first place.
You could try the retro-solution explained here, which overrides bind() and connect() instead of socket().
But more modern solution would be to create a separate network namespace and then run applications in their own namespace. Google ip netns
for the examples. Creating and setting up the network namespace still requires root, but these privileges can be dropped before running the application. There are likely to be tools available to do that also.