Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm running the following bash script as root to configure iptables (I'm logged in via SSH):

#!/bin/bash

# Delete all existing rules
iptables --flush

# Set default chain policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

# Allow port 80 (http)
iptables -A INPUT -p tcp --sport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT

# Allow port 443 (https)
iptables -A INPUT -p tcp --sport 443 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT

# Allow port 8443
iptables -A INPUT -p tcp --sport 8443 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 8443 -j ACCEPT

# Allow port 22 (ssh)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p udp --sport 22 -j ACCEPT

# Allow port 25 (smtp)
iptables -A INPUT -p tcp --sport 25 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 25 -j ACCEPT

# Allow port 110 (pop)
iptables -A INPUT -p tcp --sport 110 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 110 -j ACCEPT

# Allow port 995
iptables -A INPUT -p tcp --sport 995 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 995 -j ACCEPT

# Allow port 143 (imap)
iptables -A INPUT -p tcp --sport 143 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 143 -j ACCEPT

# Allow port 993
iptables -A INPUT -p tcp --sport 993 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 993 -j ACCEPT

# Allow port 465 (smtp)
iptables -A INPUT -p tcp --sport 465 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 465 -j ACCEPT

# Allow port 8447
iptables -A INPUT -p tcp --sport 8447 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 8447 -j ACCEPT

# Ping rate limit (from outside)
iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j REJECT
iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j REJECT
iptables -A INPUT -p icmp -m icmp -m limit --limit 1/second -j ACCEPT

# Prevent DoS attack
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT

# Loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# User feedback
service iptables save
echo "Rules set, restarting iptables..."
service iptables restart
echo "Finished configuring iptables"

The script executes and kicks me out of SSH immediately - all ports are closed as well (80, 443, 21, etc). If I change the default chain policies to:

# Set default chain policies
iptables -P INPUT REJECT
iptables -P FORWARD REJECT
iptables -P OUTPUT REJECT

It works fine and I can get in via port 80 and SSH (22). HOWEVER, running iptables --list shows the following:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:http
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:https
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:pcsync-https
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:smtp
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:pop3
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:pop3s
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:imap
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:imaps
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:urd
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:8447
REJECT     icmp --  anywhere             anywhere            icmp address-mask-request reject-with icmp-port-unreachable
REJECT     icmp --  anywhere             anywhere            icmp timestamp-request reject-with icmp-port-unreachable
ACCEPT     icmp --  anywhere             anywhere            icmp any limit: avg 1/sec burst 5
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:http limit: avg 25/min burst 100
ACCEPT     all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:https
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:pcsync-https
ACCEPT     udp  --  anywhere             anywhere            udp spt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:smtp
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:pop3
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:pop3s
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:imap
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:imaps
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:urd
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:8447
ACCEPT     all  --  anywhere             anywhere

... all the default policies are set to ACCEPT. Can anyone tell me why this is happening? Thanks for taking a look.

share|improve this question
add comment

3 Answers

up vote 11 down vote accepted

You have many, many errors in your rules. From getting sport/dport wrong to specifying udp instead of TCP. You're also forgetting DNS. The service iptables restart is also unnecessary.

Forget about all the output rules, just have a rule that allows all outgoing traffic on established connections at the top of both INPUT and OUTPUT.

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 

Then only add rules to INPUT, and use dport in those, not sport.

And add an output rule for dns to make mail and ssh work again. Again, use dport.

The ping ratelimits are useless. They don't prevent a DOS/DDOS at all: the packets still arrive at your server. So don't bother with those. And IMHO http rate limits should be handled in the application, not the firewall, but that's more opinion than fact.

share|improve this answer
    
Thank you Dennis, very helpful. I based my script largely on the CentOS 4 & 5 documentation for IPTables, but its clearly outdated. –  Jongosi Jan 28 '13 at 2:28
add comment

Another flaw in your rules is that ICMP too big errors are not excepted.

share|improve this answer
add comment

Amongst other things this line

iptables -A OUTPUT -p udp --sport 22 -j ACCEPT

is your problem. You're only allowing UDP packets out on port 22. It should be

iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.