在网络编程中,通常将INADDR_ANY
(或IN6ADDR_ANY
)作为第二个参数传递给绑定(),告诉网络堆栈您希望套接字从机器恰好拥有的任何网络接口接收连接/流量。许多程序都这样做,因为这通常是最有用的行为。另一个常见选项是指定要绑定到的单个网络接口。
但是,我有一个用例,我希望我的 Linux 机器上的一个特定网络接口被“保留”,即它不包含在绑定到 的套接字使用的网络接口集中INADDR_ANY
。特别是,我希望这个网络接口只能由明确绑定到其 IP 地址的套接字使用(或者可能已经执行了其他一些明确步骤来表明它们知道这个网络接口的特殊状态并希望使用它)——如果你愿意的话,可以称之为一种“套接字白名单”,以保证只有少数精心挑选的应用程序可以通过这个网络接口发送/接收流量。(如果这很重要的话,这些应用程序可能是我编写并亲自控制的)
Linux 中是否存在什么机制可以实现这一点?
我考虑过但并不完全满意的一些方法:
- 修改所有应用程序以明确绑定到它们想要使用的网络接口,而不是绑定到
INADDR_ANY
,并且不将此网络接口包括在集合中。(工作量太大,而且无论如何我可能无权修改所有这些应用程序) - 在网络接口上设置防火墙,以便只接受某些端口上的流量。(这可能有点作用,但这意味着我必须提前指定我将在接口上使用的所有端口,这将排除需要动态端口分配的软件……当然仍然有可能一些意外的应用程序“幸运”并碰巧绑定到其中一个白名单端口,这是不可取的)
- 切换到 SELinux 或具有细粒度 ACL 的类似面向安全的发行版(由于各种原因,这不是一个现实的选择)
答案1
您是否尝试过或考虑过 iptables(我知道很难准确指定要求,但可能值得尝试直到成功):
仅允许来自 IP 地址 10.0.0.1 和端口 80 的流量转发到保留的网络接口
iptables -A FORWARD -i <reserved_interface> -s 10.0.0.1 -p tcp --dport 80 -j ACCEPT
然后阻止所有其他
iptables -A FORWARD -i <reserved_interface> -j DROP
或者使用网络管理器创建一个虚拟网络接口,并将要保留的 IP 地址移动到虚拟接口,这样应用程序将无法默认绑定到它,您也可以在虚拟接口上使用防火墙规则。我会看这篇文章看看最终结果会是什么。