One of the interesting features of using CentOS was that IPTables are installed by default. IPTables is a host based statefull firewall which can be useful for securing a small number of simple servers. As the number of servers grows or the complexity of the rulebase increases, it would make sense to begin using a host based firewall solution which supports central management and logging.
IPTables rule files are stored under /etc/sysconfig and by default, it sends all logs as standard syslog to /var/log/messages. The /etc/sysconfig directory contains two files:
- iptables contains rules for IPv4 services
- ip6tables contains the rules for IPv6 services
IPtables are managed using a command line syntax to insert, append or delete lines into the respective files. The command syntax is discussed in a number of posts, so I won’t go into that here. The default rules allow everything out of the server and only lets ssh in. Since the command line is cumbersome, I chose to set up my initial rulebase by replacing the default file with the new file. Of course, until I was sure that the new rulebase worked, I kept a backup copy of the original rulebase just in case. Future changes can then be made through the command line.
For a standard web server, I used the following two base files. The configurations create a new chain called RH-Firewall-1-INPUT into which both the INPUT and FORWARD chains are redirected. This rulebase also logs all dropped packets to the default file /var/log/messages with the prefix “Firewall-log: “. This makes it easy to view dropped packets by grepping for “Firewall” when viewing the log file.
iptables:
*filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :RH-Firewall-1-INPUT - [0:0] -A INPUT -j RH-Firewall-1-INPUT -A FORWARD -j RH-Firewall-1-INPUT -A RH-Firewall-1-INPUT -i lo -j ACCEPT -A RH-Firewall-1-INPUT -p icmp --icmp-type echo-reply -j ACCEPT -A RH-Firewall-1-INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT -A RH-Firewall-1-INPUT -p icmp --icmp-type time-exceeded -j ACCEPT # Accept Pings -A RH-Firewall-1-INPUT -p icmp --icmp-type echo-request -j ACCEPT # Accept any established connections -A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Accept ssh traffic. Restrict this to known ips if possible. -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -m limit --limit 3/min --limit-burst 3 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT #Log and drop everything else -A RH-Firewall-1-INPUT -j LOG --log-prefix "Firewall-Log: " -A RH-Firewall-1-INPUT -j DROP COMMIT
ip6tables:
*filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :RH-Firewall-1-INPUT - [0:0] -A INPUT -j RH-Firewall-1-INPUT -A FORWARD -j RH-Firewall-1-INPUT -A RH-Firewall-1-INPUT -i lo -j ACCEPT -A RH-Firewall-1-INPUT -p ipv6-icmp -j ACCEPT # Accept any established connections -A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Accept ssh traffic. -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -m limit --limit 3/min --limit-burst 3 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT #Log and drop everything else -A RH-Firewall-1-INPUT -j LOG --log-prefix "Firewall-Log: " -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp6-adm-prohibited COMMIT
The following commands are useful for managing and monitoring IPTable activity:
Viewing the rules with their respective line numbers (in case you want to delete or insert lines) –
# iptables --line-numbers -n -L
Viewing the rules with number of hits and bytes per rule (to see if the rule is actually working) –
# iptables -L RH-Firewall-1-INPUT -v -n -x
Stopping, starting and restarting –
# service iptables start/stop/restart
After making changes with the command line, do not forget to save the changes with the command before restarting the service –
# service iptables save
Some interesting notes:
- PUTTY works with both IPv4 and IPv6 to ssh to a client.
- Stopping, starting and restarting iptables has no impact on established sessions. So if you are logged into a server via SSH, then you shouldn’t lose your session by restarting iptables. Just in case there is an issue or if you are worried that you might lock yourself out of the server, you can use a simple shell script to stop iptables if the connection is lost (see below).
#!/bin/bash # # Perform 6, 10 second loops to delay for one minute # Stop the script if everything goes as planned within # the 60 seconds. # x=0 y=60 echo "Start" while [ $x -lt $y ]; do echo $x x=$(($x + 10)) sleep 10s done service iptables stop echo "All Done"
- If at any time you edit the rules using the GUI, it will reset the entire file to the original default format removing all changes you made.