
子网路由这件事看着简单真正在生产环境里踩过坑的人都知道问题从来不在“会不会配一条ip route add”而在整个网段规划和转发链路是不是从一开始就设计对了。这篇文章不涉及任何外部网络加速或跨地域组网工具只聊最普通的工程场景企业内网、实验室、办公区有多段子网时怎么把子网路由器配对、配稳、配得可维护。适合看这篇文章的人有两类。一类是刚接触网络管理的新手需要把子网、网关、路由表、静态路由这些概念串起来知道第一步做什么、第二步做什么。另一类是已经在用 Linux 做网关或者维护多网段环境的人想系统检查一遍自己的配置有没有隐患。最值得先记住的判断是子网路由器不是“配完能通就行”而是要保证任何一条路径都能通、断了能查、重启不丢配置、新增网段不冲突。下面按我从单机实验到生产环境落地的一个完整顺序来拆先理解子网路由解决什么问题再设计网段方案然后动手配置最后验证和排错。1. 先搞清楚“子网路由”到底解决什么问题1.1 子网、路由器和路由表的基本关系一个 IP 地址由网络部分和主机部分组成子网掩码或前缀长度决定了网络部分占多少位。比如192.168.10.0/24前面的192.168.10是网络部分后面最后一段是主机部分整段最多容纳 254 台可用主机去掉网络地址和广播地址。只要两台设备不在同一个子网内它们就不能靠二层广播直接通信。主机要发送数据包时会先判断目标地址是不是自己所在的子网。如果在同一子网直接查 ARP 找目标机器如果不在同一子网就把数据包扔给默认网关。这个默认网关就是一台拥有多个子网接口的设备也就是子网路由器。子网路由器的工作方式并不复杂它收到数据包后查看目标 IP 地址在自己的路由表里寻找最匹配的路由条目然后把数据包从对应的接口转发出去。如果找不到匹配路由就使用默认路由默认路由也没有就直接丢弃。所以路由表的质量直接决定整个网络的连通质量。这里有一个新手容易忽略的点路由器两端都要有正确的“路径意识”。A 子网的主机把数据包发给路由器路由器转发给 B 子网的主机这只是单向通了。B 子网的主机返回数据包时也要知道怎么回到 A 子网。如果 B 子网的返回路径没有配好就会出现“能 ping 出去但收不到回包”的奇怪现象。1.2 什么场景下才需要单独配一台子网路由器很多环境其实不需要专门的子网路由器。比如一台三层交换机开启 VLAN 间路由以后就能在不同 VLAN 之间转发数据包效果等同于子网路由。家里那种普通路由器把内网和外网隔开本质上也是一个子网路由器。真正需要单独规划子网路由器角色的场景通常是下面几种办公网和服务器区隔离办公网一段数据库一段开发测试一段各段之间需要受控互访。实验室或机房有多段保留网段不同项目组使用不同的地址段但又要共享一套出口。现场设备、物联网终端、嵌入式设备这些设备往往固定 IP网段不能随便改需要一台路由器把老网段和新网段桥接起来。虚拟化或容器网络宿主机上有多个桥接网络或自定义网络需要把容器网段和外部网段打通。在这些场景里用一台 Linux 主机做子网路由器是很常见的做法。好处是灵活、可控、日志清晰坏处是一切都要自己配配错了没人帮你兜底。这篇文章后面的步骤全部围绕“一台 Linux 主机两个或三个网卡接口连接多个网段”的场景展开。2. 动手之前先把子网规划和路由表设计好2.1 网段规划最容易踩的坑我见过太多网络故障根因不是命令写错而是地址规划一开始就有问题。最典型的几个坑第一多个区域用相同的网段。比如两套设备都默认用192.168.1.0/24接在一起之后路由器根本分不清到底要把包送到哪里。这个问题在项目现场特别常见很多工控设备出厂默认就是192.168.1.x。正确做法是开工之前先把每个区域的网段列出来写成一张表不允许重复。第二网段没有留扩展余量。规划时用/24结果设备一多就满后期只能改网段或者加子网。建议根据设备数量选择合适的前缀长度宁可留多不要留少。第三把网关地址放在一个很随意的位置。有些环境把网关放在.1有些放在.254有些干脆用中间地址。单看都能用但后期写防火墙规则、写静态路由时混乱的网关约定会让人反复核对。强烈建议统一约定网关放在每个网段的第一个可用地址也就是.1。第四没有考虑两个网段之间的地址重叠。比如云端 VPC 用10.0.0.0/16本地机房也用10.0.0.0/16一旦要做互联路由表里会出现两条几乎相同的路径数据包去向完全不可控。规划阶段的地址冲突是后期最难排查的问题之一。规划示例 区域 网段 网关 用途 办公区 192.168.10.0/24 192.168.10.1 员工终端 服务器区 192.168.20.0/24 192.168.20.1 应用服务器 数据库区 192.168.30.0/24 192.168.30.1 数据库 设备区 172.16.50.0/24 172.16.50.1 物联网终端 管理网 172.16.99.0/24 172.16.99.1 设备管理这张表就是整个网络设计的基础。后面所有路由、防火墙、设备配置都以它为准。2.2 静态路由和动态路由怎么选子网路由器上配置路由有两种方式静态路由和动态路由协议。静态路由就是手动写死每条路径。适合网段数量少、拓扑稳定、带宽和延迟要求高的环境。优点是简单、可预期、没有协议开销缺点是网段一变就要手动改不灵活。如果你管理的是几台服务器加百来台终端静态路由完全够用。动态路由协议比如 OSPF适合网段很多、存在多条冗余链路、手动维护已经容易出错的规模。路由器之间会自动交换路由信息某条链路断了之后能自动收敛到备用路径。缺点是配置复杂度明显上升出了问题需要理解协议状态排错门槛高。我给一个实用的选择标准环境规模推荐方式原因3 个以内网段静态路由配置简单一眼能看出全貌5 到 10 个网段静态路由 统一网关只要规划清楚静态仍然可靠10 个以上网段、有冗余链路OSPF 等动态路由手动维护路由表容易漏配、错配经常变动的临时环境静态路由但用脚本批量生成便于回滚和审计我自己的经验是先静态后动态。不要一上来就上 OSPF尤其不要在不理解协议的情况下依赖它。动态路由解决的是拓扑变化时的自动适应问题并不能解决网段规划混乱的问题。规划错乱时动态路由只会让错误传播得更快。3. 用 Linux 做子网路由器的完整步骤3.1 启用内核转发Linux 默认不转发 IP 数据包。主机的网络栈收到一个目标不是自己的数据包时会直接丢弃。要让它变成路由器第一步就是打开内核转发开关。# 临时启用重启失效 sysctl -w net.ipv4.ip_forward1 # 永久启用 echo net.ipv4.ip_forward 1 /etc/sysctl.conf sysctl -p如果修改内核参数没有生效检查是否被其他配置覆盖。有的发行版会在/etc/sysctl.d/目录下拆分配置文件建议统一放在/etc/sysctl.d/99-router.conf里避免和其他文件冲突。IPv6 如果需要转发对应参数是net.ipv6.conf.all.forwarding。实际环境里如果没用到 IPv6可以在网卡上明确关闭 IPv6 地址分配减少不必要的路由条目和干扰。3.2 配置接口 IP 和路由路由器必须为每个连接到的网段配置一个接口地址。以三网段场景为例路由器有三个接口分别连接办公区、服务器区和设备区。# 配置接口 IP这里以 systemd-networkd 环境为例 # /etc/systemd/network/10-lan1.network [Match] Nameeth1 [Network] Address192.168.10.1/24# /etc/systemd/network/20-lan2.network [Match] Nameeth2 [Network] Address192.168.20.1/24如果使用的是传统/etc/network/interfaces风格配置文件类似下面这样auto eth1 iface eth1 inet static address 192.168.10.1 netmask 255.255.255.0 auto eth2 iface eth2 inet static address 192.168.20.1 netmask 255.255.255.0接口地址配好之后每个直接相连的网段会自动生成一条直连路由不需要手写。但路由器如果要访问更深层级的网络比如服务器区后面还有一个数据库网段192.168.30.0/24而这个网段的网关是另一台设备192.168.20.2就需要配置静态路由ip route add 192.168.30.0/24 via 192.168.20.2这里要区分两个概念onlink直连网段的地址由本机接口配置自动产生via指定下一跳地址表示去往目标网段要先经过哪个路由器。下一跳地址必须和本机某个接口在同一个网段否则无法送达。配置完立即生效不等于重启后还在。用ip route add添加的路由重启后丢失需要写入系统配置。在 systemd-networkd 里可以加[Route]段在传统 interfaces 里可以写up ip route add ...这样才能持久化。3.3 防火墙规则别让数据包进来却出不去很多人在这一步卡住路由加好了接口地址也配了但两个网段之间就是不通。打开数据包转发后Linux 仍然会经过防火墙的 FORWARD 链。如果防火墙默认策略是 DROP所有跨网段转发都会被直接丢弃。我在实际排错时第一步永远是确认防火墙 FORWARD 链的状态。在 iptables 里看iptables -L FORWARD -n -v如果默认策略是 DROP就需要放行需要转发的网段iptables -A FORWARD -i eth1 -o eth2 -j ACCEPT iptables -A FORWARD -i eth2 -o eth1 -j ACCEPT注意方向。跨网段通信是双向的只放行一个方向会出现请求能出去、回包被丢弃的情况表现就是 ping 无响应或连接超时。使用 firewalld 的发行版需要开启内核转发并添加策略。使用 ufw 的发行版则要注意 ufw 默认可能不允许转发需要在/etc/default/ufw里把DEFAULT_FORWARD_POLICY改成ACCEPT或者自定义 ufw 转发规则。还要澄清一个容易混淆的概念子网路由只负责转发不改变源地址。数据包从办公网到服务器区源 IP 仍然是办公网的地址服务器能看到真正的来源。如果你希望服务器区只能看到路由器的 IP让终端隐藏在后面那就要做 NAT源地址转换。这是两个完全不同的需求。生产环境里段间互访通常用纯路由让源 IP 保持真实便于审计只有访问外部网络或隔离敏感区域时才考虑 NAT。4. 验证路由是否真的正确4.1 从本机验证再跨网段验证配置完成后不要直接拿业务测试先按顺序做三层验证第一步在路由器本机查看接口和路由表是否完整ip addr show ip route show确认每个网段都有对应的接口地址确认静态路由都在确认默认路由没有指向错误方向。第二步在路由器本机 ping 每个网段的网关或终端。这一步验证路由器自己的网络栈和二层链路是否正常。如果路由器 ping 不通某个网段的终端先检查接口是否 up、链路是否正常、终端 IP 是否配置正确。第三步在子网终端上 ping 自己的网关。比如办公网的一台电脑先 ping192.168.10.1通了说明终端到路由器这一段没问题。第四步跨网段 ping。办公网终端 ping 服务器区的一台机器192.168.20.10通了说明整条转发链路正常。不通时再用 traceroute 看数据包停在哪一跳traceroute 192.168.20.10如果数据包到了192.168.10.1就不再前进问题大概率出在路由器上按顺序检查路由表、FORWARD 链、接口状态。如果数据包到了服务器区的终端网关但终端不回包问题大概率出在返回路径上检查终端侧的路由或网关设置。4.2 常见验证命令怎么看结果一个高效的做法是准备一张验证核对表每次配置完逐项检查检查项命令期望结果内核转发开关sysctl net.ipv4.ip_forward输出 1接口地址ip addr show eth1能看到对应网段 IP状态 UP路由表ip route show直连路由和静态路由都存在路由查找ip route get 192.168.30.10输出正确的下一跳和出接口FORWARD 防火墙iptables -L FORWARD -n -v对应网段的转发规则计数在增长跨网段连通ping -c 3 192.168.30.10有回包丢包率 0路径确认traceroute 192.168.30.10每一跳都在预期路径上这里特别说一下ip route get。它可以直接告诉内核“去某个地址会走哪条路由、从哪个接口出去、下一跳是谁”是排查路由首选命令比猜路由表快得多。比如ip route get 192.168.30.10如果输出显示走了一个你没预期到的接口说明路由表里有冲突条目优先检查是否存在更具体的路由或者默认路由覆盖。我一般会在跑通后顺手把每台终端的默认网关也 ping 一遍。很多终端配置了错误的网关结果就是“路由器上一切正常终端就是不通”。这种问题不在路由器而在终端侧排查方向不要搞反。5. 生产环境里的边界和排查思路5.1 这些坑千万别踩第一个坑是配置不持久。ip route add、ip addr add都是临时配置一重启就没了。生产环境必须在系统配置里固化并且每一次变更后都执行一次“模拟重启”验证。做法是用systemctl restart systemd-networkd或类似命令重载配置确认配置能自动恢复。第二个坑是对称路由被破坏。有些环境有多台路由器或存在多条回程路径数据包从 A 路径去、从 B 路径回如果中间设备状态不同步很容易出现间歇性不通。排查时看到 ping 时而通时而不通优先检查路径是否对称防火墙状态是否允许回程流量。第三个坑是 MTU 不一致。两个网段的 MTU 不同或者中间链路的 MTU 小于终端设置值大包会被丢弃小包正常。典型表现是 ping 小包通、ping 大包不通或者网页打开慢、大文件传输超时。排查方法ping -M do -s 1472 192.168.20.10逐步减小包大小找到临界值就能确认 MTU 问题。第四个坑是用低性能设备做路由器时的资源边界。如果设备本身内存很小、CPU 很弱转发性能有限不能拿它当大型网络的骨干路由器。还有一个实际工程细节很多嵌入式路由器、工控机使用 MIPS 架构而且存在大小端差异比如mipsleMIPS 小端和普通 x86 平台的软件包互不兼容。在这些设备上部署路由服务或自行编译程序时一定要确认架构类型、内核版本和二进制格式匹配否则会出现“文件放上去但无法执行”的诡异错误。低配设备能转发几条路由不代表能承担大量并发转发要实测而不是拍脑袋。第五个坑是防火墙规则顺序错误。iptables 按规则顺序匹配如果前面有一条 DROP 把目标网段拦住了后面的 ACCEPT 永远不生效。排查时不要只看有没有 ACCEPT 规则要看整个链的顺序和每个规则的计数器。第六个坑是只配了路由器没配终端。路由器知道怎么去所有网段但终端的默认网关如果只指向某一个接口它仍然无法到达其他网段。多网段环境下终端上的静态路由或网关配置也是整个链路的一部分不要忽略。5.2 排查顺序和工具遇到跨网段不通我建议按这个顺序排查不要跳步先确认现象完全不通、时通时不通、单方向通、还是大包不通。在路由器上执行ip route get确认路由走向是否符合预期。在路由器上ping两端网关确认本机到两个网段都通。检查 FORWARD 链的规则和计数器看数据包是否真的进入了转发流程。在路由器两个接口分别抓包tcpdump -i eth1 icmp tcpdump -i eth2 icmp对比两个接口是否都出现了请求和回包。只出现请求没出现回包重点查返回路径和防火墙只有一个接口有包重点查路由表。tcpdump 是排错最后一道防线大多数时候它能直接告诉你数据包到底卡在哪。检查系统日志journalctl -u systemd-networkd、dmesg有时候内核丢弃的包会留下痕迹。完全确认网络层没问题之后再检查具体应用的端口、服务端监听地址、服务端防火墙。很多“网络不通”最终被证明是应用层问题但如果你一开始没有排除网络层就会来回浪费时间。最后留一个我自己常用的收尾动作把配置信息整理成文档记录每个网段、每台路由器、每条静态路由的用途和变更时间。子网路由本身不复杂真正让人崩溃的是三个月后没人记得这条路由为什么存在。配得好再加上改得清楚整个网络才算是“用正确的方式”在跑。