Linux – CentOS 6 – iptables preventing web access via port 80

apache-http-servercentosiptableslinux

I'm setting up a new web server with CentOS 6.2 and am not able to connect via the web. Everything looks set up correctly in httpd.conf and Apache is running, so I'm assuming it's an iptables issue.

Is there anything in the following which could be causing the issue?

EDIT: If i stop iptables, I can connect fine, so must be something needing tweaked in the below. I've already run iptables -A INPUT -p tcp --dport 80 -j ACCEPT and saved and restarted iptables but made no difference

# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:http

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

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Following advice in answer below:

[root@staging ~]# iptables -N TCP
[root@staging ~]# iptables -A TCP -p tcp --dport 80 -j ACCEPT
[root@staging ~]# iptables-save > /etc/iptables/iptables.rules
-bash: /etc/iptables/iptables.rules: No such file or directory
[root@staging ~]# iptables-save
# Generated by iptables-save v1.4.7 on Thu Nov  8 14:09:09 2012
*filter
:INPUT ACCEPT [91:7480]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [70:6556]
:TCP - [0:0]
-A TCP -p tcp -m tcp --dport 80 -j ACCEPT
COMMIT
# Completed on Thu Nov  8 14:09:09 2012
[root@staging ~]# iptables-restore
^C
[root@staging ~]# service iptables start
iptables: Applying firewall rules:                         [  OK  ]

Further edit: iptables-save showed nothing as I ran it after I'd stopped iptables! So here's the output:

# iptables-save
# Generated by iptables-save v1.4.7 on Thu Nov  8 14:39:10 2012
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [28:3344]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Thu Nov  8 14:39:10 2012

Best Answer

The iptables-save output shows this bit of additional information for rule 3 not shown with iptables -L:

From iptables -L output one would think that all traffic is accepted:

ACCEPT     all  --  anywhere             anywhere

but iptables-save shows:

-A INPUT -i lo -j ACCEPT

which means that iptables indeed accepts all traffic... but only from the loopback interface (lo).

And that's the reason HTTP traffic never reaches your web server: The only traffic permitted is established connections in rule 1, ICMP (for example ping) in rule 2: -A INPUT -p icmp -j ACCEPT and SSH in rule 4: -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT.

Then everything is rejected in rule 5: -A INPUT -j REJECT --reject-with icmp-host-prohibited.

That is, all HTTP traffic is rejected before even reaching rule 6: -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

To correct it delete rule 6 (-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT):

iptables -D INPUT 6

and insert it (option -I) as rule 5:

iptables -I INPUT 5 -p tcp -m tcp --dport 80 -j ACCEPT

or import this:

# Generated by iptables-save v1.4.6 on Thu Nov  8 16:46:28 2012
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [40:5423]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Thu Nov  8 16:46:28 2012

by saving it into a file and executing iptables-restore < file.

EDIT: The OP noticed that the new rules are lost after restarting iptables.

As explained here: http://wiki.centos.org/HowTos/Network/IPTables, any time we update the rules we need to save them, so run this:

# /sbin/service iptables save

to make changes permanent. Now the modified rules will be loaded by iptables.

Related Question