如何解决 "setsockopt(3, SOL_SOCKET, SO_MARK, [10], 4) = -1 EPERM" 根用户 none 操作被拒绝的问题

How to resolve "setsockopt(3, SOL_SOCKET, SO_MARK, [10], 4) = -1 EPERM" Operation denied for none root users

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

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

正如我通过 strace 发现的:'-1 EPERM Permission denied'(如 http://man7.org/linux/man-pages/man7/capabilities.7.html 所示,此命令需要 cap_net_admin 权限) 当我在命令前面使用 "sudo" 时,该工具工作,套接字是使用 none 默认网关创建的,并且按预期工作(例如 wget 文件)

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

我在网上找到并尝试过的一些东西:

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

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

您可以尝试 retro-solution 解释的 here,它会覆盖 bind() 和 connect() 而不是 socket()。

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