Skip to content

Linux Dual-NIC NAT Gateway Guide

Abstract: In HPC clusters or private cloud environments, compute nodes often reside on a private network. This guide details how to configure a Dual-NIC Linux node (Head Node or Bastion Host) as a NAT Gateway.

1. Scenario & Topology

Turn a Linux host with two interfaces into a router.

Topology:

text
          Internet (Public/External)
                 |
        +--------+--------+
        |   [ens17f1]     |  <-- WAN Interface
        |   NAT Gateway   |
        |    (Linux)      |
        |   [ens18]       |  <-- LAN Interface
        +--------+--------+
                 |
        +--------+--------+
        |   LAN Switch    |
        +--------+--------+
                 |
      [Compute 1] [Compute 2] ...
  • Use Cases: Lab environments, K8s/OpenStack SNAT exits, migration bridges.

2. Configuration Steps

2.1 Enable IPv4 Forwarding

Linux disables packet forwarding by default.

Temporary:

bash
sysctl -w net.ipv4.ip_forward=1

Permanent: Edit /etc/sysctl.conf:

bash
net.ipv4.ip_forward = 1

Apply:

bash
sysctl -p

2.2 NAT Rules (Iptables Method)

The most universal method.

1. Dynamic Public IP (MASQUERADE) If WAN (ens17f1) uses DHCP:

bash
iptables -t nat -A POSTROUTING -o ens17f1 -j MASQUERADE

2. Static Public IP (SNAT) If WAN IP is static (e.g., 1.2.3.4), SNAT is faster:

bash
# -s specifies internal subnet
iptables -t nat -A POSTROUTING -s 172.12.12.0/24 -o ens17f1 -j SNAT --to-source 1.2.3.4

3. Forward Chain Security Allow traffic routing:

bash
# Allow LAN to WAN
iptables -A FORWARD -i ens18 -o ens17f1 -j ACCEPT

# Allow established return traffic
iptables -A FORWARD -i ens17f1 -o ens18 -m state --state RELATED,ESTABLISHED -j ACCEPT

2.3 NAT Rules (Firewalld Method)

Best for RHEL / CentOS / Rocky Linux.

bash
# 1. Add WAN interface to public zone and enable masquerade
firewall-cmd --zone=public --add-interface=ens17f1 --permanent
firewall-cmd --zone=public --add-masquerade --permanent

# 2. Add LAN interface to trusted zone
firewall-cmd --zone=trusted --add-interface=ens18 --permanent

# 3. Reload
firewall-cmd --reload

2.4 NAT Rules (Nftables Method)

For modern Debian/Ubuntu. Edit /etc/nftables.conf:

text
table ip nat {
    chain postrouting {
        type nat hook postrouting priority 100;
        # Replace with your WAN interface
        oif "ens17f1" masquerade;
    }
}

Apply:

bash
nft -f /etc/nftables.conf
systemctl enable nftables

3. Client Configuration

On internal nodes, set the Default Gateway to the NAT node's LAN IP.

Assume Gateway LAN IP is 172.12.12.100.

Temporary Test:

bash
ip route add default via 172.12.12.100 dev eth0

Permanent (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]

Permanent (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. Troubleshooting

  1. Check Forwarding:

    bash
    cat /proc/sys/net/ipv4/ip_forward
    # Must return 1
  2. Check Counters:

    bash
    iptables -t nat -L -n -v

    See if packet counts increase in POSTROUTING.

  3. Tcpdump: Monitor both interfaces on the gateway:

    bash
    # Term 1: Incoming from LAN
    tcpdump -i ens18 icmp
    
    # Term 2: Outgoing to WAN (Source IP should be NAT'ed)
    tcpdump -i ens17f1 icmp

5. Best Practices

  • Persistence: Install iptables-services (RHEL) or iptables-persistent (Debian) to save rules across reboots.
  • Security: Restrict NAT access to specific internal subnets only.
  • MTU Clamping: If WAN is PPPoE, enable TCP MSS Clamping to fix packet drops:
    bash
    iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

AI-HPC Organization