Linux 双网卡 NAT 网关配置指南
摘要: 在 HPC 集群或私有云环境中,计算节点通常位于内网。本文档详细介绍了如何利用一台双网卡 Linux 节点(Head Node 或跳板机)构建 NAT 网关,使内网节点能够访问互联网。
1. 场景与拓扑
当一台 Linux 主机拥有两个网络接口时,可将其配置为 NAT 网关。
典型拓扑:
text
Internet (公网/外部网络)
|
+--------+--------+
| [ens17f1] | <-- 外网接口 (WAN)
| NAT Gateway |
| (Linux) |
| [ens18] | <-- 内网接口 (LAN)
+--------+--------+
|
+--------+--------+
| 内网交换机 |
+--------+--------+
|
[计算节点 1] [计算节点 2] ...- 适用场景: 实验室环境、K8s/OpenStack SNAT 出口、多网段迁移过渡。
2. 核心配置步骤
2.1 启用 IPv4 转发
Linux 内核默认禁用流量转发,必须显式开启。
临时生效:
bash
sysctl -w net.ipv4.ip_forward=1永久生效: 编辑 /etc/sysctl.conf 添加:
bash
net.ipv4.ip_forward = 1应用配置:
bash
sysctl -p2.2 配置 NAT 规则 (Iptables 方案)
这是最通用的方案,适用于绝大多数 Linux 发行版。
1. 动态公网 IP (MASQUERADE) 如果外网接口 (ens17f1) 通过 DHCP 获取 IP,使用伪装模式:
bash
iptables -t nat -A POSTROUTING -o ens17f1 -j MASQUERADE2. 固定公网 IP (SNAT) 如果外网 IP 是固定的(例如 1.2.3.4),推荐使用 SNAT 以提升性能:
bash
# -s 指定内网网段
iptables -t nat -A POSTROUTING -s 172.12.12.0/24 -o ens17f1 -j SNAT --to-source 1.2.3.43. 配置转发链 (Forward Chain) 为了安全起见,应配置转发规则:
bash
# 允许内网到外网的流量
iptables -A FORWARD -i ens18 -o ens17f1 -j ACCEPT
# 允许外网返回的已建立连接的流量
iptables -A FORWARD -i ens17f1 -o ens18 -m state --state RELATED,ESTABLISHED -j ACCEPT2.3 配置 NAT (Firewalld 方案)
适用于 RHEL / CentOS / Rocky Linux 等默认启用 Firewalld 的系统。
bash
# 1. 将外网接口加入 public 区域并开启伪装
firewall-cmd --zone=public --add-interface=ens17f1 --permanent
firewall-cmd --zone=public --add-masquerade --permanent
# 2. 将内网接口加入 trusted 区域 (或 internal)
# 允许内网流量进入网关
firewall-cmd --zone=trusted --add-interface=ens18 --permanent
# 或者仅信任特定源网段
# firewall-cmd --zone=trusted --add-source=172.12.12.0/24 --permanent
# 3. 重载配置
firewall-cmd --reload2.4 配置 NAT (Nftables 方案)
适用于新版 Debian/Ubuntu 或追求高性能的场景。编辑 /etc/nftables.conf:
text
table ip nat {
chain postrouting {
type nat hook postrouting priority 100;
# 将 ens17f1 替换为你的外网接口名
oif "ens17f1" masquerade;
}
}加载配置:
bash
nft -f /etc/nftables.conf
systemctl enable nftables3. 客户端配置
在内网节点上,需要将默认网关指向 NAT 节点的内网 IP。
假设 NAT 节点内网 IP 为 172.12.12.100。
临时测试:
bash
ip route add default via 172.12.12.100 dev eth0永久配置 (Netplan - Ubuntu):
yaml
network:
ethernets:
eth0:
addresses: [172.12.12.101/24]
routes:
- to: default
via: 172.12.12.100
nameservers:
addresses: [8.8.8.8, 1.1.1.1]永久配置 (NetworkManager - RHEL):
bash
nmcli con mod "System eth0" ipv4.gateway 172.12.12.100
nmcli con mod "System eth0" ipv4.dns "8.8.8.8 1.1.1.1"
nmcli con up "System eth0"4. 调试与排错
如果内网机器无法上网,请按以下步骤排查:
检查内核转发:
bashcat /proc/sys/net/ipv4/ip_forward # 必须输出 1检查 iptables 计数:
bashiptables -t nat -L -n -v观察
POSTROUTING链的pkts(包计数) 是否在增长。Tcpdump 抓包 (神器): 在网关上同时抓两个网口:
bash# 终端 1: 看内网口是否有请求进来 tcpdump -i ens18 icmp # 终端 2: 看外网口是否有包转发出去 (且源 IP 应变为外网 IP) tcpdump -i ens17f1 icmp
5. 最佳实践与安全
- 规则持久化: 对于 iptables 用户,务必安装
iptables-services(RHEL) 或iptables-persistent(Debian) 以免重启失效。 - 安全加固: 建议仅允许内网特定网段访问 NAT,并禁止从外网接口访问网关的 SSH 端口(除非有 VPN)。
- MTU 问题: 如果外网是 PPPoE 或特定隧道,可能需要调整 MSS Clamping 避免大包丢弃:bash
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
