LX-SVS-INFO-iptables
Updated sep/27/10 13:03

iptables

nuttige links
inhoudstafel: snelkoppelingen
wikipedia - iptables:
http://en.wikipedia.org/wiki/Iptables

netfilter (home page van iptables)
http://www.netfilter.org/

linux home networking on iptables:
http://www.linuxhomenetworking.com
/wiki/index.php/Quick_HOWTO_:_Ch14_:_
Linux_Firewalls_Using_iptables

CentOS howto:
http://wiki.centos.org/HowTos/Network/IPTables

simple NAT on howtoforge:
http://www.howtoforge.com/nat_iptables

andreason's tutorial:
http://www.frozentux.net/iptables-tutorial/iptables-tutorial.html


iptables is een stateful packet-filter/-mangler, en bijgevolg een belangrijk (zoniet het belangrijkste) onderdeel van een firewall.

Stateful betekent dat van de pakketten wordt nagekeken of ze tot een reeds geopende of nieuwe sessie behoren.

Filteren betekent tegenhouden of doorlaten afhankelijk van bepaalde regels.

Mangling betekent het aanpassen van (IP/TCP/UDP) headers afhankelijk van weer andere regels.

De kernel doet het eigenlijke filteren en het commando iptables voegt regeltjes toe aan de firewall. Om iptables in te stellen als een echte pakketfilter, moet er ook een routerfunctie worden opengezet. dat doen we door een 'flag' in /proc/sys/net/ipv4/ip_forward op 1 te zetten.

De regeltjes voegen we toe met het commando iptables en zijn honderden opties.

Omdat we voor het toevoegen van regeltjes voortdurend gebruik moeten maken van het commando iptables, maken we bijna altijd scripts waarin alle regeltjes netjes onder mekaar staan. Deze scripts moeten we dan uitvoerbaar maken met chmod +x en meestal uitgevoerd worden vanuit de directory met de scripts voorafgegaan door het voorzetsel ./

Om te beginnen werken we als root gebruiker.
We maken dan een directory /etc/iptables aan, waarin we onze scripts zullen bewaren.
met vim kun je dan je eerste script aanmaken.

  1. clear-iptables: een script om IPTABLES leeg te maken

    Vooraleer we iptables kunnen gebruiken moeten we een script maken dat de firewall uitschakelt en alle tabellen leegmaakt. We zullen dit script vaak nodig hebben, tijdens het testen, en we kunnen het natuurlijk vooraan in elk ander script plaatsen, zodat deze andere scripts met een schone lei vertrekken.

    #! /bin/bash
    #
    #  turn iptables back into original state (no firewall, no forwarding)
    #
    #  bvdb  ( 29/5/2008 )
    #
    ################################################################

    # v = verbose, X = flush tables, F = delete non standard chains

    # general
    iptables -vX
    iptables -vF


    # nat and masquerading -t refers to table
    iptables -vt nat -F
    iptables -vt nat -X


    # mangling TCP header
    iptables -vt mangle -F
    iptables -vt mangle -X


    # reset policies -P refers to policies
    iptables -vP INPUT ACCEPT
    iptables -vP OUTPUT ACCEPT
    iptables -vP FORWARD ACCEPT


    # turn off routing
    echo 0 > /proc/sys/net/ipv4/ip_forward

  2. nat-iptables: een eenvoudige NAT-router

    Ons tweede script maakt van onze machine een echte NAT-router. Merk op dat ons eerste script volledig vervat is in het begin van dit nieuwe script. Tevens wordt de routerfunctie aangezet door de waarde "1" in /proc/sys/net/ipv4/ip_forward te plaatsen.

    Om router te worden hebben we natuurlijk 2 netwerkkaarten nodig.
    We hebben dan een onveilige verbinding naar buiten toe (in ons voorbeeld eth0 172.16.31.11/24) en een veilig LAN (in ons voorbeeld eth1 - 192.168.0.11)

    Het is essentieel dat je netwerk perfect geconfigureerd is vooraleer je kan beginnen aan het router of firewall gedeelte.

    Hetvolgende commando zet de vlag "routing" aan. De linux-pc gaat dan toelaten pakketten tussen verschillende fysieke netwerkkaarten of logische netwerken te routen.

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

    We hebben dan nog een commando nodig om Network Address Translation te doen:

    # iptables -vt nat -A POSTROUTING -o eth0 -j SNAT --to 172.16.31.11

    in de tabel NAT (-t nat) gaan we een regel toevoegen (-A) aan de POSTROUTING
    op output kaart eth0 (-o eth0) en na -j volgt wat we dan doen: SNAT = Source-network-adress-translation naar adres 172.16.31.11

    #! /bin/bash
    #
    #  ip masquerading with ip tables unprotected
    #
    #  bert vandenbroeck (29/5/2008)
    #
    #############################################

    # configure this machine as a router with ip4 forwarding
    #
    echo 1 > /proc/sys/net/ipv4/ip_forward

    ### Clear iptables
    ###

    # flush iptables and delete non standard chains
    #
    iptables -vF
    iptables -vX


    # flush nat-tables and non standard nat chains
    iptables -vt nat -F
    iptables -vt nat -X


    ## Mangle is used to modify the TCP Header. The chain's function is
    ## Modification of the TCP packet quality of service bits before routing
    ## occurs

    # flush mangle-tables and non standard mangle chains
    iptables -vt mangle -F
    iptables -vt mangle -X


    ### implement NAT routing
    ###

    ## the real thing: NAT routing - eth0 is on your outside and unprotected
    #  network, in our case the ip address is 172.16.31.11 (outside address)
    #
    iptables -vt nat -A POSTROUTING -o eth0 -j SNAT --to 172.16.31.11


    ### PRINT iptables configuration
    ###

    iptables -n -L
    iptables -t nat -L

    Uiteindelijk heb je met 1 commandoregel een volledige NAT-router opgebouwd.
    Pas OP!!! er is geen enkele beveiliging - alle policies zijn open zowel forward als naar de natrouter toe.

  3. in-nat-iptables: een eenvoudige NAT-router met servicefilter op de firewall

    Het commando

    # iptables -vP INPUT DROP

    zorgt ervoor dat geen enkel pakket bestemd voor de firewall/router zelf doorkomt. De optie -P staat voor policy. INPUT is alles wat toekomt met eindbestemming de machine waarop iptables draait, en DROP betekent letterlijk laten vallen.

    Het is echter nogal drastisch dit commando zonder meer uit te voeren. Want, ook localhost, op netwerkkaart lo, kan nu niet meer naar binnen (bij zichtzelf). We lossen dit op met:

    # iptables -vA INPUT -i lo -j ACCEPT

    We voegen toe (-A) aan de INPUT regels, dat op de input netwerkkaart lo (-i lo) alles wordt geaccepteerd (-j ACCEPT).
    Dit commando wordt logisch uitgevoerd na het vorige (DROP),
    en de volgorde is belangrijk:
    eerst alles dicht doen, en dan enkele uitzonderingen toelaten.

    Het zou echter interessant zijn ook nog de service ssh te kunnen benaderen op de firewall/router, van overal, om deze van op afstand te beheren. Daartoe voeren we het volgende commando uit:

    # iptables -vA INPUT -p TCP --dport 22 -j ACCEPT

    Aan de INPUT voegen we toe dat
    het protocol TCP op poort 22 (-p TCP --dport 22)
    wordt geaccepteerd (-j ACCEPT).

    Tot slot voegen we hetvolgende commando uit om open sessies open te laten:

    # iptables -vA INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    Dit geeft een volgende totaalscript:

    #! /bin/bash
    #
    #  ip masquerading with a protected router
    #
    #  bert vandenbroeck (29/5/2008)
    #
    #############################################

    # configure this machine as a router with ip4 forwarding
    #
    echo 1 > /proc/sys/net/ipv4/ip_forward

    ### Clear iptables
    ###

    # flush iptables and delete non standard chains
    #
    iptables -vF
    iptables -vX


    # flush nat-tables and non standard nat chains
    iptables -vt nat -F
    iptables -vt nat -X


    ## Mangle is used to modify the TCP Header. The chain's function is
    ## Modification of the TCP packet quality of service bits before routing
    ## occurs

    # flush mangle-tables and non standard mangle chains
    iptables -vt mangle -F
    iptables -vt mangle -X


    ### implement NAT routing
    ###

    ## the real thing: NAT routing - eth0 is on your outside and unprotected
    #  network, in our case the ip address is 172.16.31.11 (outside address)
    #
    iptables -vt nat -A POSTROUTING -o eth0 -j SNAT --to 172.16.31.11

    ### INPUT POLICIES: traffic to the
    ### firewall/router

    iptables -vP INPUT DROP
    iptables -vA INPUT -i lo -j ACCEPT
    iptables -vA INPUT -p TCP --dport 22 -j ACCEPT


    ### RELATED,ESTABLISHED
    ###

    iptables -vA INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    ### PRINT iptables configuration
    ###

    iptables -n -L
    iptables -t nat -L
    echo "routing set: " `cat /proc/sys/net/ipv4/ip_forward`


  4. proxy-iptables: een gesloten NAT-router met open proxyfilter op de firewall


    Het commando

    # iptables -vP FORWARD DROP

    zorgt ervoor dat alle verkeer doorheen de firewall/router wordt geblokkeerd (DROP). Dat is natuurlijk nogal drastisch, vooral nu we er eerst de moeite hebben gedaan er een NAT-ROUTER van te maken. De FORWARD chain controleert alle pakketten die de machine niet als eindbestemming hebben en er doorheen lopen.

    Als eerste maatregel kunnen we een squid-proxy op de firewall/router toegankelijk maken.
    Dit zit in de INPUT, want het is een lokale service. Daarvoor gebruiken we het commando:

    # iptables -vA INPUT -i eth1 -p TCP --dport 3128 -j ACCEPT

    eth1 is de netwerkkaart van het beveiligde private netwerk.

    We voegen toe (-A) aan de INPUT een regel die alle verkeer vanaf eth1 op tcp poort 3128 toelaat naar de firewall/router.

    Op de webbrowsers in ons privé netwerk moeten we nu nog de proxy configureren. Die proxy heeft het ipadres van eth1 en zit op poort 3128.

    Nu hebben we de volgende situatie:

    #! /bin/bash
    #
    #  ip masquerading with a protected router
    #
    #  bert vandenbroeck (29/5/2008)
    #
    #############################################

    # configure this machine as a router with ip4 forwarding
    #
    echo 1 > /proc/sys/net/ipv4/ip_forward

    ### Clear iptables
    ###

    # flush iptables and delete non standard chains
    #
    iptables -vF
    iptables -vX


    # flush nat-tables and non standard nat chains
    iptables -vt nat -F
    iptables -vt nat -X


    ## Mangle is used to modify the TCP Header. The chain's function is
    ## Modification of the TCP packet quality of service bits before routing
    ## occurs

    # flush mangle-tables and non standard mangle chains
    iptables -vt mangle -F
    iptables -vt mangle -X


    ### implement NAT routing
    ###

    ## the real thing: NAT routing - eth0 is on your outside and unprotected
    #  network, in our case the ip address is 172.16.31.11 (outside address)
    #
    iptables -vt nat -A POSTROUTING -o eth0 -j SNAT --to 172.16.31.11

    ### FORWARD Policies: traffic through the firewall/router
    ###
    iptables -vP FORWARD DROP

    ### INPUT POLICIES: traffic to the
    ### firewall/router
    iptables -vP INPUT DROP
    iptables -vA INPUT -i lo -j ACCEPT
    iptables -vA INPUT -p TCP --dport 22 -j ACCEPT
    iptables -vA INPUT -i eth1 -p TCP --dport 3128 -j ACCEPT


    ### RELATED,ESTABLISHED
    ###
    iptables -vA INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    ### PRINT iptables configuration
    ###
    iptables -n -L
    iptables -t nat -L
    echo "routing set: " `cat /proc/sys/net/ipv4/ip_forward`

  5. fw-iptables: een gefilterde NAT-router met enkele open services op zichzelf

    Na de introductie met clear-iptables om iptables te clearen, en nat-iptables om een nat-router in te stellen met iptables en nog enkele tussenscriptjes om policies in te stellen op INPUT en FORWARD, gaan we nu over tot een echte firewall:

    iptables source NAT with firewall

    We hebben nog een commando nodig om pakketten die doorheen de firewall lopen te filteren:

    # iptables -vA FORWARD -i eth1 -p UDP --dport 53 -j ACCEPT

    dit commando voegt toe (-A) aan de FORWARD chain en alleen op input kaart (-i) eth0 dat pakketten met als protocol (-p) UDP op poort 53 (-p UDP --dport 53) worden doorgelaten (-j ACCEPT). Dit is het protocol DNS.


    We gaan nu een firewall bouwen die toelaat te surfen, een DNS te bereiken, mailen naar SMTP en POP3 en tenslotte ook SSH-en naar buiten.

    Op de firewall zelf is alleen ssh toegelaten als service.


    #! /bin/bash
    #
    #  ip source NAT with iptables firewall
    #
    #  bert vandenbroeck (2/6/2008)
    #
    ########################################################
    #
    #   This iptables script Configures your linux box to a NAT firewall
    #
    #   The interior network (eth1) can only access the web through a squid
    #   proxy (3128) on the Firewall. Moreover, we protected the squid proxy
    #   also with the URL and DOMAIN filter Squidguard.
    #   The interior network is forwarded by NAT to DNS, POP3, SMTP and SSH
    #  
    on the internet.
    #   The interior network can also access the webserver and ssh service on
    #  
    this firewall.
    #  
    #   The exterior network (eth0) can only access the SSH service of this
    #   firewall. It is recommended to use strong encryption and to filter
    #   on incoming ip address.
    #
    ########################################################


    ### >>> configure this machine as a router with ip4 forwarding first
    #
    echo 1 > /proc/sys/net/ipv4/ip_forward

    ### ###################################
    ### Let's CLEAR the CONFIGURATION now

    ## flush iptables and delete non standard chains
    #
    iptables -vF
    iptables -vX


    ## flush nat-tables and non standard nat chains
    #
    iptables -vt nat -F
    iptables -vt nat -X


    ## flush mangle-tables and non standard mangle chains
    ## Mangle is used to modify the TCP Header
    #
    iptables -vt mangle -F
    iptables -vt mangle -X


    ### END CLEAR
    ### #########

    ### #####################################
    ### NOW the FORWARDING and ROUTING rules:
    ### who can be forwarded and to where

    ## DENY all ROUTING except ADDED rules
    #
    iptables -vP FORWARD DROP

    ## NAT routing (replace 172.16.31.11 with your own exterior IP address
    ## eth0 is the network card connected to the unsecure network)
    #
    iptables -vt nat -A POSTROUTING -o eth0 -j SNAT --to 172.16.31.11

    ## ALLOW NAT ROUTING FROM WITHIN for DNS, MAIL and SSH
    #
    # allow forward of DNS queries and replies
    iptables -vA FORWARD -i eth1 -p UDP --dport 53 -j ACCEPT
    # allow forward of SMTP and POP3 mail communication
    iptables -vA FORWARD -i eth1 -p TCP --dport 25 -j ACCEPT
    iptables -vA FORWARD -i eth1 -p TCP --dport 110 -j ACCEPT
    # allow forward of HTTP and HTTPS mail communication
    iptables -vA FORWARD -i eth1 -p TCP --dport 80 -j ACCEPT
    iptables -vA FORWARD -i eth1 -p TCP --dport 443 -j ACCEPT
    # allow forward of ssh
    iptables -vA FORWARD -i eth1 -p TCP --dport 22 -j ACCEPT
    # without the following the requested
    # internet hosts cannot reply any request
    iptables -vA FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

    ### END FORWARDING AND NAT
    ### ######################

    ### ########################################################
    ### WHICH SERVICES on THIS SERVER are ACCESSIBLE AND BY WHOM

    ## DROP ACCESS TO THIS SERVER
    #
    iptables -vP INPUT DROP

    ## allow access to this server to SSH from inside and outside
    #
    # ssh service is accessible from everywhere
    iptables -vA INPUT -p TCP --dport 22 -j ACCEPT

    ## allow localhost access to local services
    #
    iptables -vA INPUT -i lo -j ACCEPT
    #

    # keep established and related sessions open
    iptables -vA INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    ### END LOCAL SERVICES
    ### ##################

    ### PRINT iptables
    #
    iptables -L
    iptables -t nat -L



    **********************************************************************
    output of script:
    **********************************************************************
    # ./fw-iptables
    Flushing chain `INPUT'
    Flushing chain `FORWARD'
    Flushing chain `OUTPUT'
    Flushing chain `PREROUTING'
    Flushing chain `POSTROUTING'
    Flushing chain `OUTPUT'
    Flushing chain `PREROUTING'
    Flushing chain `INPUT'
    Flushing chain `FORWARD'
    Flushing chain `OUTPUT'
    Flushing chain `POSTROUTING'
    SNAT  0 opt -- in * out eth0  0.0.0.0/0  -> 0.0.0.0/0  to:172.16.31.11
    ACCEPT  udp opt -- in eth2 out *  0.0.0.0/0  -> 0.0.0.0/0  udp dpt:53
    ACCEPT  tcp opt -- in eth2 out *  0.0.0.0/0  -> 0.0.0.0/0  tcp dpt:25
    ACCEPT  tcp opt -- in eth2 out *  0.0.0.0/0  -> 0.0.0.0/0  tcp dpt:110
    ACCEPT  tcp opt -- in eth2 out *  0.0.0.0/0  -> 0.0.0.0/0  tcp dpt:22
    ACCEPT  0 opt -- in * out *  0.0.0.0/0  -> 0.0.0.0/0  state RELATED,ESTABLISHED
    ACCEPT  tcp opt -- in eth2 out *  0.0.0.0/0  -> 0.0.0.0/0  tcp dpt:80
    ACCEPT  tcp opt -- in eth2 out *  0.0.0.0/0  -> 0.0.0.0/0  tcp dpt:3128
    ACCEPT  tcp opt -- in * out *  0.0.0.0/0  -> 0.0.0.0/0  tcp dpt:22
    ACCEPT  0 opt -- in * out *  0.0.0.0/0  -> 0.0.0.0/0  state RELATED,ESTABLISHED
    ACCEPT  0 opt -- in lo out *  0.0.0.0/0  -> 0.0.0.0/0
    Chain INPUT (policy DROP)
    target     prot opt source               destination
    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
    ACCEPT     0    --  anywhere             anywhere            state RELATED,ESTABLISHED

    Chain FORWARD (policy DROP)
    target     prot opt source               destination
    ACCEPT     udp  --  anywhere             anywhere            udp dpt:domain
    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:smtp
    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:pop3
    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:http
    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:https
    ACCEPT     0    --  anywhere             anywhere            state RELATED,ESTABLISHED


    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    Chain PREROUTING (policy ACCEPT)
    target     prot opt source               destination

    Chain POSTROUTING (policy ACCEPT)
    target     prot opt source               destination
    SNAT       0    --  anywhere             anywhere            to:172.16.31.11

    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
  6. reverse masquerading

    Reverse masquerading betekent het doorgeven van services op een computer in het interne netwerk, naar het buitennetwerk toe. Dit is dus een soort van reverse NAT. Men noemt dit ook Destination NAT.

    In het vorige experiment hebben we gebruik gemaakt van een client PC om IPtables te testen. Nu gaan we op die PC ook een webserver plaatsen, en die webserver bruikbaar maken vanaf het externe netwerk.

    Daar zijn in principe maar twee extra regels voor nodig. Hier is de eerste (alles op één regel, \ weglaten):

    #
    iptables -vt nat -A PREROUTING -i eth0 -p tcp --dport 80 \
      -j DNAT --to 10.0.1.3:80


    De pakketten die binnenkomen vanaf het buitennetwerk op TCP poort 80, worden doorverwezen naar ipadres 10.0.1.3 op poort 80.

    We moeten die pakketten dan natuurlijk ook toelaten met een ACCEPT statement:

    # iptables -vA FORWARD -i eth0 -p TCP --dport 80 -j ACCEPT

    We moeten nu nog testen vanaf het externe netwerk of onze interne webserver beschikbaar is via het ipadres van de router/firewall

    Onze configuratie wordt dan:

    #! /bin/bash
    #
    #  ip source/destination NAT with iptables firewall
    #
    #   The interior network (eth1)
    #   The exterior network (eth0)
    #
    ########################################################

    ### >>> configure this machine as a router with ip4 forwarding first
    #
    echo 1 > /proc/sys/net/ipv4/ip_forward

    ### ###################################
    ### Let's CLEAR the CONFIGURATION now

    ## flush iptables and delete non standard chains
    #
    iptables -vF
    iptables -vX


    ## flush nat-tables and non standard nat chains
    #
    iptables -vt nat -F
    iptables -vt nat -X


    ## flush mangle-tables and non standard mangle chains
    ## Mangle is used to modify the TCP Header
    #
    iptables -vt mangle -F
    iptables -vt mangle -X


    ### END CLEAR

    ### NOW the FORWARDING and ROUTING rules:
    ### who can be forwarded and to where

    ## DENY all ROUTING except ADDED rules
    #
    iptables -vP FORWARD DROP

    ## NAT routing (replace 172.16.31.11 with your own exterior IP address
    ## eth0 is the network card connected to the unsecure network)
    ## source nat is done towards an output network card
    #
    iptables -vt nat -A POSTROUTING -o eth0 -j SNAT --to 172.16.31.11

    ## ALLOW NAT ROUTING FROM WITHIN for DNS, MAIL and SSH
    #
    iptables -vA FORWARD -i eth1 -p UDP --dport 53 -j ACCEPT
    iptables -vA FORWARD -i eth1 -p TCP --dport 25 -j ACCEPT
    iptables -vA FORWARD -i eth1 -p TCP --dport 110 -j ACCEPT
    iptables -vA FORWARD -i eth1 -p TCP --dport 22 -j ACCEPT
    iptables -vA FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT


    ## DNAT routing (replace 192.168.0.7 with your own exterior IP address
    ## eth0 is the network card connected to the unsecure network)
    #
    # destination nat is done from an input network card
    #
    iptables -vt nat -A PREROUTING -i eth0 -p TCP --dport 80 -j DNAT --to 192.168.0.7:80
    iptables -vA FORWARD -i eth0 -p TCP --dport 80 -j ACCEPT

    ### WHICH SERVICES on THIS SERVER are ACCESSIBLE AND BY WHOM

    ## DROP ACCESS TO THIS SERVER
    #
    iptables -vP INPUT DROP

    iptables -vA INPUT -i eth1 -p TCP --dport 80 -j ACCEPT
    iptables -vA INPUT -i eth1 -p TCP --dport 3128 -j ACCEPT
    iptables -vA INPUT -p TCP --dport 22 -j ACCEPT


    ## allow localhost access to local services
    iptables -vA INPUT -i lo -j ACCEPT
    iptables -vA INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


    ### END LOCAL SERVICES
    ### ##################

    ### PRINT iptables
    #
    iptables -L
    iptables -t nat -L
    echo "routing set: " `cat /proc/sys/net/ipv4/ip_forward`