Linux – Trying to make iptables stateless is causing unforeseen filtering

firewalliptableslinuxtcp

I'm trying to improve the performance of my server by tuning iptables to not keep track of TCP connection's state. I'm looking at this guide: http://cotdp.com/2011/07/nginix-on-a-256mb-vm-slice-24000-tps/

However, if I do any of the following it seems like all outgoing connections are cut off:

remove this rule: INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
adding these:

iptables -t raw -I OUTPUT -j NOTRACK
iptables -t raw -I PREROUTING -j NOTRACK

Immediately after making either change makes it so "ping google.com" returns an error about not being able to find "google.com" (ie the DNS stops resolving).

Here are the rules that are loaded up on boot, but other rules are then added by fail2ban:

*filter
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -p tcp --dport ssh -j ACCEPT
-A INPUT -p tcp --dport http -j ACCEPT
-A INPUT -p tcp --dport https -j ACCEPT
-A INPUT -p tcp --dport smtp -j ACCEPT
-A INPUT -p tcp --dport ssmtp -j ACCEPT
-A INPUT -j REJECT
-A FORWARD -j REJECT
COMMIT

Here's the output of iptables –list:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
fail2ban-ssh  tcp  --  anywhere             anywhere            multiport dports ssh 
fail2ban-ssh-ddos  tcp  --  anywhere             anywhere            multiport dports ssh 
fail2ban-pam-generic  tcp  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
REJECT     all  --  anywhere             loopback/8          reject-with icmp-port-unreachable 
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED 
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:https 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:smtp 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssmtp 
REJECT     all  --  anywhere             anywhere            reject-with icmp-port-unreachable 

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
REJECT     all  --  anywhere             anywhere            reject-with icmp-port-unreachable 

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            

Chain fail2ban-pam-generic (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            

Chain fail2ban-ssh (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            

Chain fail2ban-ssh-ddos (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            

Best Answer

You have a rule which blocks all incoming traffic:

-A INPUT -j REJECT

And you stop connection tracking, so the rule to accept established connections' packets doesnt work anymore:

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

So your DNS packet goes out, is not tracked, and is then rejected by the first rule.

You need to enable tracking for the second rule to work, or add rules to allow incoming traffic from "good" sources.