为什么不能将客户端的连接请求跳转或转发到本机lo回环接口上?
一、为什么不能将本机的请求跳转/转发到回环接口上?
如上图一样,服务器对外只开放了一个80端口,但是web服务监听在了lo 接口上8080端口上,现在要实现外网通过访问服务器的80端口,来提供web服务。(有人可能会说这样做没有意义啊!你直接把web服务的监听ip和端口改成外网ip和80端口上就得了)。有意义无意义,我也不清楚,只是想从技术上考虑能否实现?
像平常一样,做个DNAT转发,将访问 192.168.30.177(公网)端口80的请求转发/跳转到 127.0.0.1的8080 端口上。使用下面两条命令就行:
# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:8080 # iptables -I INPUT 5 -p tcp --dport 80 -j ACCEPT
检查服务监听地址:
# netstat -ulntp|grep :8080 tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 3667/nginx
但是在测试80端口连接时,出现了连接失败的提示,如下图:
正常我觉得是可以通的啊,毕竟用dnat转发到其它主机时是没有问题的。而且我用了REDIRECT 动作,也是不行。
二、算不上分析的分析(其实就是查资料😅)
根据维基百科上针对Loopback得到相关loopback 接口的定义:在同一台机器上执行时的网络应用程序可以进行通信。它完全在操作系统的网络软件中实现,并且不将任何数据包传递给任何网络接口控制器。计算机程序发送到环回IP地址的任何流量都将被简单地立即传回网络软件堆栈,就像从另一个设备接收到的一样。
另外,源地址或目标地址设置为环回地址的任何IP 数据报都不得出现在计算机系统之外(通俗就是说网络上不允许出现源或目的为127.0.0.1的包),也不得由任何路由设备进行路由。必须删除在网络接口上收到具有环回目的地址的报文。这样的分组有时被称为火星分组。与其他虚假数据包一样,它们可能是恶意的,可以通过应用bogon过滤来避免任何可能导致的问题。
看过定义之后才知道原来这个包文是直接被删除了。根据这个帖子所说,可以修改内核的参数,将eth0(即本例中的外网卡)设置为不删除环回目的地址的报文。
默认是禁止的。内核参数如下:
route_localnet - BOOLEAN Do not consider loopback addresses as martian source or destination while routing. This enables the use of 127/8 for local routing purposes. default FALSE
备注:大致意思是不要将来自或发送到 环回接口上的数据包视为火星报文(这里称这个包为火星报文),既不丢弃它,启用用于127.0.0.1的本地路由。
飞走不可
使用以下命令(针对eth0)进行修改该内核参数的值为TRUE:
# sysctl -w net.ipv4.conf.eth0.route_localnet=1 net.ipv4.conf.eth0.route_localnet = 1
永久保存该设置
# echo "net.ipv4.conf.eth0.route_localnet=1" >> /etc/sysctl.conf # sysctl -p
防火墙的nat设置无需改变,按照第一步的命令即可。
三、验证以上的配置
测试访问80端口:
按照预期一样,可以成功访问。本来在访问期间,是想用tcpdump 抓lo接口上的包来看看的。结果很失望,没抓到。。。。不太清楚为什么,难道是tcpdump在nat表的后面么?抓不到PREROUTING的包?
不过,另辟蹊径,用了iptables 自带的计数器,查看到了当访问站点时,确实经过了nat表的PREROUTING链,如下图:
总结下:
系统上的lo 环回接口为了防止攻击(火星报文),所以内核默认禁止了所有网卡的路由本地网络功能,即丢弃源或目标为127.0.0.1的数据包。但在有些时候可以在不重启或改变应用程序配置的时候,我们可以开启该功能即 route_localnet,来访问监听在127.0.0.1上的端口。如kvm 虚拟机默认的vnc端口设置。另外为了安全考虑,在设置DNAT规则时,可以限定访问来源。
小扩展:如果只是本机内的端口跳转可以使用 -j REDIRECT --to-ports port-number.
该文属于原创,如有转载,请备注原文链接:飞走不可(会不定期修改文章)谢谢。其中有些内容来源于互联网,并已在最下方标注参考链接,
参考链接:
https://unix.stackexchange.com/questions/111433/iptables-redirect-outside-requests-to-127-0-0-1
https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
http://linux-ip.net/html/nat-dnat.html
http://blog.csdn.net/dog250/article/details/7664055
https://en.wikipedia.org/wiki/Loopback
https://www.howtogeek.com/126304/why-is-the-localhost-ip-127.0.0.1/
http://www.tech-faq.com/127-0-0-1.html