net.ipv4.conf.eth0.route_localnet的作用
背景:默认情况下不能将本机的请求跳转/转发到回环接口上
在某些场景下会用在一台主机内网络流量重定向,比如将在本机回环设备中的数据包强行转发到另一台主机上。结果发现原本在正常的NAT场景中生效的iptables规则在loopback数据包的转发中并不起作用
例如:对本地流量利用iptables来转发不生效,以下规则并不生效
iptables -t nat -I PREROUTING -p tcp -d 192.168.1.0/24 --dport 2222 -j DNAT --to-destination 127.0.0.1:2222
注意:回环lo接口上的 127.0.0.1 地址,不允许发到设备外部sysctl -w net.ipv4.conf.eth0.route_localnet=1 开启route_localnet后,数据包就可以在lo上做nat
具体例子:
如上图一样,服务器对外只开放了一个80端口,但是web服务监听在了lo 接口上8080端口上,现在要实现外网通过访问服务器的80端口,来提供web服务。
像平常一样,做个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
然而网络并不通,原因:
源地址或目标地址设置为环回地址的任何IP 数据报都不得出现在计算机系统之外
通俗就是说网络上不允许出现源或目的为127.0.0.1的包,也不得由任何路由设备进行路由。
必须删除在网络接口上收到具有环回目的地址的报文。这样的分组有时被称为火星分组。
与其他虚假数据包一样,它们可能是恶意的。因此这类报文其实是不会被正常处理的
原因归结:系统上的lo 环回接口为了防止攻击(火星报文),所以内核默认禁止了所有网卡的路由本地网络功能,即丢弃源或目标为127.0.0.1的数据包。
解决方法
临时开启:
sysctl -w net.ipv4.conf.eth0.route_localnet=1
永久开启:
echo "net.ipv4.conf.eth0.route_localnet=1" >> /etc/sysctl.conf
sysctl -p
route_localnet参数含义
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的本地路由。
route_localnet功能
该参数指定一个网络设备是否允许转发目的或源地址为127/8的数据包,也就是来自或去往lo设备的数据包,通常情况下Linux系统中的每个网络设备都有自己的参数配置。
注意:
-
如果只是本机内的端口跳转可以使用 -j REDIRECT --to-ports port-number.
-
127.0.0.1这些环回地址与localhost不一样,localhost本质上不能等于127.0.0.1
-
ip_forward参数对lo设备数据包的转发没有影响