Linux 双网卡服务器外网访问不通?策略路由、回程路径与 rp_filter 排查
本内容发表于:2026-09-09 10:42:31
浏览量
1052

服务器加上第二张网卡后,SSH 或网站突然从外网连不上,但在机器上能看到请求进入;也有服务器只有某个 IP 能访问,换一个出口就超时。遇到这些现象,先别急着增加默认路由,也不要直接关闭所有 rp_filter。

双网卡故障常见的线索是:请求从一张网卡进入,回包却选了另一条路径。Linux 的反向路径过滤、源地址策略路由,以及上游网络的地址校验,都可能影响最终结果。下面按“请求有没有到、回包往哪里走、是否被过滤”的顺序排查。

本文针对 Linux IPv4 场景。命令中的接口、地址、路由表编号都是示例,不能原样套到生产服务器;云服务器、容器和 VRF 环境应在承载业务的网络上下文中检查。资料核对日期:2026 年 9 月 9 日。

一、先确认故障范围,不要一上来修改内核参数

先记下出问题的客户端 IP、服务器实际本地 IP、服务端口和故障时间,然后检查地址、监听和路由规则:

date -Is
ip -br address
ip -4 rule show
ip -4 route show table all
ss -lntp

以上命令只读取状态,不修改网络配置。ss 若需要显示其他用户进程,可能需要相应权限。重点看四件事:

  • 网卡是否处于预期状态,IP 和掩码是否正确。

  • 服务是否监听目标 IP 或合适的通配地址。只监听 127.0.0.1 的服务,不能靠改默认路由变成外网可访问。

  • 是否已经存在按源地址、fwmark 或其他条件选择路由表的规则。

  • 是否同时配置了多条默认路由,以及它们的 metric 和所属路由表。

在同一路由表、同等匹配条件下,较低的 metric 通常更优先。但路由选择还涉及规则优先级和最长前缀匹配,不能仅凭默认路由的 metric 判断所有流量。ip rule 的优先级数字越小,检查顺序越靠前。[2][3]

如果连入站包都没有到达服务器,应先查 DNS 指向、负载均衡、云安全组、网络 ACL 和上游路径。此时把 rp_filter 改成 0,通常无法解决前面的链路问题。

二、用实际源地址检查回包出口

假设故障场景如下,所有地址均为文档示例地址:

  • eth0:192.0.2.10/24,网关 192.0.2.1。

  • eth1:198.51.100.10/24,网关 198.51.100.1。

  • 外部测试客户端:203.0.113.50。

  • 客户端访问 eth1 对应的服务,服务器回包源地址应为 198.51.100.10。

不要只运行不带源地址的 route get。对于这条会话,应查询:

ip -4 route get 203.0.113.50 from 198.51.100.10

输出中的 dev、via 和 table,可以帮助你判断这组源地址与目标地址会选哪张网卡、哪个网关和路由表。[2]

如果查询结果走 eth0,而业务要求从 eth1 的运营商出口返回,就有了回程不匹配的线索。不过,这条命令只是按给定条件执行路由查询,不是端到端连通性测试,也不能证明数据包已经发出。

若网络设计还使用 fwmark、VRF 或按端口选路,查询时也应带上相应条件。例如已知业务使用标记 0x1 时,可检查:

ip -4 route get 203.0.113.50 from 198.51.100.10 mark 0x1

不要凭空添加 mark。要先确认防火墙、连接标记和应用实际如何设置、恢复它,否则查到的不是故障流量所走的路径。

三、在两张网卡上抓同一条连接,确认请求和回包

可以开两个终端,在一次受控测试中分别观察 eth0 和 eth1:

sudo tcpdump -nn -i eth0 -c 100 'host 203.0.113.50 and tcp port 443'
sudo tcpdump -nn -i eth1 -c 100 'host 203.0.113.50 and tcp port 443'

把客户端 IP、端口和接口替换为实际值。-nn 避免地址与端口名称解析,-c 100 限制捕获数量;如果始终没有足够的数据包,命令不会因为达到某个时间而自动退出,可在测试结束后按 Ctrl+C 停止。[4]

观察时可以按下面几种情况缩小范围:

  • 两张网卡都没有入站 SYN:先检查抓包位置与过滤条件,再排查上游路径。

  • eth1 收到 SYN,但没有看到响应:继续查服务监听、主机防火墙、反向路径过滤及本机协议栈处理,不能直接认定是 rp_filter。

  • eth1 收到 SYN,eth0 发出 SYN-ACK:回包出口与入站接口不同。核对这是否符合网络设计,以及上游是否允许该源地址从这个出口发送。

  • eth1 收到 SYN,也从 eth1 发出 SYN-ACK,但客户端没有 ACK:继续查上游回程、NAT、防火墙和客户端侧,而不是反复修改本机监听。

抓包看到包到达网卡,不等于应用已收到它。非对称路由本身也不必然是错误;有些网络允许不同的入站和出站路径,关键在于过滤策略、NAT 状态和上游路由能否支持这种设计。[1][5]

抓包应限定对象和时间,不要默认采集全站业务载荷。对外分享结果前隐藏客户地址、域名及敏感信息。

四、rp_filter 的 0、1、2 分别代表什么?

rp_filter 是 IPv4 的源地址反向路径校验参数。Linux 内核文档给出的含义是:[1]

  • 0:不执行这项源地址校验。

  • 1:严格模式。若到报文源地址的最佳反向路径不经过该入站接口,校验失败的报文默认被丢弃。

  • 2:宽松模式。只要源地址能通过任意接口到达,就不因入站接口不同而在这一检查中失败;完全不可达的源地址仍会校验失败。

先读现有配置。示例接口为 eth0 和 eth1:

sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.eth0.rp_filter
sysctl net.ipv4.conf.eth1.rp_filter

这里容易看错的是作用范围:对某个接口做校验时,内核使用 all 与该接口配置中的数值最大值。[1]

例如,all=1、eth1=0,eth1 并不会因此关闭校验;all=1、eth1=2,则使用宽松模式。数字更大不代表过滤更严格,2 是宽松而不是“比 1 更严格”。

内核文档给出的默认值是 0,但发行版启动脚本或其他网络配置可能改变它。因此不要根据网上教程推断当前值,也不要把 IPv4 的 rp_filter 当成 IPv6 故障的通用修复开关。

已确认需要非对称路由时,怎样做有限测试?

仅在证据指向严格反向路径校验、网络设计确实允许非对称路径,且保留云控制台或其他恢复通道时,才考虑把受影响接口临时切换为宽松模式。先记录原值:

sysctl -n net.ipv4.conf.all.rp_filter
sysctl -n net.ipv4.conf.eth1.rp_filter

记录完成后,临时测试:

sudo sysctl -w net.ipv4.conf.eth1.rp_filter=2

用同一个外部客户端重新测试并观察抓包。若没有改善,应恢复刚才记录的接口原值。例如原值确实为 1 时,回滚命令才是:

sudo sysctl -w net.ipv4.conf.eth1.rp_filter=1

这不是要求所有双网卡服务器都设成 2,更不是让你全局关闭防伪造检查。即便改动后恢复,也要继续检查原来的路由是否错误。宽松模式放宽了接口约束,需要结合网络边界的源地址校验和访问控制评估风险。[1][5]

五、需要固定回程出口时,如何验证源地址策略路由?

如果业务要求“从 eth1 地址回复的流量,经 eth1 的网关返回”,应评估源地址策略路由,而不是不断给 main 表增加默认路由。[2][3]

下面只验证上文那一台测试客户端,避免直接把所有业务流量迁走。执行前必须确认:接口地址与网关真实存在、网关可达、路由表 101 未被使用、优先级 11010 未被占用,并检查更靠前的规则是否会先匹配。管理连接不要使用本次测试的客户端路径。

先检查预备使用的表和现有规则:

ip -4 rule show
ip -4 route show table 101

只有确认这个编号可以专用于本次测试后,才添加以下临时配置:

sudo ip -4 route add table 101 198.51.100.0/24 dev eth1 src 198.51.100.10
sudo ip -4 route add table 101 default via 198.51.100.1 dev eth1
sudo ip -4 rule add priority 11010 from 198.51.100.10/32 to 203.0.113.50/32 lookup 101
ip -4 route get 203.0.113.50 from 198.51.100.10

先添加直连网段,让该表能够解析示例网关,再添加默认路由,最后用规则把指定源地址到指定客户端的流量交给表 101。这一示例仅适用于上述普通以太网直连网关拓扑;云平台的特殊网关和路由约束需要按实际环境处理。

如果中途某条命令报错,应停止检查原因,不要把 add 随意改成 replace 去覆盖已有配置。完成测试后,按实际成功新增的对象精确回滚;三条均成功时可依次执行:

sudo ip -4 rule del priority 11010 from 198.51.100.10/32 to 203.0.113.50/32 lookup 101
sudo ip -4 route del table 101 default via 198.51.100.1 dev eth1
sudo ip -4 route del table 101 198.51.100.0/24 dev eth1

若需要把策略推广到该源地址的全部目标,先补齐管理网、内网和其他特定网段应走的路由,再设计更宽的规则。不要直接删除示例里的 to 条件,就当作完整生产配置。验证通过后,再通过当前使用的 NetworkManager、systemd-networkd 或发行版网络配置机制持久化,避免只在运行时有效。

六、云服务器、CDN 和标记路由还要留意哪些区别?

公网 IP 未必配置在服务器网卡上

如果公网地址由平台映射到私网地址,ip address 中可能只有私网地址。route get 的 from 应使用这条业务在本机实际使用的源地址,而不是把未分配给本机的公网地址直接填进去。还要核对云侧路由、NAT 和安全策略,不能只查操作系统。

CDN 访问与源站回程是两段链路

使用 CDN 时,应区分“访问者到边缘节点”和“边缘节点到源站”。若排查的是源站连接,抓包过滤对象应按实际回源对端选择,不能一律填终端访问者 IP。CDN 回源超时并不能单独证明 Linux 策略路由出错。

fwmark 与 src_valid_mark 需要一起理解

如果使用标记路由,反向路径校验是否考虑标记,会影响结果。内核文档说明,src_valid_mark=0 时反向查询不包含报文 fwmark;设为 1 时包含 fwmark,可用于相应的双向标记路由设计。[1]

先检查实际配置:

sysctl net.ipv4.conf.all.src_valid_mark
sysctl net.ipv4.conf.eth1.src_valid_mark

这一参数同样取 all 与接口值的最大值。它不是给所有策略路由服务器开启的通用开关:只在单方向使用 mark 的透明代理等设计,可能需要不同处理。要先弄清标记何时设置、是否跨连接恢复,再决定是否修改。

七、怎样确认故障真的修好了?

保留改动前后的 rule、route get 和抓包结果,再用原来失败的外部客户端验证完整业务请求。至少确认:目标 IP 与端口仍正常监听,入站与回包路径符合设计,TCP 握手和应用响应均成功,管理连接与其他地址未受影响。

如果进行了持久化,还应在可控维护窗口验证网络配置重新加载后的结果。不要只凭一次 ping 成功就结束,也不要通过 flush 全部路由、清空防火墙或全局关闭 rp_filter 来“试运气”。

双网卡服务器外网访问不通,最有效的起点是把同一条连接的源地址、入站接口、选路规则和回程出口对应起来。先找到路径在哪里偏离预期,再决定修路由、调整过滤模式,还是继续排查云平台和上游网络。

参考资料

以下资料用于核对参数与命令含义,不代表文中示例已在读者的生产环境验证。核对日期:2026 年 9 月 9 日。

  1. Linux Kernel Documentation — IP Sysctl

  2. iproute2 上游手册 — ip-route(8),man7 在线呈现

  3. iproute2 上游手册 — ip-rule(8),man7 在线呈现

  4. tcpdump 官方手册

  5. RFC 3704 — Ingress Filtering for Multihomed Networks