1

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?

Dominik S.
  • 76
  • 1
  • 9
  • Make up your mind. Either run it with root privilege or don't use that syscall. You're not going to persuade the system to relax its security. – user207421 May 07 '19 at 23:58
  • This looks like C, not a script: *`setsockopt(sd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));`*. I think you need to provide a [Minimal, Complete, and Verifiable (MCVE) example](http://stackoverflow.com/help/mcve) so folks can sort out what you are doing. – jww May 08 '19 at 03:20

1 Answers1

3

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.

Erki Aring
  • 2,032
  • 13
  • 15
  • Thanks for the hint with ip netns. I've seen the documentation but my desktop environment (KDE) reacts by dropping all assigned interfaces of the connection GUI. Is there a way to let the interface be configured via GUI? I mean I can do it by console, but my parents surely can't do this without proper explanation. So it would be nice to have an GUI. I'll mark the answer as accepted for the hint. (I'm gonna use netns for my use case) – Dominik S. May 15 '19 at 20:42