当前位置: 首页 > news >正文

Ubuntu服务器双网卡NAT与桥接共存配置实战

1. 项目概述与核心需求

最近在折腾一台Ubuntu 20.04的服务器,它有两张物理网卡,我需要实现一个有点“拧巴”但又很实用的网络配置:让两张网卡同时工作,一张走NAT模式用于安全地访问外网,另一张走桥接模式,获得一个与物理网络同网段的独立IP,方便局域网内其他设备直接访问。最关键的是,无论通过哪张网卡,我都要能从外部远程SSH连接上这台机器。这个需求听起来简单,但实际操作时,如果对Linux网络管理、路由表和防火墙规则没有清晰的理解,很容易把自己绕进去,导致要么上不了网,要么远程连不上,或者两张网卡“打架”。

这种配置的典型场景,比如你有一台开发测试服务器,eth0通过NAT连接公司内网(或家庭路由器后的网络),可以安全地访问互联网下载包;而eth1桥接出来,获得一个固定的局域网IP(如192.168.1.100),方便同局域网内的其他开发机、测试设备用低延迟、高带宽直接访问它上面的服务(如数据库、Web API)。这比单纯用端口转发要灵活和直接得多。下面,我就把这次配置的完整思路、详细步骤,以及我踩过的几个坑,从头到尾捋一遍。

2. 网络拓扑设计与核心思路拆解

2.1 物理与逻辑拓扑

首先,我们要在脑子里构建出清晰的网络拓扑图。假设我们的Ubuntu 20.04服务器有两张网卡:

  • ens33 (或 eth0): 我们计划将它配置为NAT模式。在虚拟机环境下(如VMware/VirtualBox),这意味着它连接到一个虚拟的NAT网络,由虚拟网络设备(如VMnet8)分配一个私有IP(通常是192.168.xxx.xxx),并通过宿主机进行地址转换访问外网。对于物理服务器,这可以理解为连接到一个已经做了NAT转换的路由器LAN口。
  • ens38 (或 eth1): 我们计划将它配置为桥接模式。在虚拟机环境下,这意味着它直接“桥接”到宿主机的物理网卡上,从宿主机的物理网络(比如你的家庭路由器DHCP)获取一个同网段的IP。对于物理服务器,就是直接插到交换机上,从上层DHCP获取IP。

我们的目标是:系统同时使用这两张网卡,但默认路由(去往互联网的流量)走NAT网卡(ens33);而去往局域网特定网段的流量(比如桥接网卡所在的网段)走桥接网卡(ens38)。并且,两个IP地址都要能响应SSH连接。

2.2 配置策略与潜在冲突

这里最核心的挑战是避免路由冲突策略混乱。如果两张网卡都从DHCP获取了默认网关,系统就会产生两个默认路由,导致网络行为不可预测,时通时断。因此,我们的策略必须明确:

  1. 单一默认网关原则: 只有一张网卡(这里是NAT网卡ens33)配置网关,作为系统访问非本地网络(主要是互联网)的出口。
  2. 静态路由补充: 为桥接网卡(ens38)所在的局域网网段,添加一条明确的静态路由,指定从ens38网卡发出。这样,访问局域网内其他设备时,流量就不会“绕路”走NAT再折返,而是直接通过桥接网卡高效通信。
  3. 防火墙放行: Ubuntu 20.04默认使用ufwiptables管理防火墙。必须确保防火墙规则允许从两个网络接口的IP地址接入SSH端口(默认为22)。
  4. SSH服务监听: 确保SSH服务配置为监听所有接口(0.0.0.0),而不是只监听某个特定IP。

注意: 在开始之前,请务必确认你的两张网卡在系统中已被正确识别。使用ip link showls /sys/class/net命令查看网卡名称(可能是ens33, ens34, eth0, eth1等)。下文将以ens33(NAT)和ens38(桥接)为例。

3. 详细配置步骤与实操要点

我们将通过修改Ubuntu 20.04的Netplan配置文件来完成主要配置。Netplan是Ubuntu 17.10之后引入的网络配置工具,使用YAML格式,比传统的/etc/network/interfaces更现代。

3.1 备份与定位Netplan配置文件

首先,进入Netplan配置目录并找到主配置文件。

cd /etc/netplan ls -la

你可能会看到类似01-netcfg.yaml50-cloud-init.yaml00-installer-config.yaml的文件。请根据你的实际文件名进行后续操作。强烈建议先备份!

sudo cp /etc/netplan/01-netcfg.yaml /etc/netplan/01-netcfg.yaml.backup

3.2 编辑Netplan配置文件

使用你喜欢的编辑器(如vimnano)打开配置文件。

sudo vim /etc/netplan/01-netcfg.yaml

以下是完整的配置示例,请根据你的网络环境修改IP地址、网关、DNS等参数:

network: version: 2 renderer: networkd # 或者 networkd, 20.04 server版通常用networkd ethernets: # 配置NAT网卡 - ens33 ens33: dhcp4: no # 禁用DHCP,我们使用静态IP以便控制网关 addresses: - 192.168.122.100/24 # 静态IP地址,需与你的NAT网络网段匹配(如VMware的VMnet8通常是192.168.122.0/24) routes: - to: 0.0.0.0/0 via: 192.168.122.1 # NAT网络的网关地址(通常是虚拟网卡的IP,如VMnet8的192.168.122.1) metric: 100 # 为默认路由设置一个度量值(优先级),值越小优先级越高 nameservers: addresses: [8.8.8.8, 114.114.114.114] # DNS服务器 optional: true # 设置为true,即使此网卡未连接,系统也能正常启动 # 配置桥接网卡 - ens38 ens38: dhcp4: no # 同样使用静态IP addresses: - 192.168.1.100/24 # 静态IP地址,需与你的物理局域网网段匹配(如常见的192.168.1.0/24) # 注意:这里不配置默认网关(via),只配置IP和掩码 routes: - to: 192.168.1.0/24 # 添加一条到本地局域网的路由 via: 192.168.1.1 # 指定该局域网的网关(通常是你的物理路由器IP) metric: 200 # 设置一个比默认路由更大的metric,确保去往互联网的流量优先走ens33 nameservers: addresses: [8.8.8.8, 114.114.114.114] optional: true

关键参数解析:

  • addresses: 指定网卡的静态IP地址和CIDR掩码。
  • routes: 这是实现双网卡共存的关键。
    • 对于ens33(NAT),我们添加了一条到0.0.0.0/0(即所有目标)的路由,指向NAT网关,并设置metric: 100。这成为了系统的默认路由
    • 对于ens38(桥接),我们添加了一条到其所在局域网网段(192.168.1.0/24)的特定路由,指向物理局域网的网关,并设置metric: 200。这样,访问192.168.1.x的流量会匹配这条更具体的路由(/24掩码比/0更具体),即使它的metric更高。
  • metric: 路由的度量值,用于决定优先级。当有多条路由可以到达同一目标时,系统优先选择metric值小的。这里我们让默认路由的metric更小,确保其优先级。
  • optional: true: 这个设置非常实用。它告诉系统,即使这张网卡在启动时没有插线或没有连接,也不要等待它超时而阻塞整个系统启动过程。对于服务器,特别是有一张网卡可能不常使用时,建议加上。

3.3 应用网络配置

保存并退出编辑器后,使用以下命令测试配置语法并应用:

sudo netplan try

这条命令会应用配置并给你一个回滚的倒计时(通常是120秒)。在此期间,如果你的SSH连接没有断开,说明配置基本正确,你可以按回车确认。如果连接断开,配置会在倒计时结束后自动回滚。

如果netplan try顺利,或者你想直接应用,可以使用:

sudo netplan apply

应用后,立即检查新的配置是否生效:

ip addr show # 查看IP地址是否配置正确 ip route show # 查看路由表,这是最重要的检查项

你应该在路由表中看到类似下面的输出:

default via 192.168.122.1 dev ens33 proto static metric 100 192.168.1.0/24 via 192.168.1.1 dev ens38 proto static metric 200 192.168.1.0/24 dev ens38 proto kernel scope link src 192.168.1.100 192.168.122.0/24 dev ens33 proto kernel scope link src 192.168.122.100

这表示:默认路由走ens33;去往192.168.1.0/24网段的流量,会通过ens38网关192.168.1.1发出(第一行特定路由),同时系统也知道192.168.1.100这个IP本身在ens38上(第三行直连路由)。

3.4 配置SSH服务监听

默认情况下,Ubuntu的SSH服务(sshd)是监听在所有网络接口(0.0.0.0)上的。但为了确保无误,我们可以检查一下:

sudo ss -tlnp | grep :22

输出中应该看到0.0.0.0:22*:22。如果不是,需要编辑SSH配置文件:

sudo vim /etc/ssh/sshd_config

找到#ListenAddress 0.0.0.0这一行(可能被注释),确保它没有被改成具体的IP地址。保持注释或设置为ListenAddress 0.0.0.0即可。修改后重启SSH服务:

sudo systemctl restart sshd

3.5 配置防火墙(UFW)

Ubuntu 20.04默认可能启用了UFW防火墙。我们需要允许SSH端口通过。

sudo ufw allow ssh # 或者明确指定端口 # sudo ufw allow 22/tcp

如果你需要更精细的控制,可以指定允许来自特定网段的SSH连接,但为了测试双网卡连通性,我们先简单允许所有。

启用UFW(如果尚未启用):

sudo ufw enable

查看规则:

sudo ufw status verbose

4. 功能验证与连通性测试

配置完成后,必须进行全面的测试,确保每张网卡都按预期工作。

4.1 基础连通性测试

  • 测试NAT网卡(ens33)的外网访问

    ping -I ens33 8.8.8.8

    使用-I参数指定从ens33网卡发出ping包。应该能收到回复。

  • 测试桥接网卡(ens38)的局域网访问

    ping -I ens38 192.168.1.1 # 假设192.168.1.1是你的物理路由器

    同样指定从ens38发出。应该能ping通同网段的其他设备。

4.2 路由路径测试

使用traceroutetracepath命令,查看去往不同目标的实际路径。

# 测试去往外网的路径,应该第一跳是NAT网关(192.168.122.1) tracepath -i ens33 8.8.8.8 # 测试去往同局域网另一台主机的路径,应该直接到达,不经过NAT网关 tracepath -i ens38 192.168.1.50 # 假设这是同局域网的另一台电脑

4.3 远程SSH连接测试

这是最终目标,需要从两个不同的网络位置进行测试。

  1. 从NAT网络内部(或宿主机)连接: 在你的宿主机或与NAT网卡同网段的机器上,使用SSH客户端连接NAT IP。

    ssh username@192.168.122.100

    应该能成功连接。

  2. 从桥接网络所在的物理局域网连接: 在连接到你物理局域网(如192.168.1.0/24)的另一台电脑上,使用SSH客户端连接桥接IP。

    ssh username@192.168.1.100

    同样应该能成功连接。

实操心得: 在进行远程测试时,务必先确保能在服务器本地通过ssh localhost连接成功,以排除SSH服务本身的问题。另外,如果使用虚拟机,请确保虚拟网络编辑器的设置正确(NAT网络和桥接网络已正确配置并启用)。

5. 高级排错与深度优化

即使按照步骤操作,也可能遇到各种问题。下面是我在实际操作中遇到的一些典型问题及解决方法。

5.1 常见问题排查表

问题现象可能原因排查命令与解决方案
应用netplan apply后网络断开1. 配置文件语法错误。
2. 网关地址错误或不可达。
3. IP地址冲突。
1. 使用sudo netplan --debug apply查看详细错误。
2. 在服务器本地控制台,检查ip addrip route,并用ping测试网关连通性。
3. 回滚备份配置:sudo cp /etc/netplan/01-netcfg.yaml.backup /etc/netplan/01-netcfg.yaml && sudo netplan apply
可以ping通外网,但无法apt update(域名解析失败)DNS服务器配置错误或未生效。1. 检查/etc/netplan/*.yaml中的nameservers
2. 检查/etc/resolv.conf,看是否被其他服务(如systemd-resolved)覆盖。可以临时修改/etc/resolv.conf,或配置systemd-resolved。
3. 直接ping IP地址(如ping 8.8.8.8)测试网络,再ping域名(如ping google.com)测试DNS。
只能从一个IP地址SSH连接,另一个连不上1. 防火墙(UFW)规则可能只允许了某个子网或接口。
2. SSH服务可能绑定到了特定IP。
3. 路由问题导致返回流量路径错误。
1. 检查UFW规则:sudo ufw status numbered。确保有22/tcp ALLOW Anywhere规则。
2. 检查SSH配置:sudo grep ^ListenAddress /etc/ssh/sshd_config
3. 在服务器上,从“连不上的那个IP”所在网络ping服务器该IP,看是否可达。检查服务器到该客户端的回程路由。
桥接网卡无法获取到IP或无法ping通网关1. 物理连接问题(网线、虚拟机桥接设置)。
2. 桥接的物理网络有MAC地址过滤或DHCP限制。
3. IP地址冲突。
1. 虚拟机检查:确保桥接模式已启用,并正确桥接到了活动的物理网卡。
2. 物理服务器检查:ethtool ens38查看链路状态Link detected: yes
3. 尝试为桥接网卡配置一个非常用IP,或查看路由器DHCP分配列表。
访问互联网速度慢,或部分网站打不开可能出现了路由环路或策略路由问题,流量没有按预期路径走。1. 使用ip route get 8.8.8.8查看去往某个外网地址的实际路由出口,确认是否从ens33出去。
2. 检查是否有其他网络管理服务(如NetworkManager)干扰,Server版建议只用networkd。
3. 使用mtr命令进行持续路由追踪,观察路径是否异常。

5.2 防火墙策略精细化配置

上面的sudo ufw allow ssh是允许所有来源。在生产环境中,你可能需要更安全。

# 假设我们只想允许来自NAT网络(192.168.122.0/24)和桥接局域网(192.168.1.0/24)的SSH连接 sudo ufw delete allow ssh # 先删除之前的宽松规则 sudo ufw allow from 192.168.122.0/24 to any port 22 proto tcp sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp

这样配置后,只有指定两个网段的IP才能连接SSH,安全性更高。

5.3 使用systemd-networkd的额外配置(如遇复杂路由)

对于更复杂的路由策略(如基于源地址的路由),Netplan的YAML配置可能不够用。这时可以编写systemd-networkd的底层drop-in文件。

例如,为ens38添加一个路由表,并设置规则让来自ens38IP的流量使用该路由表:

  1. 创建路由表文件。编辑/etc/iproute2/rt_tables,添加一行,例如:
    200 bridge-net
  2. ens38创建networkd配置片段:
    sudo vim /etc/systemd/network/10-ens38.route
    内容如下:
    [Route] Gateway=192.168.1.1 Destination=192.168.1.0/24 Table=bridge-net
  3. 创建路由规则配置片段:
    sudo vim /etc/systemd/network/10-ens38.routing-policy
    内容如下:
    [RoutingPolicyRule] From=192.168.1.100/32 Table=bridge-net Priority=100
  4. 重启systemd-networkd服务:
    sudo systemctl restart systemd-networkd

这种方法提供了极强的灵活性,但对于简单的双网卡NAT/桥接共存,之前的Netplan配置通常已足够。

5.4 开机自启与服务依赖

确保网络配置在开机时能正确应用。Netplan服务通常由systemd-networkd实现,其开机自启是默认的。你可以检查相关服务状态:

sudo systemctl status systemd-networkd sudo systemctl status netplan-apply

如果服务器上运行着一些依赖网络的服务(如Docker, Nginx),你可能需要在Netplan配置中为网卡设置optional: true,并考虑在服务配置中添加After=network-online.targetWants=network-online.target,以确保网络就绪后再启动这些服务。

经过以上步骤,你的Ubuntu 20.04服务器就应该能够稳定地运行在双网卡(NAT+桥接)模式下,并且可以通过两个IP地址进行远程SSH管理。这种配置在混合网络环境、开发测试、服务隔离等场景下非常实用。关键点始终在于理解路由表的工作原理,并清晰地规划每张网卡的职责。如果在配置过程中遇到本指南未覆盖的奇怪问题,多使用ip route get <目标IP>命令来追踪数据包的实际路径,这是最直接的诊断工具。

http://www.jsqmd.com/news/1377896/

相关文章:

  • CUTTag与RNA-seq多组学关联分析:5大实用套路与工程实践
  • JS逆向攻防实战:反调试、代码混淆与AST加密的对抗技术
  • 外文人工翻译平台测评:平台体验 - 逢君学术-AI论文写作
  • 前端跨标签页状态同步:三层架构解决多Tab聊天鬼打墙
  • 终极SoundCloud音乐下载器完整指南:从零开始构建你的离线音乐库
  • LoongForge优化实战:将大型视觉-语言模型训练吞吐提升2.3倍
  • Hive SQL字符串匹配:LIKE、RLIKE与REGEXP核心区别与实战指南
  • 【2026-08】铁砂混凝土优秀公司选哪个?钢箱梁铁砂混凝土、钢渣混凝土优选——可耐可特 - 多才菠萝
  • 响应时间(Response Time, RT)是衡量系统性能的关键指标之一,表示从客户端发出请求开始,到接收到完整响应为止所经历的总耗时
  • Coze平台一站式AI Bot开发:从零构建智能会议助手并集成飞书微信
  • 分布式链路追踪Java实战11
  • 5分钟掌握OpenSpeedy:让你的Windows游戏体验提升300%的开源加速神器
  • 为AI助手添加视频理解能力:FFmpeg与Whisper本地部署实战
  • Unity书本翻页效果全解析:从插件使用到自定义Shader实现
  • 投票链接被微信拦截怎么办?使用云众评选降低风险 - 微信投票小程序
  • PUBG压枪宏终极方案:罗技鼠标如何帮你告别后坐力烦恼?
  • C++ unordered_map与map深度对比:哈希表原理、性能调优与实战选型指南
  • Cocos Creator多语言插件开发:从数据驱动到组件化实战
  • 万字拆解 BabyAGI 认知架构:从100行Python到自主智能体的底层逻辑
  • VC6.0部署与开发实战:从环境搭建到MFC应用
  • AI PC异构计算新范式:解析NVIDIA RTX Spark与联发科SoC的协同架构
  • 05-Git常用高阶操作:reset/rebase/cherry-pick/merge冲突解决
  • 工程机械工件焊缝硬度精准检测解决方案 - 仪器小丸子
  • 本地部署Krea-2-Turbo-GGUF与ComfyUI:构建可视化AI生图工作流
  • 开源视频知识蒸馏工具“仓颉.Skill”2.0:从原理到部署实战
  • Postman入门指南:从HTTP请求到API测试自动化
  • 基于Playwright的滑块验证码自动化破解实战指南
  • 分布式链路追踪Java实战12
  • 5分钟解锁Wand高级功能:开源增强工具全面指南
  • 从1到n求和:编程思维、算法优化与OJ实战全解析