在日常的网络拓扑规划、嵌入式开发或者实验室测试中,我们经常会遇到这样的场景:
主机 B (Ubuntu B)是一台双网口计算机,一个网口连接互联网(WAN),另一个网口直连主机 A (Ubuntu A)。为了网络安全或业务合规,我们需要满足以下需求:
- Ubuntu B自身能够正常上外网。
- Ubuntu A能够与Ubuntu B自由通信(如 SSH、数据传输、共享服务等)。
- Ubuntu A绝对不能通过 Ubuntu B 访问外网。
本文将手把手带你完成这个网络隔离与互通的配置过程。
1. 网络拓扑与 IP 规划
首先,我们梳理两个系统的网卡和 IP 配置。
- 外网网口(连接 Internet):仅在 Ubuntu B 上,网口名称为
enx6c1ff72115c1。 - 内网网口(直连局域网):
- Ubuntu B 的内网口(假设名称为
enp3s0):配置静态 IP192.168.100.1。 - Ubuntu A 的网口(假设名称为
eth0):直连 Ubuntu B 的内网口,配置静态 IP192.168.100.2。
- Ubuntu B 的内网口(假设名称为
[ Internet ] │ ▼ (enx6c1ff72115c1) ┌───────────┐ │ Ubuntu B │ (192.168.100.1 / enp3s0) └───────────┘ │ ▼ (直连网线 / 私有交换机) ┌───────────┐ │ Ubuntu A │ (192.168.100.2 / eth0) └───────────┘2. 步骤一:基础 IP 配置(路由物理隔离)
要限制 Ubuntu A 上网,最基础的第一道关卡是在 Ubuntu A 上不配置默认网关(Default Gateway)和 DNS 服务器。
在 Ubuntu A 上的配置:
编辑 Netplan 配置文件(通常位于/etc/netplan/01-netcfg.yaml或类似文件):
network:version:2renderer:networkdethernets:eth0:# 直连网卡名称dhcp4:noaddresses:-192.168.100.2/24# 重点:不要写 gateway4 (默认网关) 和 nameservers (DNS)应用配置:
sudonetplan apply在 Ubuntu B 上的配置(内网口):
同样在 Ubuntu B 的 Netplan 中配置其内网口 IP:
network:version:2renderer:networkdethernets:enp3s0:# 连接 A 的网卡dhcp4:noaddresses:-192.168.100.1/24应用配置:
sudonetplan apply此时的效果:Ubuntu A 与 B 之间可以互相
ping通。但即使 A 尝试向外网发送数据包,因为本地路由表中没有“默认网关”,数据包在 A 本地就会被丢弃。
3. 步骤二:关闭 Ubuntu B 的系统级内核转发
为了防止 Ubuntu A 侧人为手动添加了网关路由(例如ip route add default via 192.168.100.1),我们必须在 Ubuntu B 上从系统内核层面关闭 IP 转发功能。
默认情况下,Ubuntu 是关闭 IP 转发的。可以通过以下步骤进行确认和加固:
- 临时关闭:
sudosysctlnet.ipv4.ip_forward=0 - 永久关闭:
编辑/etc/sysctl.conf文件,确保包含以下这一行:
保存并重新加载配置:net.ipv4.ip_forward = 0sudosysctl-p
4. 步骤三:配置防火墙拦截(双重保险)
在实际复杂的企业或实验室网络环境中,Ubuntu B 可能会因为运行 Docker、VPN 或其他网络代理服务,而不得不开启ip_forward转发功能。
如果 Ubuntu B 必须开启转发,我们应该如何针对性地仅禁止其它网口转发到外网网口enx6c1ff72115c1呢?答案是使用iptables进行精确拦截。
在 Ubuntu B 上运行以下命令:
sudoiptables-IFORWARD-oenx6c1ff72115c1-jDROP规则详解:
-I FORWARD:在FORWARD(转发)链的最顶部插入一条拦截规则。-o enx6c1ff72115c1:匹配所有输出(Outgoing)网口为外网网口enx6c1ff72115c1的中转数据包。-j DROP:直接丢弃匹配到的数据包。
为什么不影响 B 自己上网?
FORWARD链只处理经由 B 转发/中转的数据(如来自 A 的包)。B 自身产生的上网数据会走OUTPUT链,因此 B 自身上网完全不受此规则限制。
保存防火墙规则(防止重启失效):
在 Ubuntu 上,我们推荐使用iptables-persistent工具来保存和自动加载规则:
# 1. 安装工具(安装过程中会弹窗询问是否保存当前规则,选择“是”)sudoapt-getinstalliptables-persistent# 2. 如果以后修改了规则,运行以下命令手动保存规则:sudoiptables-save|sudotee/etc/iptables/rules.v45. 验证测试
配置完成后,我们通过以下三个测试来验证方案是否成功:
测试 1:验证 Ubuntu B 自身上网是否正常
在 Ubuntu B 上运行:
ping-c4baidu.com- 预期结果:可以正常
ping通,B 自身上网一切正常。
测试 2:验证 A 与 B 之间局域网互通是否正常
在 Ubuntu A 上pingB 的内网 IP:
ping-c4192.168.100.1在 Ubuntu B 上pingA 的内网 IP:
ping-c4192.168.100.2- 预期结果:双向均可秒通,局域网内的 SSH、服务访问一切正常。
测试 3:验证 Ubuntu A 无法上网
在 Ubuntu A 上尝试访问外网:
ping-c4baidu.com# 或者直接 ping 外网公网 IPping-c48.8.8.8- 预期结果:提示
Network is unreachable(未配默认网关时)或无限超时(手动配了网关但被 B 拦截时)。A 无法访问任何 Internet 资源。
6. 总结
通过“Netplan 基础路由隔离 + 系统内核转发关闭 +iptables规则双重保险”的组合方案,我们成功构建了安全的单向网络隔离:
- 安全性高:即使 Ubuntu A 被植入后门或手动修改路由,在 Ubuntu B 的防火墙关卡也会被直接丢弃。
- 副作用小:完全不会影响 Ubuntu B 自身的网络体验,且保持了 A 与 B 之间的高速局域网互通。