# Really need some help with iptables

## FizzyWidget

This is the last thing stoping me from moving my 3 systems to linux,even though i am behind an spi firewalled router, i am unsure of how to firewall my system using iptables , I have been doing a lot of reading and my main goal is to block everything in and out of my machine unless i allow it, so far i have come up with

```
#!/bin/bash

iptables -F

iptables -P INPUT DROP

iptables -P FORWARD DROP

iptables -P OUTPUT DROP

iptables -A INPUT -i eth0 -p tcp -m state --state ESTABLISHED -j ACCEPT

iptables -A OUTPUT -o eth0 -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -A INPUT -i eth0 -p udp -m state --state ESTABLISHED -j ACCEPT

iptables -A OUTPUT -o eth0 -p udp -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -A INPUT -i lo -j ACCEPT

iptables -A INPUT -s 192.168.1.0/24 -i eth0 -j ACCEPT

iptables -A INPUT -i eth0 -j DROP
```

I know it looks a bit thing, its not like i need to add ftp/web or mail servers to this as it's just my laptop, and i know ho wto add allowed ips and ports to it, im just wondering will do do what i require it to do? I am thinking of putting the laptop into the DMZ and letting a few sites test it to see what happens, nothing is on here atm, and i will be reinstall gentoo anyway and its a mess with all my testing   :Embarassed: 

----------

## Hu

I like putting simple rules first, such as interface-based or address-based rules.  Since every packet must traverse the chain until a decision is made, you want the typical case to make a decision with a minimum number of rules visited.  Rules based on state tracking are very useful, but require more processing.

The final rule is redundant, since any packets not otherwise matched will be handled by the policy.  That rule serves only to provide a counter of how many packets were dropped on eth0 versus how many packets were dropped from other interfaces.

I assume this is just your initial setup script.  Once you have the rules finalized, you should use the Gentoo initscript to manage loading your rules.  That will also make it easier to load your rules before the interface comes up.

----------

## Veldrin

I would add RELATED as additional state (this is required for ftp, and also simplifies any icmp messages - destination unreachable, et all)

you might need to allow lo output too iptables -A OUTPUT -o lo -j ACCEPT.

apart from that, your firewall looks pretty tight.

V.

If you like, I can post my current workstation config, which basically allows only local ping and ssh, and denies the rest. outbound (almost) anything is allowed.

----------

## FizzyWidget

if you could post examples or your own tables i would be grateful, my head is about to explode with all the linux reading i have done today, or if you could change mine above to how you think it should be? (yes im lazy  :Wink:  )

 *Hu wrote:*   

> 
> 
> I assume this is just your initial setup script.  Once you have the rules finalized, you should use the Gentoo initscript to manage loading your rules.  That will also make it easier to load your rules before the interface comes up.

 

For the laptop that should be all i need, for the server i will add them as and when i decide what i am going to have on there, and if they will be inet accessible, apache/php/mysql will be for internal test of sites and such, ftp may go inet side.

As to the loading of the rules i used

rc-update add iptables default

should this have been

rc-update add iptables boot ?

----------

## Veldrin

rc-update add iptables default sounds good. lo gets normally started in boot, while all other interfaces are started in default.

you might want to use /etc/init.d/iptables save to store the current config, which should be loaded at boot time. 

Be warned, I am using a 2 stage firewall. the first 2 snipplets below gets started by the iptables and ip6tables scripts. It is a stateful firewall allowing all (or most) outbound traffic, while dropping all inbound one (except for known connections). I am using conntrack opposed to state (that you use). IIRC has some more features, but for a host only firewall (i.e no forwarding) state should be enough.

The second stage is script called by networkmanager, and it opens some inbound connections to the host from the local network. basically it populated the ${IF}_in and ${IF}_out chains for each interface. 

I have currently interfaces defined: em0 (wired), iwn0 (wireless) and tun0 (openvpn tunnel)

I haven't verified it completely, but it works for me. I might be a little rough in some parts, especially the logging parts need some rework.

```

# Generated by iptables-save v1.4.12.1 on Sat Oct 29 00:11:38 2011

*raw

:PREROUTING ACCEPT [240:60475]

:OUTPUT ACCEPT [229:22569]

COMMIT

# Completed on Sat Oct 29 00:11:38 2011

# Generated by iptables-save v1.4.12.1 on Sat Oct 29 00:11:38 2011

*nat

:PREROUTING ACCEPT [0:0]

:INPUT ACCEPT [0:0]

:OUTPUT ACCEPT [3:202]

:POSTROUTING ACCEPT [3:202]

COMMIT

# Completed on Sat Oct 29 00:11:38 2011

# Generated by iptables-save v1.4.12.1 on Sat Oct 29 00:11:38 2011

*mangle

:PREROUTING ACCEPT [54:3822]

:INPUT ACCEPT [54:3822]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [53:3081]

:POSTROUTING ACCEPT [53:3081]

COMMIT

# Completed on Sat Oct 29 00:11:38 2011

# Generated by iptables-save v1.4.12.1 on Sat Oct 29 00:11:38 2011

*filter

:INPUT DROP [1:36]

:FORWARD DROP [0:0]

:OUTPUT DROP [0:0]

:em0_in - [0:0]

:em0_out - [0:0]

:iwn0_in - [0:0]

:iwn0_out - [0:0]

:tun0_in - [0:0]

:tun0_out - [0:0]

-A INPUT -i lo -j ACCEPT

-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

-A INPUT -m conntrack --ctstate INVALID -j LOG --log-prefix "invalid: " --log-level 6

-A INPUT -m conntrack --ctstate INVALID -j DROP

-A INPUT -i em0 -j em0_in

-A INPUT -i iwn0 -j iwn0_in

-A INPUT -i tun0 -j tun0_in

-A INPUT -m addrtype --dst-type ANYCAST -j DROP

-A INPUT -m addrtype --dst-type BROADCAST -j DROP

-A INPUT -m addrtype --dst-type MULTICAST -j DROP

-A INPUT -j LOG --log-prefix "cleanup: " --log-level 6

-A OUTPUT -o lo -j ACCEPT

-A OUTPUT -m conntrack --ctstate NEW,RELATED,ESTABLISHED -j ACCEPT

-A OUTPUT -m conntrack --ctstate INVALID -j LOG --log-prefix "invalid: " --log-level 6

-A OUTPUT -m conntrack --ctstate INVALID -j DROP

-A OUTPUT -o em0 -j em0_out

-A OUTPUT -o iwn0 -j iwn0_out

-A OUTPUT -o tun0 -j tun0_out

-A OUTPUT -j LOG --log-prefix "cleanup: " --log-level 6

-A em0_in -i em0 -j RETURN

-A em0_out -o em0 -j RETURN

-A iwn0_in -i iwn0 -j RETURN

-A iwn0_out -o iwn0 -j RETURN

-A tun0_in -i tun0 -j RETURN

-A tun0_out -o tun0 -j RETURN

COMMIT

# Completed on Sat Oct 29 00:11:38 2011
```

```
# Generated by ip6tables-save v1.4.12.1 on Sat Oct 29 00:11:40 2011

*raw

:PREROUTING ACCEPT [1:117]

:OUTPUT ACCEPT [0:0]

COMMIT

# Completed on Sat Oct 29 00:11:40 2011

# Generated by ip6tables-save v1.4.12.1 on Sat Oct 29 00:11:40 2011

*filter

:INPUT DROP [0:0]

:FORWARD DROP [0:0]

:OUTPUT DROP [0:0]

:em0_in - [0:0]

:em0_out - [0:0]

:iwn0_in - [0:0]

:iwn0_out - [0:0]

:tun0_in - [0:0]

:tun0_out - [0:0]

-A INPUT -i lo -j ACCEPT

-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

-A INPUT -m conntrack --ctstate INVALID -j LOG --log-prefix "invalid: " --log-level 6

-A INPUT -m conntrack --ctstate INVALID -j DROP

-A INPUT -i em0 -j em0_in

-A INPUT -i iwn0 -j iwn0_in

-A INPUT -i tun0 -j tun0_in

-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 134 -m limit --limit 2/sec --limit-burst 10 -j LOG --log-prefix "global: " --log-level 6

-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j ACCEPT

-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 136 -m limit --limit 2/sec --limit-burst 10 -j LOG --log-prefix "global: " --log-level 6

-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 136 -j ACCEPT

-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 135 -m limit --limit 2/sec --limit-burst 10 -j LOG --log-prefix "global: " --log-level 6

-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 135 -j ACCEPT

-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 4 -m limit --limit 2/sec --limit-burst 10 -j LOG --log-prefix "global: " --log-level 6

-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 4 -j ACCEPT

-A INPUT -j LOG --log-prefix "cleanup: " --log-level 6

-A OUTPUT -o lo -j ACCEPT

-A OUTPUT -m conntrack --ctstate NEW,RELATED,ESTABLISHED -j ACCEPT

-A OUTPUT -m conntrack --ctstate INVALID -j LOG --log-prefix "invalid: " --log-level 6

-A OUTPUT -m conntrack --ctstate INVALID -j DROP

-A OUTPUT -p ipv6-icmp -j ACCEPT

-A OUTPUT -o em0 -j em0_out

-A OUTPUT -o iwn0 -j iwn0_out

-A OUTPUT -o tun0 -j tun0_out

-A OUTPUT -j LOG --log-prefix "cleanup: " --log-level 6

-A em0_in -i em0 -j RETURN

-A em0_out -o em0 -j RETURN

-A iwn0_in -i iwn0 -j RETURN

-A iwn0_out -o iwn0 -j RETURN

-A tun0_in -i tun0 -j RETURN

-A tun0_out -o tun0 -j RETURN

COMMIT

# Completed on Sat Oct 29 00:11:40 2011

# Generated by ip6tables-save v1.4.12.1 on Sat Oct 29 00:11:40 2011

*mangle

:PREROUTING ACCEPT [0:0]

:INPUT ACCEPT [0:0]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [0:0]

:POSTROUTING ACCEPT [0:0]

COMMIT

# Completed on Sat Oct 29 00:11:40 2011
```

```
#!/bin/bash

#

# dynfw.lo

# dynamic firewall update script to interface lo.

#

# Nicolas Schlumberger <n.schlumberger@gmail.com>, (C) 2011

#

# This program is distributed under the GNU General Public License

# http://www.gnu.org/licenses/gpl.txt

#

## params

TRUSTED_TCP="ssh"

TRUSTED_UDP=""

TRUSTED_ICMP="echo-request"

TRUSTED_ICMPV6="echo-request"

#common programs (paths work for gentoo)

IP=/sbin/ip

ROUTE=/sbin/route

IPTABLES=/sbin/iptables

IP6TABLES=/sbin/ip6tables

PROGS="${IPTABLES} ${IP6TABLES}"

SCRIPTNAME=`basename $0`

IF=${SCRIPTNAME#*.}

unset SCRIPTNAME

STATE=${1:-up}

IN="${IF}_in"

OUT="${IF}_out"

CHAINS="${IN} ${OUT}"

VPN_NETS="10.23.8.0/21"

VPN6_NETS="fec0:1f77::/40"

# flush all interface chains

for PROG in ${PROGS};   do 

        for CHAIN in ${CHAINS}; do 

                ${PROG} -F ${CHAIN}

        done

done

if [[ $STATE == "up" || $STATE == "dhcp4-change" ]] ; then

        # get the attached nets, but exclude loopback...

        NETS=`${IP} addr show dev $IF| grep 'inet ' | grep -v 'host lo' | awk -F ' ' '{print $2}'`

        # ...and link-local ranges including eui64

        NETS6=`${IP} addr show dev $IF| grep 'inet6' | egrep -v '( fe[89ab]| ::1/128|ff:fe..:.*/64)' | awk -F ' ' '{print $2}'`

        # configure IPv4...

        for SRC in ${NETS}; do 

                for TCP in ${TRUSTED_TCP}; do

                        ${IPTABLES} -A ${IN} -s ${SRC} -i ${IF} -p tcp -m tcp --dport ${TCP} -m conntrack --ctstate NEW -j LOG -m limit --limit 3/second --limit-burst 10 --log-prefix "dynfw ${IN}: " --log-level 6

                        ${IPTABLES} -A ${IN} -s ${SRC} -i ${IF} -p tcp -m tcp --dport ${TCP} -m conntrack --ctstate NEW -j ACCEPT

                done

                for UDP in ${TRUSTED_UDP}; do

                        ${IPTABLES} -A ${IN} -s ${SRC} -i ${IF} -p udp -m udp --dport ${UDP} -m conntrack --ctstate NEW -j LOG -m limit --limit 3/second --limit-burst 10 --log-prefix "dynfw ${IN}: " --log-level 6

                        ${IPTABLES} -A ${IN} -s ${SRC} -i ${IF} -p udp -m udp --dport ${UDP} -m conntrack --ctstate NEW -j ACCEPT

                done

                for ICMP in ${TRUSTED_ICMP}; do

                        ${IPTABLES} -A ${IN} -s ${SRC} -i ${IF} -p icmp -m icmp --icmp-type ${ICMP} -j LOG -m limit --limit 3/second --limit-burst 10 --log-prefix "dynfw ${IN}: " --log-level 6

                        ${IPTABLES} -A ${IN} -s ${SRC} -i ${IF} -p icmp -m icmp --icmp-type ${ICMP} -j ACCEPT

                done

        done

        # ... and IPV6 filters

        for SRC6 in ${NETS6}; do

                for TCP in ${TRUSTED_TCP}; do

                        ${IP6TABLES} -A ${IN} -s ${SRC6} -i ${IF} -p tcp -m tcp --dport ${TCP} -m conntrack --ctstate NEW -j LOG -m limit --limit 3/second --limit-burst 10 --log-prefix "dynfw ${IN}: " --log-level 6

                        ${IP6TABLES} -A ${IN} -s ${SRC6} -i ${IF} -p tcp -m tcp --dport ${TCP} -m conntrack --ctstate NEW -j ACCEPT

                done

                for UDP in ${TRUSTED_UDP}; do

                        ${IP6TABLES} -A ${IN} -s ${SRC6} -i ${IF} -p udp -m udp --dport ${UDP} -m conntrack --ctstate NEW -j LOG -m limit --limit 3/second --limit-burst 10 --log-prefix "dynfw ${IN}: " --log-level 6

                        ${IP6TABLES} -A ${IN} -s ${SRC6} -i ${IF} -p udp -m udp --dport ${UDP} -m conntrack --ctstate NEW -j ACCEPT

                done

                for ICMP in ${TRUSTED_ICMPv6}; do

                        ${IP6TABLES} -A ${IN} -s ${SRC6} -i ${IF} -p icmpv6 -m icmpv6 --icmpv6-type ${ICMP} -j LOG -m limit --limit 3/second --limit-burst 10 --log-prefix "dynfw ${IN}: " --log-level 6

                        ${IP6TABLES} -A ${IN} -s ${SRC6} -i ${IF} -p icmpv6 -m icmpv6 --icmpv6-type ${ICMP} -j ACCEPT

                done

        done

fi

if [ $STATE == "vpn-up" ] ; then

        # configure IPv4...

        for SRC in ${VPN_NETS}; do 

                for TCP in ${TRUSTED_TCP}; do

                        ${IPTABLES} -A ${IN} -s ${SRC} -i ${IF} -p tcp -m tcp --dport ${TCP} -m conntrack --ctstate NEW -j LOG -m limit --limit 3/second --limit-burst 10 --log-prefix "dynfw ${IN}: " --log-level 6

                        ${IPTABLES} -A ${IN} -s ${SRC} -i ${IF} -p tcp -m tcp --dport ${TCP} -m conntrack --ctstate NEW -j ACCEPT

                done

                for UDP in ${TRUSTED_UDP}; do

                        ${IPTABLES} -A ${IN} -s ${SRC} -i ${IF} -p udp -m udp --dport ${UDP} -m conntrack --ctstate NEW -j LOG -m limit --limit 3/second --limit-burst 10 --log-prefix "dynfw ${IN}: " --log-level 6

                        ${IPTABLES} -A ${IN} -s ${SRC} -i ${IF} -p udp -m udp --dport ${UDP} -m conntrack --ctstate NEW -j ACCEPT

                done

                for ICMP in ${TRUSTED_ICMP}; do

                        ${IPTABLES} -A ${IN} -s ${SRC} -i ${IF} -p icmp -m icmp --icmp-type ${ICMP} -j LOG -m limit --limit 3/second --limit-burst 10 --log-prefix "dynfw ${IN}: " --log-level 6

                        ${IPTABLES} -A ${IN} -s ${SRC} -i ${IF} -p icmp -m icmp --icmp-type ${ICMP} -j ACCEPT

                done

        done

        # ... and IPV6 filters

        for SRC6 in ${VPN6_NETS}; do

                for TCP in ${TRUSTED_TCP}; do

                        ${IP6TABLES} -A ${IN} -s ${SRC6} -i ${IF} -p tcp -m tcp --dport ${TCP} -m conntrack --ctstate NEW -j LOG -m limit --limit 3/second --limit-burst 10 --log-prefix "dynfw ${IN}: " --log-level 6

                        ${IP6TABLES} -A ${IN} -s ${SRC6} -i ${IF} -p tcp -m tcp --dport ${TCP} -m conntrack --ctstate NEW -j ACCEPT

                done

                for UDP in ${TRUSTED_UDP}; do

                        ${IP6TABLES} -A ${IN} -s ${SRC6} -i ${IF} -p udp -m udp --dport ${UDP} -m conntrack --ctstate NEW -j LOG -m limit --limit 3/second --limit-burst 10 --log-prefix "dynfw ${IN}: " --log-level 6

                        ${IP6TABLES} -A ${IN} -s ${SRC6} -i ${IF} -p udp -m udp --dport ${UDP} -m conntrack --ctstate NEW -j ACCEPT

                done

                for ICMP in ${TRUSTED_ICMPv6}; do

                        ${IP6TABLES} -A ${IN} -s ${SRC6} -i ${IF} -p icmpv6 -m icmpv6 --icmpv6-type ${ICMP} -j LOG -m limit --limit 3/second --limit-burst 10 --log-prefix "dynfw ${IN}: " --log-level 6

                        ${IP6TABLES} -A ${IN} -s ${SRC6} -i ${IF} -p icmpv6 -m icmpv6 --icmpv6-type ${ICMP} -j ACCEPT

                done

        done

fi

# force interface chains to return to main chain

for PROG in ${PROGS};   do 

        for CHAIN in ${CHAINS}; do 

                ${PROG} -A ${CHAIN} -j RETURN

        done

done

```

----------

## FizzyWidget

^^^^^^^^

not something to look at when you have just woke up at 7:30am   :Embarassed: 

Thanks though, will look at it later after a few coffees  :Smile: 

I put my laptop into DMZ and ran a few on-line probes all said ports were filtered, grc was one nmap on-line was another, cant remember the others, at first it said it couldnt tell if the system was even up then i added -PN to the command

----------

## FizzyWidget

having had sometime to mess about with iptables and adding some rules for new wireless usb dongles, was wondering if people could check it over see if i have made any mistakes

previious ruleset

```
#!/bin/bash 

iptables -F 

iptables -P INPUT DROP 

iptables -P FORWARD DROP 

iptables -P OUTPUT DROP 

iptables -A INPUT -i eth0 -p tcp -m state --state ESTABLISHED -j ACCEPT 

iptables -A OUTPUT -o eth0 -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT 

iptables -A INPUT -i eth0 -p udp -m state --state ESTABLISHED -j ACCEPT 

iptables -A OUTPUT -o eth0 -p udp -m state --state NEW,ESTABLISHED -j ACCEPT 

iptables -A INPUT -i lo -j ACCEPT 

iptables -A INPUT -s 192.168.1.0/24 -i eth0 -j ACCEPT 

iptables -A INPUT -i eth0 -j DROP
```

new ruleset

```
#!/bin/bash 

iptables -F 

iptables -P INPUT DROP 

iptables -P FORWARD DROP 

iptables -P OUTPUT DROP

#

#Ethernet

iptables -A INPUT -i eth0 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT 

iptables -A OUTPUT -o eth0 -p tcp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT 

iptables -A INPUT -i eth0 -p udp -m state --state ESTABLISHED,RELATED -j ACCEPT 

iptables -A OUTPUT -o eth0 -p udp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

#

# Wireless inet 1

iptables -A INPUT -i wlan0 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT 

iptables -A OUTPUT -o wlan0 -p tcp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT 

iptables -A INPUT -i wlan0 -p udp -m state --state ESTABLISHED,RELATED -j ACCEPT 

iptables -A OUTPUT -o wlan0 -p udp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

#

# Wireless inet 2

iptables -A INPUT -i wlan1 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT 

iptables -A OUTPUT -o wlan1 -p tcp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT 

iptables -A INPUT -i wlan1 -p udp -m state --state ESTABLISHED,RELATED -j ACCEPT 

iptables -A OUTPUT -o wlan1 -p udp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

#

# Wireless inet 1

iptables -A INPUT -i wlan2 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT 

iptables -A OUTPUT -o wlan2 -p tcp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT 

iptables -A INPUT -i wlan2 -p udp -m state --state ESTABLISHED,RELATED -j ACCEPT 

iptables -A OUTPUT -o wlan2 -p udp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

#

iptables -A INPUT -i lo -j ACCEPT

iptables -A OUTPUT -o lo -j ACCEPT

iptables -A INPUT -s 192.168.1.0/24 -i eth0 -j ACCEPT 

iptables -A INPUT -s 192.168.1.0/24 -i wlan0 -j ACCEPT

iptables -A INPUT -s 192.168.1.0/24 -i wlan1 -j ACCEPT

iptables -A INPUT -s 192.168.1.0/24 -i wlan2 -j ACCEPT 

iptables -A INPUT -i eth0 -j DROP

iptables -A INPUT -i wlan0 -j DROP

iptables -A INPUT -i wlan1 -j DROP

iptables -A INPUT -i wlan2 -j DROP

```

----------

