# Having trouble with iptables, locking myself out

## Bloodsurfer

Hello, old friends.

At the moment I'm trying to install some basic firewall rules on my server. It's a Debian box. Up to now I have not been using any iptables rules there. I'm using the following script which is basically a combination of some hints from the Gentoo manual, an example from the Arch wiki and some ideas of my own. Every time I execute it, I'm locking myself out along with everything else. No HTTP connection will be possible anymore, no SSHing in. Existing ssh connection will be lost. I've stared at these rules for quite some time now and I can't figure out what's wrong with them...

```

#!/bin/bash

# TODO: log portscans to different logfile

# TODO: block and log also outgoing portscans

# service ports to be allowed

SERVICES_UDP="" # none yet

SERVICES_TCP="22 80" # ssh, http

# drop existing rules

iptables -F

iptables -X

echo "Basic chains..."

iptables -P OUTPUT ACCEPT # anything out

iptables -P INPUT DROP # nothing in

iptables -P FORWARD DROP # no forwarding

# chain OTHER_PACKETS: Security - defective packets, only limited ICMP

echo "Installing chain OTHER_PACKETS..."

iptables -N OTHER_PACKETS

iptables -A OTHER_PACKETS -p ALL -m state --state INVALID -j DROP # drop invalid/defective packets

iptables -A OTHER_PACKETS -p icmp -m limit --limit 1/s -j LOG --log-prefix "IPTABLES: Too many/fast ICMP packets: "

iptables -A OTHER_PACKETS -p icmp -m limit --limit 1/s -j ACCEPT # limit ICMP to max. 1 packet per second

iptables -A OTHER_PACKETS -p ALL -j RETURN

# chain SERVICE_SECURITY - SYN-flood, portscanner, ...

echo "Installing chain SERVICE_SECURITY..."

iptables -N SERVICE_SECURITY

iptables -A SERVICE_SECURITY -p tcp --syn -m limit --limit 2/s -j ACCEPT # against SYN-flood

iptables -A SERVICE_SECURITY -p tcp ! --syn -m state --state NEW -j DROP # drop TCP-SYN-packets without state NEW

iptables -A SERVICE_SECURITY -p tcp --tcp-flags ALL NONE -m limit --limit 1/h -j LOG --log-prefix "IPTABLES: Portscan attempt (all none) caught: "

iptables -A SERVICE_SECURITY -p tcp --tcp-flags ALL NONE -m limit --limit 1/h -j ACCEPT # portscan

iptables -A SERVICE_SECURITY -p tcp --tcp-flags ALL ALL -m limit --limit 1/h -j LOG --log-prefix "ITTABLES: Portscan attempt (all all) caught: "

iptables -A SERVICE_SECURITY -p tcp --tcp-flags ALL ALL -m limit --limit 1/h -j ACCEPT # portscan

iptables -A SERVICE_SECURITY -p ALL -j RETURN

# the DEVIL'S rejects - pun intended

echo "Installing chain DEVILS_REJECTS..."

iptables -N DEVILS_REJECTS

iptables -A DEVILS_REJECTS -p tcp -j REJECT --reject-with tcp-reset

iptables -A DEVILS_REJECTS -p udp -j REJECT --reject-with icmp-port-unreachable

iptables -A DEVILS_REJECTS -p icmp -j REJECT --reject-with icmp-host-unreachable

iptables -A DEVILS_REJECTS -j REJECT --reject-with icmp-proto-unreachable # everything else

iptables -A DEVILS_REJECTS -p ALL -j RETURN

# allow services

echo "Installing chain SERVICES..."

iptables -N SERVICES

for port in $SERVICES_TCP ; do

    echo "Making TCP port $port availabe..."

    iptables -A SERVICES -p tcp --dport $port -j SERVICE_SECURITY # use chain SERVICE_SECURITY for this allowed port

    iptables -A SERVICES -p tcp --dport $port -j ACCEPT # then accept everything that passes said chain

done

for port in $SERVICES_UDP ; do

    echo "Making UDP port $port available..."

    iptables -A SERVICES -p udp --dport $port -j SERVICE_SECURITY

    iptables -A SERVICES -p udp --dport $port -j ACCEPT

done

iptables -A SERVICES -p ALL -j RETURN

# INPUT

echo "Installing chain INPUT..."

iptables -A INPUT -p ALL -i lo -j ACCEPT # allow all traffic on the loopback interface

iptables -A INPUT -p ALL -m state --state ESTABLISHED,RELATED -j ACCEPT # allow all existing connections

iptables -A INPUT -p ALL -j OTHER_PACKETS 

iptables -A INPUT -p ALL -j SERVICES

iptables -A INPUT -p ALL -m limit --limit 10/s -j DEVILS_REJECTS

iptables -A INPUT -p ALL -j DROP

# OUTPUT

echo "Installing chain OUTPUT..."

iptables -A OUTPUT -p ALL -j ACCEPT # ausgehende Pakete erlauben

# save the rules

# TODO: of course only do that when the rules are working...

```

Can anybody help? And while we're at it, does anybody have an idea how to best prevent outgoing portscans?

Thanks in advance.

----------

## Hu

Adding rules via a series of invocations of iptables is a very popular, and very often wrong, solution.  Are you sure that every line in the script executes successfully?  Usually, you should use iptables-restore to apply the entire ruleset in one step.  Try changing every instance of DROP to ACCEPT, so that you can remain connected and use the hit counters to see which rules are being triggered.

----------

## Ant P.

There's an easier way to debug it - replace all DROP rules with log rules.

----------

## Bloodsurfer

Thank you very much, both of you.

Hu, you were right of course. The problem was this series of invocations. After changing that bash script into a ruleset file and invoking it via iptables-restore, I wasn't locked out anymore and the rules seemed to be working as expected. I guess the old bash script never got executed completely which broke at least some of the rules.

Ant P., your comment was also very helpful. Before applying my new ruleset for the first time I did exactly that and replaced DROPing by LOGing. After being sure everything worked as expected, I changed it back and made some additional changes and everything is still working.

Now I just need to DROP and LOG outgoing portscan attempts and I'm happy.

----------

