一台Linux服务器,`net.ipv4.ip_forward` 设成了1,然后它就成了内网里的“交通枢纽”。听起来挺方便,直到某天安全扫描报告里蹦出一行红字:IP forwarding enabled。很多人第一反应是——这算漏洞?我特意开的啊。
问题不在转发本身,而在“谁在用”。内核开启IP转发后,这台机器默认会转发所有接口之间到达的数据包,不区分来源和目的。攻击者一旦拿到内网任意一台机器的shell,就能把流量灌到这台转发机上,借它当跳板访问原本隔离的网段。去年某云厂商的托管K8s节点就出过这事:容器逃逸后,攻击者发现宿主机的ip_forward是1,直接横向扫到了同VPC里的Redis集群。那个Redis没设密码。
更隐蔽的场景在VPN和Docker里。Docker默认会把宿主机的ip_forward打开,因为容器要出网。但很多人装完Docker就不管了,结果宿主机变成了一台开放路由器。如果这台机器还有公网IP,且iptables的FORWARD链是ACCEPT策略,那它就是一个货真价实的开放中继。Shodan上搜“ip_forward”相关的banner,能翻出大量暴露的OpenVPN和WireGuard端点,有些连认证都没配好。
怎么判断自己的机器有没有这个问题?sysctl net.ipv4.ip_forward 看一眼。返回1不代表一定有问题,但得追问:FORWARD链默认策略是什么?有没有针对转发流量的限制规则?iptables -L FORWARD -n -v 如果看到policy ACCEPT且没有具体规则,那就是裸奔。容器环境里更麻烦,Docker会自己插一堆链,你得用iptables -t filter -L DOCKER-USER -n 看有没有兜底。
修复思路分两层。不需要转发的机器,直接sysctl -w net.ipv4.ip_forward=0 并写进/etc/sysctl.d/。需要转发的,比如VPN网关或K8s节点,把FORWARD链默认策略改成DROP,然后只放行必要的源和目的组合。K8s节点上还要注意,kube-proxy和CNI插件会频繁改iptables规则,手动加的规则可能被冲掉,得用iptables -I FORWARD 1 插到最前面,或者干脆上nftables的优先级机制。
有个细节容易被忽略:IPv6的net.ipv6.conf.all.forwarding 默认是0,但有些发行版在启用IPv6后会跟着打开。检查的时候别只看IPv4。另外,云厂商的安全组和网络ACL是另一层,但别指望它们能替代主机防火墙——同VPC内的流量往往不经过安全组。
说到底,IP forwarding enabled本身不是漏洞,它是个配置状态。危险的是这个状态和宽松的FORWARD策略、缺失的网络隔离叠加在一起。就像你家大门开着不一定是贼,但门开着、屋里没人、保险柜还没锁,那就是另一回事了。每次看到扫描报告里这条,我都会先问:这台机器到底该不该转发?如果该,那规则写全了吗?