Background
Network Address Translation (NAT) is a common use case in network configuration. It allows the network manager to translate network address from one into the other, effectively hiding the original IP address.
Here is a document from RedHat giving brief introduction about different NAT types.
Masquerading
Source NAT (SNAT)
Destination NAT (DNAT)
Redirect
This article focuses on Masquerading among all these types. It is the very NAT type to change the source IP address of packets. It’s widely used at network gateways, mapping the source IP address from a certain internal subnet to a public IP address. Such ability is useful when you don’t have enough public IP addresses for each subnet hosts, or want to hide internal network details for security reasons.
iptables
is the classic tool in Linux for packet filtering and NAT. It
provides simple yet powerful means to apply management rules. For a detailed
manual about it, refer to this site.
Describing the Problem
The problem I try to demonstrate in this article is about setting a gateway for an internal subnet. There’re two hosts in my scenario. They are connected together via a 100Mbps switch with wired connection, assigned each a static IP address to form the network.
In addition, the laptop is also capable of creating wireless connection to the school’s public network. The goal is to make the laptop the gateway of the my subnet, allowing Internet access for the workstation, while hiding it from the outside.
The Solution
Enable packet forwarding
Packet forwarding is to forward packets from one interface to another. Here in
my case, I should forward all packets from enp5s0
to wlp3s0
. Generally, the
Linux kernel is compiled with the functionality to forward packets.
# Access the system configuration to check if packet forwarding is enabled.
cat /proc/sys/net/ipv4/ip_forward
# The content should be "1" if it's enabled. Otherwise try writing "1" to it in
# order to enable.
echo 1 >/proc/sys/net/ipv4/ip_forward
# In order to make the changes permanent, write following lines into
# /etc/sysctl.conf.
echo "net.ipv4.ip_forward = 1" >>/etc/sysctl.conf
Apply iptables
rules
The solution can be quite simple with the help of iptables
. The following
rules should be set.
# Be noticed that `iptables` must run under `root`
# Forwarding packets from `enp5s0` to `wlp3s0`
iptables -A FORWARD -i enp5s0 -o wlp3s0 -j ACCEPT
# Enabling address masquerade on `wlp3s0`
iptables -t nat -A POSTROUTING -o wlp3s0 -j MASQUERADE
# Save configurations permanently
iptables-save >/etc/sysconfig/iptables
These commands should do the work. For a more detailed explanation about the
commands above, please refer to the iptables
manual.
iptables
and firewalld
In case you’re a Fedora, RedHat, CentOS, etc. user, it becomes a little tricky
to handle the iptables
rules. Since RedHat is deploying its brand-new
firewalld
solution for network management, it brings some conflicts between
iptables
and firewalld
.
To solve the conflicts, one have to choose between them, enabling one while
disabling the other in systemctl
. Since it’s said that iptables
is getting
deprecated in the system, it may be better to use firewalld
. But here I stick
to iptables
to leave things simple (And it’s easier to find tutorials for
iptables
).
On Fedora 36 what I’m using, because of the existence of firewalld
, the
package iptables-services
is by default uninstalled, thus have to be handled
manually with dnf install
.