考虑一个server
绑定到“*”并监听传入连接的程序。我只server
从本地主机连接,我不希望外部用户能够连接到它。但是,该server
程序编写得很糟糕,没有提供仅绑定在本地主机上的配置选项或标志。此外,我很难破解源代码来server
解决这个问题。
因此,我将寻找一个要运行的包装器server
,但使其绑定在本地主机上而不是“*”上。 (例如,也许基于 LD_PRELOAD 的技巧可以完成这项工作,例如tsocks
强制在第三方程序上使用 SOCKS 代理。)这样的事情存在吗?我是机器上的 root,如果有帮助的话。
我知道另一种解决方案是使用 iptables,但这些规则不会在重新启动后持续存在,因此它们可能会默默地被破坏。此外,它们是“全局的”,可以被服务器的其他用户修改,或者混淆它们。相比之下,当以 运行服务器程序时wrapper server
,我更有信心设置不会因其他原因而中断。
答案1
以下是如何使用 ip 命名空间执行此操作(需要 root 权限,以下内容应以 root 身份运行)。
为服务器创建命名空间:
ip netns add myserverns
将 IP 地址分配给命名空间中的环回并将其打开(来源:这个帖子):
ip netns exec myserverns ifconfig lo 127.0.0.1 up
在命名空间中运行
server
(其中“serveruser”是应该运行服务器的用户)
ip netns exec myserverns sudo -u serveruser server
我们假设服务器侦听端口
4242
。现在,使用socat
将环回绑定到命名空间(注意它的使用bind=127.0.0.1
是整个要点)(来源:这个答案):
socat tcp-listen:4242,bind=127.0.0.1,fork,reuseaddr exec:'ip netns exec myserverns socat STDIO tcp-connect\:127.0.0.1\:4242',nofork
这实现了我的预期目标:即使server
尝试绑定到“*”(或完全绑定到不同的端口),当我们以这种方式运行它时,我们确信它只能在具有 port 的本地计算机上访问4242
。