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