三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

UOS/Deepin双网卡策略路由配置:实现内外网同时访问

UOS/Deepin双网卡策略路由配置:实现内外网同时访问

1. 项目概述与核心需求解析

在UOS(Deepin)这类基于Linux的国产操作系统上,配置双网卡同时上网,听起来像是个简单的网络设置,但背后其实涉及路由策略、网关优先级、源地址选择等一系列网络底层知识。很多朋友,尤其是从Windows环境迁移过来的用户,常常会遇到一个尴尬的局面:明明插了两根网线,一个连内网、一个连外网,结果要么是外网不通,要么是内网访问不了,系统似乎“傻傻地”只认一条路。这其实不是系统傻,而是我们没有告诉它更精细的“交通规则”。

我自己在部署开发测试环境、搭建内外网隔离的工作站时,就反复折腾过这个问题。核心需求非常明确:让两张网卡各司其职,访问不同目标网络的流量,自动从正确的网卡出去,互不干扰,且能同时保持连接。比如,有线网卡1(eth0)连接公司内网,网关是192.168.1.1,用于访问内部服务器和资源;有线网卡2(eth1)或无线网卡(wlan0)连接互联网,网关是192.168.31.1,用于浏览网页、下载更新。理想状态是,访问10.0.0.0/8这类内网地址时,流量走eth0;访问其他所有地址(默认路由)时,流量走eth1/wlan0。

UOS(Deepin)提供了图形化网络管理工具,对于简单场景(如双网卡接入同一网络)可能够用,但对于这种需要策略路由的复杂场景,图形界面往往力不从心,最终还是要靠命令行和配置文件来精准控制。接下来,我将从原理到实操,完整拆解在UOS上实现这一目标的步骤、踩过的坑以及确保稳定性的技巧。

2. 网络基础原理与方案选型

在动手之前,我们必须搞清楚Linux系统处理多网卡、多网关的基本逻辑,否则配置就是盲人摸象。

2.1 默认路由的“唯一性”与冲突

Linux内核维护着一张路由表(通常指主路由表main),用于决定数据包从哪个网卡发出。当系统存在多个网关时,默认路由(0.0.0.0/0)只能有一条生效。后配置的默认路由会覆盖先前的,或者系统会根据某种度量值(如metric)来选择一条。这就是为什么当你为两张网卡都配置了网关并启用后,经常只有一张网卡能通外网,另一张则“失灵”了。系统并非不能处理多个网关,而是我们需要更明确的指示。

2.2 策略路由:为流量指定专属通道

解决上述冲突的关键是策略路由。它允许我们定义多张路由表,并根据数据包的源地址、目的地址、协议类型等条件,决定使用哪张路由表来查询出口。对于我们“双网卡各走各路”的场景,最常用且有效的方法是“基于源地址的策略路由”

其核心思想是:

  1. 创建两张自定义路由表,例如table_eth0table_eth1
  2. 在每个路由表内设置各自的路由规则。在table_eth0里,添加到达内网网段的路由,并设置其默认网关为内网网关;在table_eth1里,设置默认网关为外网网关。
  3. 建立路由策略规则:规定“来自eth0网卡IP的流量,查询table_eth0”;“来自eth1网卡IP的流量,查询table_eth1”。
  4. 设置主路由表:主路由表(main)通常只保留直连网络和本地路由,不设置默认网关,或者设置一个兜底的默认网关(通常指向外网)。

这样,当系统要发送一个数据包时,会先匹配策略规则。例如,一个从内网服务器192.168.1.100返回的数据包到达eth0(源地址是内网IP),策略规则会指示系统去查table_eth0,从而确保回复流量也走eth0出去,形成一个完整的回路。

2.3 方案对比:NetworkManager vs systemd-networkd vs 手动配置

UOS(Deepin)默认使用NetworkManager来管理网络,它提供了图形界面和nmcli命令行工具。此外,底层还有传统的systemd-networkdnetplan(某些版本)等方案。

  • NetworkManager图形界面:适合简单双网卡(如DHCP获取IP),但对于复杂的策略路由支持有限,高级配置仍需命令行。
  • nmcli命令行:功能强大,可以配置连接(connection)、设备(device),并支持通过ipv4.routing-rules参数设置简单的策略路由,是推荐的主要配置方式,因为它与系统图形界面集成较好,配置相对持久。
  • 手动编辑/etc/network/interfacesip rule/route命令:最传统、最直接的方式,通过脚本实现,灵活性最高,但需要自行处理持久化,对新手不友好。
  • systemd-networkd:更底层、更轻量的方案,通过.network文件配置,同样支持策略路由,但需要禁用NetworkManager,可能影响桌面环境的网络小程序。

我们的选型:为了兼顾易用性、持久化和与UOS桌面环境的兼容性,本方案将nmcli命令行为主,辅以必要的ip命令进行验证和调试。这样配置可以通过NetworkManager持久化,重启后依然有效,且图形界面能正常显示连接状态。

3. 环境准备与网卡信息确认

开始配置前,请确保你拥有系统的管理员权限(sudo)。

3.1 识别物理网卡与连接名称

首先,我们需要知道系统识别到的网卡设备名以及NetworkManager为它们创建的连接名称。

# 查看所有网络设备及其状态 nmcli device status

你会看到类似下面的输出:

DEVICE TYPE STATE CONNECTION eth0 ethernet 已连接 Wired connection 1 eth1 ethernet 已连接 Wired connection 2 wlan0 wifi 已断开 --

这里,eth0eth1是物理设备名,Wired connection 1Wired connection 2是NetworkManager为它们自动创建的连接名称。我们后续操作主要针对这些“连接”。

注意:连接名称(CONNECTION)是可以修改的更具描述性的标识,建议在配置前将其改为容易记忆的名字,例如company-laninternet-wan,避免混淆。可以使用nmcli con mod “旧名称” connection.id “新名称”来修改。

3.2 记录关键网络参数

你需要为每张网卡规划或记录下以下信息:

  • 内网网卡(例如eth0)
    • 静态IP地址:如192.168.1.100/24
    • 网关:如192.168.1.1
    • DNS服务器:内网DNS,如192.168.1.1或公司指定的DNS。
    • 需要访问的内网网段:如10.0.0.0/8,172.16.0.0/12等。
  • 外网网卡(例如eth1或wlan0)
    • 获取IP方式:通常为DHCP,但如果需要静态IP,也要记录。
    • 网关:由路由器分配,如192.168.31.1
    • DNS服务器:外网DNS,如114.114.114.114,8.8.8.8

实操心得:强烈建议在内网使用静态IP,避免DHCP租约变化导致路由策略失效。外网卡用DHCP通常没问题,但如果你知道网关地址,在配置策略路由时会用到。

4. 核心配置步骤详解

我们将分步配置,每一步都解释其作用。请根据你的实际网卡名称和IP信息进行替换。

4.1 配置内网网卡(eth0)的连接

假设内网网卡设备是eth0,其NetworkManager连接名称我们改为company-lan

# 1. 修改连接名称(可选,但推荐) sudo nmcli con mod “Wired connection 1” connection.id company-lan # 2. 配置静态IP地址、网关和DNS sudo nmcli con mod company-lan ipv4.addresses 192.168.1.100/24 sudo nmcli con mod company-lan ipv4.gateway 192.168.1.1 sudo nmcli con mod company-lan ipv4.dns “192.168.1.1” sudo nmcli con mod company-lan ipv4.method manual # 设置为手动(静态IP) # 3. **关键步骤:禁止此连接添加默认路由** # 这是避免双默认路由冲突的核心操作。我们只为内网网段配置路由。 sudo nmcli con mod company-lan ipv4.never-default yes # 4. 重新启用连接以应用更改 sudo nmcli con down company-lan sudo nmcli con up company-lan

参数解释

  • ipv4.addresses: 设置静态IP和子网掩码(CIDR格式)。
  • ipv4.method manual: 指定为手动配置,而非DHCP。
  • ipv4.never-default yes: 这个参数至关重要!它告诉NetworkManager:“不要为这个连接在系统主路由表里添加默认路由(0.0.0.0/0)”。这样,192.168.1.1这个网关就不会成为全局默认网关,避免了与另一张网卡的网关冲突。

4.2 配置外网网卡(eth1)的连接

假设外网网卡设备是eth1,连接名称改为internet-wan。我们假设它通过DHCP获取IP,并且我们希望它提供默认路由。

# 1. 修改连接名称 sudo nmcli con mod “Wired connection 2” connection.id internet-wan # 2. 配置为DHCP自动获取,并允许其设置默认路由和DNS sudo nmcli con mod internet-wan ipv4.method auto # 3. **关键步骤:确保此连接可以添加默认路由**(默认就是允许的,这里显式确认) sudo nmcli con mod internet-wan ipv4.never-default no # 4. 重新启用连接 sudo nmcli con down internet-wan sudo nmcli con up internet-wan

执行后,使用ip route show命令,你应该能看到主路由表(main)里有一条默认路由,指向eth1获取到的网关(例如default via 192.168.31.1 dev eth1)。而eth0的路由表里只有直连网络路由(192.168.1.0/24 dev eth0)和本地路由,没有默认路由。

4.3 为内网网卡添加策略路由

现在,我们需要为内网流量创建独立的路由表和策略规则。这需要用到nmcli设置路由规则参数。

# 1. 为内网连接(company-lan)添加一条静态路由:指向内网网段,网关为内网网关。 # 假设你需要访问 10.0.0.0/8 这个大型内网。 sudo nmcli con mod company-lan +ipv4.routes “10.0.0.0/8 192.168.1.1” # 2. **核心:添加基于源地址的策略路由规则** # 规则含义:来自源地址 192.168.1.100 的流量,使用路由表编号 100(一个自定义表)进行查询。 sudo nmcli con mod company-lan +ipv4.routing-rules “from 192.168.1.100 table 100” # 3. 在上一步指定的路由表100中,添加默认路由(指向内网网关)和直连路由。 # 首先,添加直连网络路由(必须,否则本地通信有问题)。 sudo nmcli con mod company-lan +ipv4.routes “192.168.1.0/24 table 100” # 然后,添加默认路由。注意:这个默认路由只在table 100中生效,不影响主路由表。 # **这是一个关键技巧:在策略路由表里设置一个指向内网网关的默认路由,可以处理所有未明确指向外网的流量。** sudo nmcli con mod company-lan +ipv4.routes “0.0.0.0/0 192.168.1.1 table 100” # 4. 重新启用内网连接,使所有路由和规则生效 sudo nmcli con down company-lan sudo nmcli con up company-lan

原理解读

  1. +ipv4.routes:为连接添加一条静态路由。+号表示追加,而不是覆盖。
  2. +ipv4.routing-rules:添加一条IPv4路由策略规则。from 192.168.1.100 table 100是一条非常强大的规则。它创建了一个优先级很高的规则(优先级数字默认较小,意味着优先匹配),所有源IP192.168.1.100的数据包(即从本机eth0网卡发出的数据包),其出口路由将查询名为100的路由表。
  3. 我们在表100中放入了两条路由:一条是到192.168.1.0/24的直连路由(保证同网段通信),另一条是默认路由0.0.0.0/0,但网关指向了内网网关192.168.1.1。这意味着,对于匹配了策略规则(源IP是内网IP)的流量,如果目的IP不在192.168.1.0/24网段,它就会尝试走内网网关出去。这通常用于访问公司其他内网网段(如10.x.x.x),而这些网段的路由需要在内网网关192.168.1.1上配置。

4.4 验证与测试配置

配置完成后,必须进行全面的验证。

# 1. 查看所有网络接口的IP地址 ip addr show # 2. 查看主路由表 ip route show # 应该看到外网网关(如 192.168.31.1)作为默认路由,以及 eth0 的直连路由。 # 3. 查看所有路由策略规则 ip rule list # 你应该能看到类似这样的规则(优先级可能不同): # 0: from all lookup local # 32765: from 192.168.1.100 lookup 100 # 32766: from all lookup main # 32767: from all lookup default # 这表示源IP为192.168.1.100的流量,会优先查询表100。 # 4. 查看自定义路由表100的内容 ip route show table 100 # 应该看到类似: # default via 192.168.1.1 dev eth0 # 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100 # 5. 功能性测试 # 测试外网连通性(应走eth1) ping -c 4 8.8.8.8 # 测试内网同网段连通性(应走eth0) ping -c 4 192.168.1.1 # 测试其他内网网段连通性(应走eth0,经由内网网关) ping -c 4 10.0.1.1 # 6. 跟踪路由,验证路径 # 跟踪到外网地址的路由 traceroute 8.8.8.8 # 第一跳应该是外网网关 192.168.31.1,设备是 eth1。 # 跟踪到内网地址的路由 traceroute 10.0.1.1 # 第一跳应该是内网网关 192.168.1.1,设备是 eth0。

5. 高级调优与故障排查实录

即使按照上述步骤配置,在实际环境中仍可能遇到各种问题。以下是我总结的常见坑点与解决方案。

5.1 常见问题与解决方案速查表

问题现象可能原因排查命令与解决方案
内网IP可以ping通网关,但ping不通其他内网网段(如10.x.x.x)。1. 内网网关(192.168.1.1)上没有到目标网段的路由。
2. 策略路由表100中缺少默认路由或默认路由指向错误。
3. 目标服务器或中间防火墙有策略限制。
1.ip route show table 100检查表100中是否有default via 192.168.1.1
2. 在主机上traceroute 10.0.1.1,看第一跳是否是192.168.1.1。如果不是,检查ip rule list规则是否生效。
3. 联系网络管理员确认网关路由和防火墙策略。
配置重启后,策略路由失效。NetworkManager连接配置未正确持久化,或者有其他服务(如systemd-networkd)干扰。1. 使用nmcli con show company-lan | grep -E “ipv4.(routes|routing-rules)”确认配置已保存。
2. 检查是否有其他网络管理服务在运行:systemctl status systemd-networkd。如果active,考虑禁用:sudo systemctl disable --now systemd-networkd注意:这可能会影响服务器版,桌面版通常只用NetworkManager。
所有流量都走了外网,内网特定网段不通。策略路由规则from 192.168.1.100未生效,或者主路由表的路由覆盖了。1.ip rule list查看规则是否存在且优先级合理。
2. 确保内网连接设置了ipv4.never-default yes,防止其网关进入主路由表造成混淆。
3. 尝试为特定内网网段在主路由表添加更精确的路由:sudo nmcli con mod company-lan +ipv4.routes “10.0.0.0/8 192.168.1.1”。这条路由会加入主路由表,对所有流量生效,优先级高于默认路由。
DNS解析混乱,内网域名解析失败。系统DNS配置可能只使用了外网DNS,无法解析内网域名。1. 检查/etc/resolv.conf,确认是否包含了内网DNS服务器(192.168.1.1)。
2. 在NetworkManager中为内网连接单独设置DNSsudo nmcli con mod company-lan ipv4.dns “192.168.1.1”
3. 可以使用systemd-resolve --status查看各个接口的DNS配置。
无线网卡(wlan0)作为外网卡时,配置不生效。无线连接通常由NetworkManager管理,配置方式与有线相同。但无线网络可能频繁重连,导致路由规则重复添加。1. 确保无线连接的配置中,也设置了ipv4.never-default no(如果是外网出口)。
2. 为无线连接使用固定的连接配置名,避免重连后生成新的临时配置。
3. 检查无线连接的IPv4设置方法是否为auto(DHCP)。

5.2 配置持久化与启动脚本

虽然nmcli配置在重启后通常能通过NetworkManager自动恢复,但在某些极端情况下(如非常早期的系统启动阶段需要网络),可能需要更底层的保障。我们可以创建一个systemd服务单元来在启动时应用关键的路由规则。

创建一个脚本文件,例如/usr/local/bin/setup-dual-routes.sh

#!/bin/bash # 在NetworkManager启动后,确保策略路由规则存在 ip rule add from 192.168.1.100 table 100 pref 100 # 为表100添加直连路由和默认路由(如果NetworkManager还没添加) ip route add 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100 table 100 ip route add default via 192.168.1.1 dev eth0 table 100

然后创建一个systemd服务单元/etc/systemd/system/dual-route.service

[Unit] Description=Setup dual NIC routing rules After=network-online.target NetworkManager.service Wants=network-online.target [Service] Type=oneshot ExecStart=/usr/local/bin/setup-dual-routes.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target

最后启用它:sudo systemctl enable dual-route.service。这作为一个兜底方案,确保路由规则万无一失。

5.3 使用NetworkManager连接图形界面进行辅助检查

在UOS桌面环境下,你可以点击任务栏网络图标 -> “网络设置”,查看各个有线连接的配置。在“IPv4”设置页,你可以看到我们通过命令行设置的“手动”地址、DNS以及“仅对此连接使用自动路由”选项(这对应ipv4.never-default)。图形界面虽然不能直接配置复杂的策略路由,但可以用来验证基本IP设置是否正确,非常直观。

6. 方案延伸与替代思路

上述方案是基于“源地址”的策略路由,这是最通用和稳定的方法。但在某些特定场景下,也可以考虑其他思路。

6.1 基于目标地址的简单路由

如果你的需求仅仅是“访问A网段走网卡1,访问B网段走网卡2,其他走默认”,并且不关心回包路径(通常对称路由才有问题),那么可以简单地在主路由表中添加更精确的路由,而不必配置复杂的策略路由。

# 添加一条静态路由:访问10.0.0.0/8网段的流量,走内网网关192.168.1.1 sudo nmcli con mod company-lan +ipv4.routes “10.0.0.0/8 192.168.1.1” # 这条路由会进入主路由表,由于其掩码比默认路由(0.0.0.0/0)更“精确”,所以优先级更高。

这种方法更简单,但前提是你的内网网关(192.168.1.1)知道如何去往10.0.0.0/8,并且从10.0.0.0/8返回的流量,其目标IP是你的外网IP时,能正确路由回来。这在一些网络拓扑中可能不成立,会导致单向通的问题。而基于源地址的策略路由能保证“从哪来回哪去”,适应性更强。

6.2 使用systemd-networkd进行配置(适用于服务器或无图形界面环境)

如果你在UOS服务器版或希望更底层的控制,可以禁用NetworkManager,改用systemd-networkd

  1. 禁用NetworkManager:sudo systemctl disable --now NetworkManager
  2. eth0创建配置文件/etc/systemd/network/10-internal.network
    [Match] Name=eth0 [Network] Address=192.168.1.100/24 DNS=192.168.1.1 [Route] Gateway=192.168.1.1 Table=100 [RoutingPolicyRule] From=192.168.1.100 Table=100
  3. eth1创建配置文件/etc/systemd/network/20-external.network
    [Match] Name=eth1 [Network] DHCP=yes
  4. 启用并启动systemd-networkdsudo systemctl enable --now systemd-networkd

这种方式语法更简洁,但调试和日常管理不如nmcli直观,且与桌面环境整合度低。

经过以上步骤,你的UOS(Deepin)系统应该已经能够稳定地让双网卡各司其职了。这套配置的关键在于理解策略路由的“匹配-查询”逻辑,以及耐心地测试每一条路径。刚开始可能会觉得复杂,但一旦配置成功,它就能在后台默默无闻地稳定工作,极大提升在多网络环境下的工作效率。如果在配置过程中遇到任何问题,多使用ip route showip rule listtraceroute这三个命令进行诊断,它们能告诉你数据包到底选择了哪条路。

← 返回列表