Results 1 to 3 of 3

Thread: Iptables, powerful enough to block even you.

  1. #1

    Default Iptables, powerful enough to block even you.

    Iptables is the standard soft firewall built into Spry VPS's. It is flexible, powerful, and does a good job at being a firewall. It does have some pitfalls though.

    One of the most common issues I see is locking oneself out. It can be done as easily as running "iptables -P INPUT DROP" This would drop ALL incoming connections. Leaving only the exceptions already specified as an allowed connection. If you connect from home via DHCP, you could easily lose your current IP and be completely locked out.

    one of the most common ones I use to block out an IP address is

    iptables -A INPUT -s ###.###.###.### -j DROP

    This will block the ip address given in the ###.###.###.###

    Another one I use a lot of is "iptables -L" This will list out the rules that are currently set.

    If you want to make a change to the rules permanent. You will need to save them. See below for the list of options

    root@chico [/]# iptables --help
    iptables v1.2.8

    Usage: iptables -[AD] chain rule-specification [options]
    iptables -[RI] chain rulenum rule-specification [options]
    iptables -D chain rulenum [options]
    iptables -[LFZ] [chain] [options]
    iptables -[NX] chain
    iptables -E old-chain-name new-chain-name
    iptables -P chain target [options]
    iptables -h (print this help information)

    Either long or short options are allowed.
    --append -A chain Append to chain
    --delete -D chain Delete matching rule from chain
    --delete -D chain rulenum
    Delete rule rulenum (1 = first) from chain
    --insert -I chain [rulenum]
    Insert in chain as rulenum (default 1=first)
    --replace -R chain rulenum
    Replace rule rulenum (1 = first) in chain
    --list -L [chain] List the rules in a chain or all chains
    --flush -F [chain] Delete all rules in chain or all chains
    --zero -Z [chain] Zero counters in chain or all chains
    --new -N chain Create a new user-defined chain
    -X [chain] Delete a user-defined chain
    --policy -P chain target
    Change policy on chain to target
    -E old-chain new-chain
    Change chain name, (moving any references)
    --proto -p [!] proto protocol: by number or name, eg. `tcp'
    --source -s [!] address[/mask]
    source specification
    --destination -d [!] address[/mask]
    destination specification
    --in-interface -i [!] input name[+]
    network interface name ([+] for wildcard)
    --jump -j target
    target for rule (may load target extension)
    --match -m match
    extended match (may load extension)
    --numeric -n numeric output of addresses and ports
    --out-interface -o [!] output name[+]
    network interface name ([+] for wildcard)
    --table -t table table to manipulate (default: `filter')
    --verbose -v verbose mode
    --line-numbers print line numbers when listing
    --exact -x expand numbers (display exact values)
    [!] --fragment -f match second or further fragments only
    --modprobe=<command> try to insert modules using this command
    --set-counters PKTS BYTES set the counter during insert/append
    [!] --version -V print package version.

  2. #2
    Junior Member Newbie
    Join Date
    Oct 2007


    Would you recommend this approach with iptables for IP blocking, as opposed to utilizing .htaccess? It would appear to be less of an overhead for page loads, but hey, I could be wrong.


  3. #3
    Junior Member Newbie
    Join Date
    Mar 2008


    I like iptables very much for IP blocking!

    I use iptables as the key to my firewalling against a variety of threats. In fact, I can use it for anything that can be identified in a system log with a pattern match - and it works very well for me. I'm doing it on two Spry Webmin 400 Fedora 4 servers. It keeps traffic, bandwidth, resource use and log size very manageable.

    The other key item in this scenario is pop-before-smtp (, a very nice, small, perl application normally used to validate users to my smtp server after they successfully validate to the pop (or imap) server - i.e. in order to send mail, they need to succeed in logging in to collect it. It comes, out of the box, with a config file full of sample patterns to match nearly any mail server software (my favorite is postfix) and also another file showing how it can be used for blocking IPs instead. I adapted it for use on my Spry servers, so if you're not using Fedora Core 4 it may need some changes to adapt to your own versions of logging and iptables.

    Basically, I installed the pop-before-smtp daemon according to the instructions, then configure a config file and startup script for each application (e.g. ssh login attacks.) Sounds tough perhaps but it is really very simple! I call my first config file /etc/ and the uncommented lines are:

    use strict;
    use vars qw(
        $pat $out_pat $write $flock $debug $reprocess $grace $logto %file_tail
        @mynets %db $dbfile $dbvalue
        $mynet_func $tie_func $flock_func $add_func $del_func $sync_func
        $tail_init_func $tail_getline_func $log_func
        $PID_pat $IP_pat $OK_pat $FAIL_pat $OUT_pat $cmdformat
    $cmdformat = 'iptables %s INPUT -s %s -j REJECT';
    $dbfile = '/var/lib/ip-blocking';  #### PERSONALIZED! ####
    $flock = 0;
    # A 3-minute IP-blocking period before the IP address is expired.
    $grace = 3*60;
    $file_tail{'name'} = '/var/log/messages';  #### PERSONALIZED! ####
    # This is for catching login errors on SSHD only.  #### PERSONALIZED! ####
    $pat = '^(... .. ..:..:..).+Failed password.+from\s+(\d+\.\d+\.\d+\.\d+)';
    $mynet_func = \&mynet_ipblock;
    $add_func = \&add_ipblock;
    $del_func = \&del_ipblock;
    sub mynet_ipblock ## Don't block my own IP or one of my clients' ranges
        '';  #### PERSONALIZED! ####
    sub add_ipblock
        my($ip) = @_;
        $db{$ip} = $dbvalue;
        system(sprintf($cmdformat, '-A', $ip));
    sub del_ipblock
        my($ip) = @_;
        system(sprintf($cmdformat, '-D', $ip));
        delete $db{$ip};
    I marked the few lines that are unique for this instance. Note I have excluded (or whitelisted) a couple of addresses or ranges, and that I set the timeout to three minutes instead of the default 30. This is because result of passing pattern test is that the offending IP is rejected upon initial attempt to connect to the server in any way. As far as they can tell, the machine is offline or crashed. For robots, it is a great deterrent. For clients, three minutes is a minor but necessary inconvenience. For very persistent hackers, it will limit their number of guess attempts to a very few every three or four minutes. I went out looking for this system at a time when the guesses logged were hundreds per second! Life is better today!

    OK, the next (last) item in this system is the startup script. I'd like this to run every time the machine boots up, so I put it in the init.d folder: /etc/init.d/pop-before-ip-blocking and the uncommented lines are (though only the first five are personalized for this daemon)

    progname=pop-before-ip-blocking #### PERSONALIZED! ####
    conf=/etc/ 	#### PERSONALIZED! ####
    test -d /var/run && pid=/var/run/$
    if test -f $conf; then
    die(){ echo "$progname: $*">&2; exit 1; }
    case "$1" in
    	echo -n "Starting $progname: "
    	$pgm $conf $dbfile $watchlog $logto --daemon=$pid
    	if test $? -eq 0; then
    		echo done
    		echo failed
    	echo -n "Stopping $progname: "
    	p=`cat $pid 2>/dev/null`; test -n "$p" && (
    		kill $p || exit 0; sleep 1
    		kill -9 $p 2>/dev/null || exit 0; sleep 1
    		kill -0 $p && die "$pid won't die"
    	if test $? -eq 0; then
    		rm -f $pid
    		echo done
    		echo failed
    	$0 stop
    	$0 start
    	p=`cat $pid 2>/dev/null`
    	test -n "$p" || die "no pidfile for $pgm"
    	kill -0 $p || die "$pgm[$p] is no longer running"
    	ps -fp $p
    	die "Usage: `basename $0` {start|stop|restart|status}"
    That's it! Start it manually by giving the shell command
    /etc/init.d/pop-before-ip-blocking start
    or restart, or stop. Upon start, you are now protected from the common dictionary sshd attacks, as logged in /var/log/messages.

    Additional building blocks to my firewall follow (only the unique parts shown though):

    $dbfile = '/var/lib/ip-pop-blocking';
    $file_tail{'name'} = '/var/log/maillog';
    $pat = '^(... .. ..:..:..).+pop3d: LOGIN FAILED, user=.+\[.*(\d+\.\d+\.\d+\.\d+)\]';
    (Like I said, simple. Pop guessers are now banned for three minutes too.)

    $dbfile = '/var/lib/ip-blocking-secure';
    $file_tail{'name'} = '/var/log/secure';
    $pat = '^(... .. ..:..:..).+Invalid user.+from\s+(\d+\.\d+\.\d+\.\d+)';
    $dbfile = '/var/lib/ip-smtp-blocking';
    $file_tail{'name'} = '/var/log/maillog';
    $pat = '^(... .. ..:..:..).+NOQUEUE: reject: RCPT from.+\[(\d+\.\d+\.\d+\.\d+)\]';
    This last is a favorite! It matches the pattern my mail system logs when a spammer is identified by one of various methods. I've constructed an elaborate inhouse mail and quarantine system using postfix, amavisd-new, spamassassin, razor, dccm, clamd, and openvispadmin (to give a graphical control panel to the mysql based user and quarantining system.) This last item keeps the dictionary mail attacks at bay, lightening server load immensely.

    Anyhow, this is the essence of it. Very simple, small, lightweight and effective. Anything you can match a log pattern for can be blocked by adding a new config/startup pair, thinking up a new name for each. I name mine such that they alpha-list together, they can be anything you like. Then just identify the log and the pattern, and point a startup script at it and you're ready to go.

    I added a couple of maintenance items as well. In /etc/bashrc I added the alias
    alias blocked='iptables -L -n'
    so I can simply type 'blocked' in my shell window to generate a list of currently blocked IP's, usually between a dozen and four dozen. Once I found a very long list, I guess the unblock part of the script had stalled out. I restarted my daemons and restored sanity (it erases the blocked list and starts fresh) and then wrote the same commands to an alias in /etc/bashrc:
    alias unblock='/etc/init.d/pop-before-smtp-blocking restart;
    /etc/init.d/pop-before-pop-blocking restart; 
    /etc/init.d/pop-before-ip-blocking restart; 
    /etc/init.d/pop-before-secure-blocking restart'
    so the 'unblock' command will restart all my daemons.

    So! That's about the size of it. I began this project because, thankfully, when I originally provisioned this server the supplied firewall wasn't working well or something. I think my own (above) does more of what I need. It has been working fine for over a year now. I began writing about this because my server half-crashed yesterday (apache jammed up) simply due to Internet traffic - showed spam traffic at 88.8%! This is incredible: given that legit traffic is likely constant, the difference between 90% spam and 80% spam is a DOUBLING of the total traffic on the 'net! My hope is that my system will be adopted by enough Spry customers (there's a big bunch of us) to positively impact this statistic globally. It should also save tons of CO2.


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts