17

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)?

2

3 Answers 3

21

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

Note: these settings will be lost after reboot. Read how to persist iptables rules.

6
  • 5
    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
    Commented Jan 3, 2014 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
    Commented Jan 3, 2014 at 15:42
  • 4
    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
    Commented Jan 6, 2014 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!! Commented Oct 10, 2015 at 3:24
  • 3
    BTW, I downvoted this a while ago because steps 3-5 are not relevant, and could expose network services to the world unintentionally. Commented Mar 5, 2021 at 23:25
15

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.

19
  • What would be your preferred way to persist ip_forward on reboot? Commented Oct 2, 2020 at 8:41
  • 2
    @thomasrutter Edit or create a file in /etc/sysctl.d/, with contents net.ipv4.ip_forward=1. Commented Oct 2, 2020 at 22:25
  • YOU FORGOT THE MOST IMPORTANT PART. THESE SETTINGS WILL BE LOST AFTER REBOOT. Commented Mar 5, 2021 at 18:57
  • 2
    @SmitJohnth yes, please see the last sentence and the above comments. That part is fairly distribution-specific. Commented Mar 5, 2021 at 23:24
  • @multithr3at3d So this is not a ready manual, you still have to search. Who needs this if it's deleted after reboot? Commented Mar 6, 2021 at 19:04
0

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
1
  • Seeing this a little late... Note that there is no need to load any kernel modules manually, as they will be loaded automatically when using iptables. Additionally, loading extra modules (e.g. for FTP and IRC) is unnecessary and just adds extra attack surface, unless you require those specific capabilities. You also didn't add any DROP rules, so other machines on the WAN network can openly reach into your LAN if they add a static route. Lastly, the modifications to INPUT and OUTPUT don't have any effect since the default policy is ACCEPT. Commented Aug 24, 2023 at 16:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .