More IP Tables And International Troublemakers
I've been getting blasted by evildoers trying to send UBE from my system, too. Previously, I tapped a bit about how I cut down on the SSH attempts on my box (really people, root doesn't get SSH access by default), and I want to take a moment to report that it's worked!
The script I put in place to e-mail me the unwanted SSH access attempts has been empty for most days, and shows handfuls or dozens of attempts from single or few hosts if there are any at all. This is a great improvement over the hundreds of attempts from dozens or hundreds of hosts any given day.
Now I'm looking to focus on e-mail. I get a ton of UBE attempted through my system. I've secured it pretty well, so not much gets through, but there's still too many attempts.
I have decided to just stop inbound e-mail from those countries. This is a hard pill to swallow, because I'd like to think that somehow there's a fan, peer, or potential friend in one of those countries. The reality is, that I know so few people that live in foreign countries that there's really only random likelihood of this happening. So I've decided to cut them off from evil SSH attempts, and also from trying to send mail through my servers at the firewall.
I took a peek at my previous post (linked above), and noticed that I hit the high marks, but left plenty of room for me to forget what I did, and also to be unclear to others who've found this and want to implement it or something similar. Here's a bit more detail.
Small Assumption
First, an assumption is made that you've added a filter named UNWANTED to the iptables. Looking at (or editing) the /etc/iptables.up.rules (yours may be named differently), there should be a filter section that looks a little like this:
*filter
:FORWARD ACCEPT [0:0]
:INPUT DROP [0:0]
:OUTPUT ACCEPT [0:0]
:UNWANTED - [0:0]
-A INPUT -j UNWANTED
-A INPUT -s 127.0.0.1/32 -j ACCEPT
This tells the firewall that there's a filter named "UNWANTED," and that it will be checked first (because it's listed before other -A INPUT or other checks--in my example, accepting all localhost connections).
If this isn't in the firewall rules already, add it (probably easiest after running the following script), or the filter won't be executed and the work will be for naught.
A Script to Make the Rules
Here's a script to do almost everything at once.
#!/bin/bash
mkdir /tmp/iptables-work
cd /tmp/iptables-work
# Get the latest list
rm all-zones.tar.gz *.zone
wget http://www.ipdeny.com/ipblocks/data/countries/all-zones.tar.gz
tar xzf all-zones.tar.gz --wildcards *.zone
# Save the current configuration, but not UNWANTED filter entries
# Chop COMMIT from the end (we'll add another)
grep -v "\-A UNWANTED" /etc/iptables.up.rules | sed '$d' > iptables.up.rules
# Add the zones we don't want to the UNWANTED filter
cat af.zone cn.zone in.zone ru.zone tr.zone vn.zone ua.zone br.zone ve.zone kp.zone | while read iprange ; do echo "-A UNWANTED -p tcp -m tcp -m multiport -s ${iprange} -j REJECT --dports 22,25" >> iptables.up.rules; done
# Add the final COMMIT
echo COMMIT >> iptables.up.rules
The comments explain a little bit, but let's digest this for the uncertain or curious.
The mkdir and cd bit gives us a directory to work in, and makes that the working directory for the remainder of the script. The mkdir will fail if the directory already exists, but the script will continue. Change this if you need to; I chose /tmp so that the work would disappear if I wasn't careful and cleaned-up after myself.
The rm, wget and tar bit clean up from a previous run, grab the latest zone list from ipdeny.com, and unpack it so we can use the zone files inside. We could be more polite and extract only the few we'll be using, but for brevity we just extract 'em all.
The grep line grabs the current rules, minus the UNWANTED filter entries. The sed command on that line trims the last line (which should be a COMMIT), and saves the rule file to our current directory.
The cat line (long and wrapped, be careful) reads the desired .zone files and for each line in the file spits out the iptables rule to stop SSH (22) and SMTP (25) access. More ports can be added if necessary. Any port matched (not all port match simultaneously, obviously) in the list will result in a rejected connection.
Finally, we echo our COMMIT command to the end of our iptables.up.rules file.
This should result in a pretty long file. Double-check the beginning and add the UNWANTED filter bit, if it's not already there. Verify the COMMIT is at the end, and that the "-A UNWANTED" lines are correct (insomuch as you want to verify them).
Implement New Rules
All that's left to do is put it in place and start it up. I didn't make these part of the script because it's poor form to put "sudo" commands in a script (it suddenly asks for your password...), and we don't want to make the script run only as the super-user. So run the script above (or the commands in the script), and the using the generated (and certainly you've validated it, too) /tmp/iptables-work/iptables.up.rules, make it work:
sudo cp /tmp/iptables-work/iptables.up.rules /etc/iptables.up.rules
sudo iptables-restore < /etc/iptables.up.rules
The first command puts the file in place so that it will be used when the system boots. Note that the name of the file chosen here is because I'm running Ubuntu; the file for your system may be different!
The second command discards the currently loaded rules and reads the new rules from our new file.
More Detail
I've glossed over much of the iptables stuff; there are much better resources for understanding that than I can contribute. Here's a short list.
The "horse's mouth" as it were, the project home is http://www.netfilter.org/projects/iptables/index.html
A very detailed instructional is http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch14_:_Linux_Firewalls_Using_iptables