如何解决“ setsockopt(3,SOL_SOCKET,SO_MARK,[10],4)= -1 EPERM”,没有root用户的操作被拒绝

时间:2019-05-07 22:27:10

标签: linux sockets networking linux-capabilities setsockopt

我有两个网络接口(以太网和无线局域网)。现在,我在github(https://github.com/Intika-Linux-Firewall/App-Route-Jail)上找到了一个小脚本,该脚本似乎允许我通过无默认网关路由特定的应用程序,以对流量进行一点负载均衡。

该脚本正在使用以下调用: setsockopt(sd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));

正如我通过strace所发现的那样,我得到:'-1 EPERM权限被拒绝'(如http://man7.org/linux/man-pages/man7/capabilities.7.html上所示,此命令需要cap_net_admin权限) 当我在命令前使用“ sudo”命令时,该工具即可正常工作;套接字是使用无默认网关创建的,并且按预期方式工作(例如wget文件)

示例: MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me使用默认网关(不是我想要的) sudo MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me返回无默认网关的IP(我需要但不使用sudo的IP)

我在互联网上找到并尝试过的一些内容:

  • 设置文件功能(setcap cap_net_admin + eip)(仍然需要root权限)
  • 使用SUID位(chmod u + s)(完全不变)

我希望命令在没有root特权的情况下运行,因此每个应用程序都可以使用none默认网关,但是目前我需要使用sudo来获得足够的权限才能在正确的界面上运行该命令。 要归档目标,我缺少什么?

1 个答案:

答案 0 :(得分:3)

您从错误的角度看问题。首先,您应该尝试强制应用程序绑定到正确的接口,而不是标记数据包。

您可以尝试使用解释为here的追溯解决方案,该解决方案将覆盖bind()和connect()而不是socket()。

但是更现代的解决方案是创建一个单独的网络名称空间,然后在自己的名称空间中运行应用程序。谷歌ip netns为示例。创建和设置网络名称空间仍然需要root用户,但是可以在运行应用程序之前删除这些特权。可能还有一些工具可以做到这一点。