-1

Here's my iptables script:

#!/bin/sh
service iptables stop
iptables -F
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p udp --sport 53 --dport 1024:65535 -j ACCEPT
service iptables save
service iptables restart

It works fine on Centos 6.3, but on Centos 6.0 I can't establish outbound HTTP connections. (I probably can't establish any outbound TCP/IP connections.) DNS lookup, however, works just fine, as does apparently anything else based on UDP.

I'm guessing this has something to do with TCP's three-way handshake, of which I know almost nothing. That being the case, there must be a difference in the versions of one of the modules where the earlier version requires explicit specification of INPUT rules to allow the handshake. So, what rule(s) would I need to create to allow the TCP handshake and therefore receive data?

3
  • If you set the policy in OUTPUT to ACCEPT, everything should go unless explicitly filtered, what you aren't doing. The last line is completely redundant. And unless you let inbound traffic for ESTABLISHED conections through, no answer will ever come back. You allow inbound connections only to the ports for services, not to the random ports used by clients to connect to the outside.
    – vonbrand
    Feb 27, 2013 at 12:50
  • Ah yes, I forgot to remove that last rule when posting the question. I added it out of desperation and before I knew about the TCP handshake.
    – Steve
    Feb 27, 2013 at 12:59
  • 1
    Will the down-voter please speak up?
    – Steve
    Feb 27, 2013 at 13:46

2 Answers 2

1

Your system will initiate connections from ephemeral ports.

Generally speaking, don't try and be smarter than netfilter's conntrack.

the first rule in any decent ruleset should be iptables -m conntrack --ctstate ESTABLISHED -j ACCEPT (only use -m state if your distro lacks -m conntrack) - doing this will enable your system initiate outbound connections and successfully receive the replies.

Additionally, to save resources, iptables -t raw -A PREROUTING -i lo -j CT --notrack (or -j NOTRACK) and iptables -t raw -A OUTPUT -o lo -j CT --notrack along with appropriate rules in the INPUT and OUTPUT chains to allow --ctstate UNTRACKED will save unnecessarily consuming conntrack resources on loopback connections.

3
  • This distro does indeed lack the conntrack module. I tried iptables -A -m state --state ESTABLISHED -j ACCEPT, but I still can't establish an outbound connection.
    – Steve
    Feb 27, 2013 at 13:31
  • paste your entire iptables-save
    – Olipro
    Feb 27, 2013 at 14:22
  • pastebin.com/WZ5d1LtH
    – Steve
    Feb 27, 2013 at 14:29
0

This works (see comments):

#!/bin/sh
service iptables stop
iptables -F

# Unlike the script in the question, incoming TCP packets are allowed in by default.
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

# Allow all loopback
iptables -A INPUT -i lo -j ACCEPT

# Allow incoming SSH, HTTP and HTTPS
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -m state --state NEW,ESTABLISHED -j ACCEPT

# Allow DNS responses
iptables -A INPUT -p udp --sport 53 --dport 1024:65535 -j ACCEPT

# This is new: Drop all incoming TCP packets with the SYN bit set.
iptables -A INPUT -p tcp --syn -m state --state NEW -j DROP

service iptables save
service iptables restart

I tested this quite thoroughly with netcat.

6
  • You shouldn't restrict the destinations of DNS responses. Also, DNS uses TCP when the query/response is too large (rarely happens, but Murphy will ensure it happens when most damaging). Also, dropping all TCP syn is an awkward way of saying "no TCP". And if so, why not also "no UDP"? Or even better just drop everyhing that hasn't been allowed (i.e., policy)?
    – vonbrand
    Feb 27, 2013 at 14:00
  • Why not use the firewall configuration tool that comes with your distribution, system-config-firewall?
    – vonbrand
    Feb 27, 2013 at 14:01
  • I appreciate the awkwardness of the rules, but at the moment it's the only answer here that works. I'd gladly accept a better one. Thanks for the tip regarding DNS over TCP. I'm trying to find out more about that now. If the TCP connection is established by the client (i.e. my server), then no change needs to be made to these rules. Also, the server I'm renting didn't come with system-config-firewall. This is the first I have heard of it anyway.
    – Steve
    Feb 27, 2013 at 14:16
  • Are you aware of an example domain that is guaranteed to make DNS use TCP?
    – Steve
    Feb 27, 2013 at 14:31
  • I'd believe that if you ask for all records for Google.com it will overflow UDP... nope, 435 bytes only (probably tailored so they fit).
    – vonbrand
    Feb 27, 2013 at 14:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .