We have a simple router which has NAT of symmetric type, but because this router doesn't provide us with any debugging interface, we cannot figure out if a specific packet reaches the NAT or not.

Thus we want to setup a LINUX computer making it be a router with symmetric NAT, in this way we can capture all packets to this "NAT" and get the information we want. How can we do this on linux (Fedora system, kernel 2.6.xx)?


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
  • 2
    INPUT and OUTPUT chains affect only packets actually addressed to the router and packets actually generated by the router, respectively. What you need are rules on the FORWARD chain, which handle packets passing through. – pepoluan Jan 3 '14 at 15:38
  • yes correct, but when you do natting the packets are sent via the public interface and they are sent through the OUTPUT chain if i am not mistaken here, if all the ips are public and you are not doing natting then only the forward chain is needed, the same for the INPUT as the packets are sent via the public interface ip you will need to allow the previously established sessions to come back through the INPUT chain. – MohyedeenN Jan 3 '14 at 15:42
  • 2
    Um, I don't think so. All Netfilter diagrams I found on the Internet indicates that OUTPUT chains apply only to packets generated by Local Processes. For example: upload.wikimedia.org/wikipedia/commons/8/8f/… – pepoluan Jan 6 '14 at 14:20
  • @MohyedeenN I can't thank you enough, I wish I could +1 this 100x. After an entire day pulling my hair out, this was exactly what I needed. Thank you!! – Arthur Maltson Oct 10 '15 at 3:24
  • Also on the machine on the private network add: route add default gw #Or whatever the ip address of the NAT is You may also need to update the resolv.conf file to find the nameservers – Xofo Jan 5 '17 at 23:36

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

# 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  @ mansurali901@gmail.com

  # Defining interfaces for gateway.

# 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

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
  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.

None of these changes will be persisted upon reboot.

  • What would be your preferred way to persist ip_forward on reboot? – thomasrutter Oct 2 '20 at 8:41
  • 1
    @thomasrutter Edit or create a file in /etc/sysctl.d/, with contents net.ipv4.ip_forward=1. – multithr3at3d Oct 2 '20 at 22:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.