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 am installing a new centos 5.4 server and I would like to have a set of clean rules for mu iptables to startup.

What would be the good rules to start with?

Is this a good starting point :

# Allow outgoing traffic and disallow any passthroughs

iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

# Allow traffic already established to continue

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

# Allow ssh, ftp and web services

iptables -A INPUT -p tcp --dport ssh -i eth0 -j ACCEPT
iptables -A INPUT -p tcp --dport ftp -i eth0 -j ACCEPT
iptables -A INPUT -p udp --dport ftp -i eth0 -j ACCEPT
iptables -A INPUT -p tcp --dport ftp-data -i eth0 -j ACCEPT
iptables -A INPUT -p udp --dport ftp-data -i eth0 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -i eth0 -j ACCEPT

# Allow local loopback services

iptables -A INPUT -i lo -j ACCEPT

# Allow pings

iptables -I INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -I INPUT -p icmp --icmp-type source-quench -j ACCEPT
iptables -I INPUT -p icmp --icmp-type time-exceeded -j ACCEPT

For what is this rule :

iptables -A INPUT -p tcp --dport domain -i eth0 -j ACCEPT

UPDATE :

It will be a web server with FTP (required), apache, SSH, mysql.

share|improve this question
    
I use this simple rule .... Close everything and work backwards and open up what is needed. For a web server, port 80/443 are typically the only public facing services. Block everything else or limit access - for example limit ssh to specified IPs or private network. –  jeffatrackaid Dec 5 '11 at 20:17
add comment

4 Answers

up vote 11 down vote accepted

Your IPTables rules seem to be mostly appropriate for your server. But I would suggest a couple of possible changes:

  • Unless you need to allow SSH, MySQL, and FTP access from the entire Internet, it would be much more secure to use the '--source' option to restrict access on those ports from certain approved IP addresses, only. For instance, to only allow SSH access from the IP address 71.82.93.101, you'd change the 5th rule to 'iptables -A INPUT -p tcp --dport ssh --source 71.82.93.101 -i eth0 -j ACCEPT'. You'll probably need to add a separate rule for each individual IP address that you want to allow, see this question for more info on that: http://serverfault.com/questions/6989/iptables-multiple-source-ips.

  • Unless this machine is running a DNS server, you'll probably want to block access to the 'domain' (53) port. To do this, just remove the line 'iptables -A INPUT -p tcp --dport domain -i eth0 -j ACCEPT'. (This should also answer your final question, BTW.) If you are actually running a DNS server, though, leave this rule in place.

  • If you need to allow remote MySQL client access over the network, you'll need to add the line 'iptables -A INPUT -p tcp --dport 3306 -i eth0 -j ACCEPT' to open up external access to the standard MySQL port. But DON'T do this unless it's really necessary--if you only need local MySQL access (for a PHP app running under Apache, say), you don't need to provide remote MySQL access. And unless you want to risk getting hacked, if you do open port 3306 to the network, make sure that you require strong passwords for all of the MySQL user accounts, and that your MySQL server packages are up-to-date.

  • One of your comments ('Allow ssh, dns, ldap, ftp and web services') mentions LDAP services, but there is no such rule in your configuration. This happens to me a lot when I copy an example configuration and modify it. It won't affect the function, but I would fix the comment, since misleading comments can cause indirectly by confusing you or another admin in the future.

In my experience, it's hard to come up with a perfect set of IPTables rules, but I think you're definitely on the right track. Also, good luck with learning more about IPTables--these rules can seem complex at first, but it's a very helpful skill for any Linux sysadmin to have.

share|improve this answer
1  
Instead of allowing remote MySQL access through the firewall you can just make sure that everyone who needs access to the MySQL server has the right to make SSH port forwards. –  ptman Mar 3 '10 at 18:15
    
SSH port forwards are a potential alternative to opening the port and locking down the MySQL permissions. But unless he's dealing with sensitive data and/or he's a high-profile target (which would make the encryption features of SSH useful), I don't see the advantage. After all, SSH tunneling has its own disadvantages, including: setup/config hassles; increased CPU utilization, and limiting bandwidth (due to OpenSSH's static buffer size). And what if he doesn't want all of his remote MySQL clients to have local logins? –  Ryan B. Lynch Mar 3 '10 at 19:14
    
As far as comments not matching the rules goes, the ICMP rules allow traceroutes, PMTU discovery, and other useful messages but they don't allow pings (echo-request and echo-reply). –  Gerald Combs Mar 3 '10 at 20:53
    
Gerald, that's a good catch, I didn't even notice that. He should probably either change the comment to note that ping is NOT permitted, or he should add rules allowing ICMP echo request/reply traffic. –  Ryan B. Lynch Mar 8 '10 at 17:36
add comment

Definitely look to restrict your outbound traffic too.

I've seen plenty of cases where PHP exploits result in someone using 'curl' or 'wget' to fetch malicious code from elsewhere, then execute it on your server to join to a botnet.

If you do not expect Apache (as an example) to need to talk to other websites itself, restrict the traffic and save yourself a little pain down the line!

share|improve this answer
add comment

Why do you allow ftp and dns? Does your server provide those services? FTP shouldn't really be used, except for some very specific use cases, use SFTP instead (not FTPS). Also, why specify all the other ports by symbolic names and http by numeric 80? Did you just copy this from somewhere else? No copying and advise is going to make up for lack of understanding. Make sure you understand TCP, IP, firewalls, and the protocols of the services you are going to provide.

share|improve this answer
    
I don't mean to offend, ptman, but I think your answer could be seen as being somewhat discourteous and condescending. Also, you aren't really answering the question. If the asker lacks understanding, don't you think it would be better to speak respectfully, and to give him some specific education on the topic? –  Ryan B. Lynch Mar 3 '10 at 17:09
    
You are probably correct. My comments can sound negative, but weren't meant as such. I was trying to list questions that would trigger relevant thought processes. And since I don't know the base level of understand I didn't start writing a textbook. But you are absolutely correct about the unhelpful tone. Luckily you've written a much more helpful answer. –  ptman Mar 3 '10 at 18:14
add comment

These rules are ready to be imported via "iptables-restore":

*filter
:INPUT DROP [20:2036]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [93:16260]
-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT -m comment --comment "allow ICMP: echo-reply"
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT -m comment --comment "allow ICMP: echo-request"
-A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT -m comment --comment "allow ICMP: destination-unreachable"
-A INPUT -p icmp -m icmp --icmp-type 4 -j ACCEPT -m comment --comment "allow ICMP: source-quench"
-A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT  -m comment --comment "allow ICMP: time-exceeded"
-A INPUT -i lo -j ACCEPT -m comment --comment "allow input from the loop-back adapter"
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT -m comment --comment "allow SSH: ssh"
-A INPUT -i eth0 -p tcp -m tcp --dport 53 -j ACCEPT -m comment --comment "allow DNS: domain"
-A INPUT -i eth0 -p tcp -m udp --dport 53 -j ACCEPT -m comment --comment "allow DNS: domain"
-A INPUT -i eth0 -p tcp -m tcp --dport 21 -j ACCEPT -m comment --comment "allow FTP: ftp"
-A INPUT -i eth0 -p udp -m udp --dport 21 -j ACCEPT -m comment --comment "allow FTP: ftp"
-A INPUT -i eth0 -p tcp -m tcp --dport 20 -j ACCEPT -m comment --comment "allow FTP: ftp-data"
-A INPUT -i eth0 -p udp -m udp --dport 20 -j ACCEPT -m comment --comment "allow FTP: ftp-data"
-A INPUT -i eth0 -p tcp -m tcp --dport 3306 -j ACCEPT -m comment --comment "allow MariaDB/MySQL: mysql"
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT -m comment --comment "allow HTTP (apache/nxing/lighttpd)"
-A INPUT -i eth0 -p tcp -m tcp --dport 443 -j ACCEPT -m comment --comment "allow HTTPS (apache/nxing/lighttpd)"
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT  -m comment --comment "allow already established connections"
COMMIT

And just for the record...these default policies should be set too, IF the above iptables-restore is not used:

iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
share|improve this answer
    
I've edited your post -- StackOverflow is a question/answer format. Please read the FAQ: stackoverflow.com/faq –  tristan Jul 10 '13 at 10:39
    
This will introduce performance issues, since the stateful rule appears last here, and should appear first since it matches the vast majority of packets. –  Michael Hampton Jul 10 '13 at 19:13
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.