How to Set Up Linux Server As A Router with NAT

Solution 1:

To set a linux machine as a router you need the following

1- Enable forwarding on the box with

echo 1 > /proc/sys/net/ipv4/ip_forward

Assuming your public interface is eth1 and local interface is eth0

2- Set natting the natting rule with:

iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

3- Accept traffic from eth0:

iptables -A INPUT -i eth0 -j ACCEPT

4- Allow established connections from the public interface.

iptables -A INPUT -i eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT

5- Allow outgoing connections:

iptables -A OUTPUT -j ACCEPT

Solution 2:

I think the other answers missed some important points. Here's another way, assuming iptables is in a fresh state, once again using eth0 as the internal interface and eth1 as external:

  1. Enable IP forwarding in the kernel:

    echo 1 > /proc/sys/net/ipv4/ip_forward
    # or
    sysctl -w net.ipv4.ip_forward=1
    

    To persist this change after reboot, add or uncomment net.ipv4.ip_forward=1 in /etc/sysctl.conf or a file in /etc/sysctl.d.

  2. Enable masquerade on eth1 to rewrite the source address on outgoing packets. If you truly want symmetric NAT, you'll need the --random at the end:

    iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE --random
    
  3. Configure forwarding rules. By default, iptables will forward all traffic unconditionally. You probably want to restrict inbound traffic from the internet, but allow all outgoing:

    # Allow traffic from internal to external
    iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
    # Allow returning traffic from external to internal
    iptables -A FORWARD -i eth1 -o eth0 -m conntrack --ctstate RELATED, ESTABLISHED -j ACCEPT
    # Drop all other traffic that shouldn't be forwarded
    iptables -A FORWARD -j DROP
    

Note that we didn't touch the INPUT or OUTPUT chains in the filter table; these have nothing to do with being a router.

To persist these firewall changes after reboot:

iptables-save > /etc/sysconfig/iptables
systemctl enable --now iptables

This step will vary depending on the Linux distribution.

Solution 3:

This is the simple script could do the trick it has all the essence which needed by router its well tested on UBUNTU 16.04

#!/bin/bash
# This script is written to make your Linux machine Router
# With this you can setup your linux machine as gateway.
# Author @ Mansur Ul Hasan
# Email  @ [email protected]

  # Defining interfaces for gateway.
  INTERNET=eth1
  LOCAL=eth0

# IMPORTANT: Activate IP-forwarding in the kernel!

   # Disabled by default!
   echo "1" > /proc/sys/net/ipv4/ip_forward

   # Load various modules. Usually they are already loaded 
   # (especially for newer kernels), in that case 
   # the following commands are not needed.

   # Load iptables module:
   modprobe ip_tables

   # activate connection tracking
   # (connection's status are taken into account)
   modprobe ip_conntrack

   # Special features for IRC:
   modprobe ip_conntrack_irc

   # Special features for FTP:
   modprobe ip_conntrack_ftp

   # Deleting all the rules in INPUT, OUTPUT and FILTER   
   iptables --flush

   # Flush all the rules in nat table 
   iptables --table nat --flush

   # Delete all existing chains
   iptables --delete-chain

   # Delete all chains that are not in default filter and nat table
   iptables --table nat --delete-chain

   # Allow established connections from the public interface.
   iptables -A INPUT -i $INTERNET -m state --state ESTABLISHED,RELATED -j ACCEPT

   # Set up IP FORWARDing and Masquerading
   iptables --table nat --append POSTROUTING --out-interface $INTERNET -j MASQUERADE
   iptables --append FORWARD --in-interface $LOCAL -j ACCEPT

   # Allow outgoing connections
   iptables -A OUTPUT -j ACCEPT