Setting Up Linux Network Gateway Using iptables and route
Posted on In Linux, Network, Software, TutorialSharing the networking is important and setting up a gateway is a good solution to it. Building up the gateway on a Linux box is easy, cost efficient and reliable. With a Linux box, you can share the internet connection or the only cable connected to the network.
Table of Contents
The Linux box network configuration
The Linux box that we use has this configuration:
NIC1: eth0 with ip 192.168.0.1 connected to our small local area network.
NIC2: eth1 with ip 198.51.100.1 connected to another network such as a public network connected to Internet.
Now we want to share this Linux box’s connection with the other computers in the local area network with ip in 192.168.0.0/16.
Setting up the gateway
All the operations in this part is done under root on the Linux gateway.
Manipulate the IP route table
# ip route add 192.168.0.0/16 dev eth0
or
# route add -net 192.168.0.0/16 dev eth0
Enable Linux IP forwarding
# sysctl -w net.ipv4.ip_forward=1
or
# echo 1 > /proc/sys/net/ipv4/ip_forward
You can also make the setting permanent in `/etc/sysctl.conf
by adding a line below to /etc/sysctl.conf:
net.ipv4.ip_forward = 1
Set up SNAT by iptables
Change the source IP of out packets to gateway’s IP. Don’t worry since iptables will automatically change the replied packet’s destination IP to the original source IP.
# iptables -t nat -A POSTROUTING ! -d 192.168.0.0/16 -o eth1 -j SNAT --to-source 198.51.100.1
Instead of using SNAT, another way is to use MASQUERADE:
# iptables -t nat -A POSTROUTING ! -d 192.168.0.0/16 -o eth1 -j MASQUERADE
However, please note that, for static IPs, SNAT is suggested as from the iptables man page:
> This target is only valid in the nat table, in the POSTROUTING chain. It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target. Masquerading is equivalent to specifying a mapping to the IP address of the interface the packet is going out, but also has the effect that connections are forgotten when the interface goes down. This is the correct behavior when the next dialup is unlikely to have the same interface address (and hence any established connections are lost anyway).
Some other discussion on the Web: http://lists.debian.org/debian-firewall/2002/02/msg00020.html
And then make sure that the other iptables tables do not deny these connections. If you have problem in this step, you can try
# iptables -F # iptables -t nat -F # iptables -t nat -A POSTROUTING ! -d 192.168.0.0/16 -o eth1 -j SNAT --to-source 198.51.100.1
to allow all connections in. But there may be security problems after open all ports to the public. Firewall should be carefully configured.
By now, the we have set up the Linux gateway.
Client side configuration
On client such as Linux or Windows with IP 192.168.0.4, set the network connection to use this profile:
The configuration profile:
Gateway: 192.168.0.1.
DNS Server: your ISP’s DNS server IP addresses.
The method to configure the network maybe different from using NetworkManager and network and Windows.
You can try this command on Linux:
# ip route add default via 192.168.0.1 dev eth0
or
# route add default gw 192.168.0.1 eth0
You can use this GUI/TUI tool on Fedora / RedHat / CentOS systems:
# system-config-network
or
# system-config-network-tui
Remember to enable forwarding in the FORWARD chain:
# iptables -I FORWARD -j ACCEPT
more strict rules are also suggested.
Didn’t work until I added this rule. Thank you.
Another option for configuring iptables:
# iptables -I FORWARD -j ACCEPT
# iptables -t nat -I POSTROUTING –out-interface eth1 -j MASQUERADE
Instead of using SNAT, another way is to use MASQUERADE:
# iptables -t nat -A POSTROUTING ! -d 192.168.0.0/16 -o eth1 -j MASQUERADE
However, for static IPs, SNAT is suggested as from the iptables man page ( https://www.systutorials.com/docs/linux/man/8-iptables/ ):
Some other discussion on the Web:
http://lists.debian.org/debian-firewall/2002/02/msg00020.html
I guess “sysctl -w net.ipv4.ip.forward=1” should be “sysctl -w net.ipv4.ip_forward=1” with the underscore ;-)
Oh, yes. Fixed. Thanks for pointing out the typo.
why using the negation ! -d 192.168.0.0/16 on eth1??
Please don’t use random IP addresses for examples. If you need an example IP address, you should review RFC5735 and look for “TEST-NET”
Good point. I have changed the public IP used to TEST-NET one.