前言
如果不是 Docker 而是其他程序的话,首先需要考虑的是直接把程序改改。
如果程序确实不能改,那么确实可以使用 NAT 的方法进行处理。
方法
由于程序 bind 在了 127.0.0.1 上,因此程序只接受目的地址为 127.0.0.1 的包。
于是需要作地址转换,做的是目的地址转化,也就是 DNAT,于是应该在 PREROUTING 里写。
iptables -t nat -A PREROUTING -p tcp --dport 5555 -j DNAT --to 127.0.0.1:5555
注意
这里还有个特殊情况:因为根据 RFC,目的地址 127.0.0.1 的包,由于安全问题,是不允许从网络上收到的。从网络上收到的目的地址为 127.0.0.1 的包应该被丢弃。
echo 1 > /proc/sys/net/ipv4/conf/eth0/route_localnet
所以需要上述命令改变这种行为。
但是这可能会导致安全隐患,因为这样你的系统就可以处理从 eth0 进入的,目的地址为 127.0.0.1 的包。如果攻击者恶意构造这样的包的话,就可以直接访问到你机器上所有 bind 在 127.0.0.1 上的端口。而往往,多数的程序会默认这样的连接是来自于本机,可能权限检查和鉴定有所放宽。
参考
清华大学 TUNA 协会,坏人。