Iptables - Forwarding + Masquerading

5,329

First off, a couple of corrections: The table names are case sensitive, as are the command line switches: you need --table filter -A INPUT. Also, the dport for https is 443 (probably a typo, but worth pointing out)

What you need to do next is to drop the INPUT rules at the bottom of your script. The INPUT chain is only used by packets which are bound for a local process on the server itself. So those rules will allow client on the LAN to connect directly to services listening on port 80+443 on the server. This is correct for your initial SSH and HTTP rules, but not for the packet forwarding. Use the FORWARD chain instead:

#http
iptables --table filter -A FORWARD -p tcp -dport 80 --in-interface eth1 -j ACCEPT
#https
iptables --table filter -A FORWARD -p tcp -dport 443 --in-interface eth1 -j ACCEPT

In addition to this, you'll need to enable IP forwarding in the kernel. Add this to the top of the script:

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

An additional recommendation: Rather than rules that drop packets at the end of the chains, consider using the policy settings:

iptables -t filter -P INPUT DROP
iptables -t filter -P OUTPUT DROP
iptables -t filter -P FORWARD DROP

For further reference, there's a good diagram of packet flow through netfilter, here: http://www.shorewall.net/NetfilterOverview.html

Share:
5,329

Related videos on Youtube

ankit
Author by

ankit

Updated on September 17, 2022

Comments

  • ankit
    ankit over 1 year

    I am new to iptables and trying to set my linux server as a gateway for my other computers.So naturally I am playing with iptables and needed some help

    My server has 2 NIC cards, eth0(WAN) and eth1(LAN)

    my goals are:

    1. For me to have ssh access to the linux server
    2. Forward all http(80) and https(443) traffic coming into eth1(LAN) to eth0 and do ip masquerading
    3. All other traffic coming into eth1(mainly DHCP requests from LAN clients) should not be forwarded to eth0
    4. Not allow the LAN clients to run any service ie. only have access to the web(tcp:80/443)

    The rules I have so far are:

    #To clear all IPTables Rules
    iptables --flush            
    iptables --table nat --flush
    iptables --delete-chain     
    iptables --table nat --delete-chain
    
    #allow me to ssh into the server + access the web server on it
    #ssh
    iptables --table FILTER -A INPUT -p tcp --dport 22 -j ACCEPT
    #webserver
    iptables --table FILTER -A INPUT -p tcp --dport 80 -j ACCEPT
    #drop everything else
    iptables --table FILTER -A INPUT -j DROP
    
    #enable IP Masquerading on eth0
    iptables --table NAT -A POSTROUTING --out-interface eth0 -j MASQUERADE
    
    #accept incoming traffic from eth1
    #http
    iptables --table FILTER -A INPUT -p tcp -dport 80 --in-interface eth1 -j ACCEPT
    #https
    iptables --table FILTER -A INPUT -p tcp -dport 443 --in-interface eth1 -j ACCEPT
    #drop everything else
    iptables --table FILTER -A INPUT --in-interface eth1 -j DROP
    

    So at this point I have the http/https traffic coming in from eth1(which was allowed to come in by iptables) and my eth0 line ready for masquerading.

    My question is How do i forward this traffic from eth1 to eth0 ?

    Any help would be much appreciated,
    ankit

  • ankit
    ankit about 13 years
    Thanks for pointing out the typos... corrected them. I think my basic understanding itself is not correct.In the link you mentioned, whats the "Routing Decision" box. How is that decision made? What I mean is how does it know that a particular packet needs to be sent to the FORWARD chain instead of the INPUT chain?
  • SmallClanger
    SmallClanger about 13 years
    Routing is a big topic, but specifically to your example: When the packet arrives on eth1, the routing part of the kernel looks at its destination address. If the address belongs to one of its own interfaces, then it sends it to the INPUT chain, as it's destined for a local process (such as the first rule for your ssh server).
  • SmallClanger
    SmallClanger about 13 years
    If it's destined for the wider internet, the kernel will send it on via the route it has for that address (likely the default route on your box) and the FORWARD chain decides whether it's allowed through. Chapter 4 of linux-ip.net/html for further reading.
  • ankit
    ankit about 13 years
    i opened up another thread for this since this was already getting cluttered and happy to say i was finally able to figure it out. Thank you for pointing me in the right direction. the solution can be found here