Setup NAT on Linux (iptables/nftables/firewalld)
The Setup
Having this set up where Machine A
like to connect to the Internet via Machine B
.
+-------------------+ +-----------------+ | | | Machine B | | Machine A | | (the gateway) | | (the client) | | | | | | | | eth0 +----------+ eth1 eth0 | +-------------------+ +-------------+---+ | | .-~~~-. | .- ~ ~-( )_ _ | / ~ -. | | internet \<----+ \ .' ~- . _____________ . -~
Iptables
Add the following lines to the iptables
iptables -I FORWARD -o eth1 -m comment --comment "NAT" -j ACCEPT iptables -I FORWARD -i eth1 -m comment --comment "NAT" -j ACCEPT iptables -I POSTROUTING -o eth0 -m comment --comment "NAT" -j MASQUERADE -t nat
and make sure to enable forwarding on Machine B
sysctl -w net.ipv4.ip_forward=1
Firewalld
If for example the interface eth0
is part of the public
zone and eth1
is part of the internal
zone, we just need to run
firewalld-cmd --zone=public --add-masquerade # To make this setting persistent, repeat the command adding the --permanent option.
With RHEL/CentOS9 there is a need to add a policy, source[1]
// create new policy firewall-cmd --permanent --new-policy policy_int_to_ext firewall-cmd --permanent --policy policy_int_to_ext --add-ingress-zone internal firewall-cmd --permanent --policy policy_int_to_ext --add-egress-zone external firewall-cmd --permanent --policy policy_int_to_ext --set-priority 100 firewall-cmd --permanent --policy policy_int_to_ext --set-target ACCEPT // Enable masquerade on external; 'forward' does not need to be set firewall-cmd --permanent --zone=external --add-masquerade // restart firewalld systemctl restart firewalld.service
The policy looks like this…
# firewall-cmd --info-policy policy_int_to_ext policy_int_to_ext (active) priority: 100 target: ACCEPT ingress-zones: internal egress-zones: external services: ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
Resources
- https://forums.fedoraforum.org/archive/index.php/t-327324.html