一次愚蠢的网络配置导致的傻逼问题
前言
作为一个经常折腾网络的人,我总认为自己对网络配置已经驾轻就熟。然而,最近的一次"小操作"却给我上了生动的一课,提醒我即使是最基础的网络配置,稍有不慎也会导致令人头疼的问题。
问题描述
事情是这样的,我有一台服务器,内网IP地址为192.168.50.100
。然后我买了一个物联网上网卡,内网IP为 192.168.0.100
,为了正确配置多网卡上网的分流,我去修改了服务器的netplan:
|
|
请注意上面的 to: 192.168.50.0/24
这条规则,这条规则的意思是:发往192.168.50.0/24
网段的所有流量,都要经过网关192.168.50.1
转发。
配置完成后,我发现局域网内的设备突然无法通过内网IP访问这台服务器上的服务了。
但奇怪的是,通过路由器IP访问却可以(路由器配置了DMZ主机)。具体表现为:
- 其他设备可以ping通这台服务器
- 这台服务器自己可以通过
192.168.50.100
走nginx访问到http服务 - 其他设备可以通过
10.xx.xx.xx
走nginx访问到http服务 - 其他设备无法通过
192.168.50.100
访问到http服务
问题分析
经过长达1个小时排查,我终于意识到问题出在哪里。。。这是一个典型的路由配置错误,而且错得相当愚蠢。
正常情况下的网络通信
在正常情况下,同一局域网内(同一网段)的设备通信是不需要经过网关的。比如,当192.168.50.100
想要与192.168.50.200
通信时,它会直接在局域网内发送数据包,通过ARP协议找到对方的MAC地址,然后直接通信。
这是因为操作系统会根据目标IP和本机IP以及子网掩码判断:目标是否在同一网段。如果在同一网段,就直接在局域网内通信,不需要经过网关。
错误配置后的情况
但我的错误配置改变了这一行为。我手动添加了一条路由规则,强制要求所有发往192.168.50.0/24
网段的流量都要经过网关192.168.50.1
。
这就导致了以下荒谬的情况:
- 当服务器(
192.168.50.100
)想要与同网段的设备(如192.168.50.200
)通信时 - 它不再直接在局域网内发送数据包
- 而是将数据包发送给网关
192.168.50.1
- 期望网关能够帮它转发到目标设备
但问题是,网关通常不会转发同一网段内的流量!因为按照正常的网络设计,同网段设备应该直接通信,不需要网关参与。
这种配置最终导致了单向通信问题:其他设备发送到192.168.50.100
的数据包仍然遵循正常路由,但192.168.50.100
的回复却走错误的路由,导致无法正常通信。
而且这种错误非常隐蔽。。其他设备访问192.168.50.100
时,ping可以通,curl结果是 Connection reset by peer
,然后去看 nginx 的日志,发现状态码是499,光看日志还以为是 nginx 配置问题。
解决方案
解决这个问题非常简单:删除那条错误的路由规则。