coding, hacking, startups, computer security, technology and more
HOWTO Secure Your Linux Box With IPTABLES
Okay, so this post will be brief but to the point. Today
I needed to lock down a machine I administer so the only inbound connections
which were allowed were SSH connections from trusted hosts.
I'm using Debian so this will obviously work for other Debian based distros such as Ubuntu, Linux Mint etc.
Assuming you're running a current version of Debian or a derivative then iptables will already be present on your system. One of the first things to
take note is that iptables won't hold its ruleset during a reboot so to start off this tutorial the first thing I ensured was
that the ruleset will be restored when the machine is rebooted. So, as root I edited /etc/rc.local and before the exit line i added /etc/iptables-init. Because this was a fresh install my rc.local ended up looking like this:
/etc/rc.local from Debian 6
12345678910111213141516
#!/bin/sh -e## rc.local## This script is executed at the end of each multiuser runlevel.# Make sure that the script will "exit 0" on success or any other# value on error.## In order to enable or disable this script just change the execution# bits.## By default this script does nothing.# Setup iptables/etc/iptables-init
exit 0
Next, I created the script which we've setup to be executed from rc.local:
#!/bin/sh# ----------------------------------------------------------------------# simple but secure iptables initialization script# DateCreated: Thu 12 Jan 2012 00:37:04 GMT# Author: Jerry Walsh# ----------------------------------------------------------------------# Put your trusted hosts/ranges here:TRUSTED_HOSTS="1.2.3.4 8.8.8.8/24 \ 4.3.2.1 1.2.2.2 3.3.3.4 "# flush rulesiptables -F
# Log dropped connections#iptables -N LOGDROP# allow localhost connections to the loopback interface iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT
# allow connections which are already establishediptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# allow all outbound connectionsiptables -A OUTPUT -j ACCEPT
# allow tcp to port 22 (ssh daemon) from trusted hostsfor GOODIE in $TRUSTED_HOSTS; doiptables -A INPUT -p tcp -m state --state NEW -s $GOODIE --dport 22 -j ACCEPT
done# or you could just allow ssh access from all hosts# NOTE: if you're going to allow ssh access from all hosts then# it's always a good idea to put sshd on a non-standard port# - this keeps the majority of script kid trawlers out#iptables -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT#other optional extras:# allow inbound http access#iptables -A INPUT -p tcp -m state --state NEW --dport 80 -j ACCEPT# allow inbound https access#iptables -A INPUT -p tcp -m state --state NEW --dport 443 -j ACCEPT# drop all other inbound traffic (including ICMP, UDP etc.)iptables -A INPUT -j DROP
# you could also just block tcp connections..#iptables -A INPUT -p tcp -j DROP
Finally, I set the script executable and executed the script now to load the new rules in to iptables:
finally, we mark the script executable and run it!
12
chmod 0700 /etc/iptables-init
!$
And that's it! Remember - it's always good to
test your configuration from a remote host or
better still from a 'bad' remote host and a
'good' (whitelisted) host.
REMEMBER: The above script is just an example!
You should modify the script to meet YOUR needs
(as it stands this met mine) but it still serves
as a useful starting point. It should also be
noted that ICMP ping replies will be blocked
using the above setup - this may not be
desirable but in my case it was!