IPTables GeoIP, Port Knocking and Port Scan Detection

Here's a quick tutorial on how to enable extra IPTables functionality such as "GeoIP", "Port Knocking" and "Port Scan Detection" with modules provided by xtables-addons. See the full list of available modules.

xtables-addons Logo

Note 1: Can be used on dedicated servers or any KVM- or Xen-based VPS. Does NOT work on OpenVZ VPS due to its limitations.
Note 2: If you upgrade your server's Linux kernel later, you must first comment out the relevant IPTables rules, reboot the server, then compile and install xtables-addons again before re-enabling those rules.

Check the project website of xtables-addons for the latest versions. Note that if your server's Linux kernel version is older than 3.7 (including 2.6.x), use xtables-addons version 1.47.1.

See separate instructions below for Ubuntu/Debian and CentOS/RHEL. Credit goes to this HowToForge tutorial and comments, which I used as a reference.

Pre-install steps for Ubuntu/Debian:

Update package index and install required software:

apt-get update  
apt-get install iptables-dev libtext-csv-xs-perl linux-headers-`uname -r` \
build-essential pkg-config automake wget xz-utils unzip zip

Note: If you use Proxmox, install the kernel headers package with:

apt-get install pve-headers-`uname -r`  

Now you can go directly to the install steps.

Pre-install steps for CentOS/RHEL:

First, update your server's Linux kernel and reboot. Note for Linode users: Please enable GRUB and use a CentOS-provided kernel.

# (Recommended) Update all software including the kernel:  
yum update  
# Or, update the Linux kernel only:
yum update kernel  
# DigitalOcean users should change kernel settings in the Control Panel,
# then power off the droplet and power it on again. Please see:    
How to update a DigitalOcean server's kernel  
# For Non-DigitalOcean servers, just reboot:
reboot  

To avoid issues with xtables-addons, SELinux must be disabled. Check the current status with sestatus. It should say:

# sestatus  
SELinux status:   disabled  

Otherwise, we need to disable it before proceeding:

setenforce 0  
sed -i 's|SELINUX=enforcing|SELINUX=disabled|' /etc/selinux/config  

Proceed to install some required software:

yum install gcc gcc-c++ make automake \
iptables-devel wget nano unzip zip xz

Install the kernel source package that matches the running kernel:

yum install kernel-devel-`uname -r`  

It is OK if you see "Package already installed". But if the above command fails with "No package available", try these additional steps.

Next, enable the EPEL repository. Required for CentOS/RHEL 6.x users.

yum install epel-release  

Finally, install the package perl-Text-CSV_XS:

yum install perl-Text-CSV_XS  


Install steps for both Ubuntu/Debian and CentOS/RHEL:

Create and switch to working directory:

mkdir -p /opt/src  
cd /opt/src  

For CentOS/RHEL 6.x and Proxmox 3, the following workaround is required:

sed -i "s|#define CONFIG_IP6_NF_IPTABLES_MODULE 1|/* #define CONFIG_IP6_NF_IPTABLES_MODULE 1 */|" /lib/modules/`uname -r`/build/include/linux/autoconf.h  
# After the install succeeds, you may remove the workaround with:
# sed -i "s|/\* #define CONFIG_IP6_NF_IPTABLES_MODULE 1 \*/|#define CONFIG_IP6_NF_IPTABLES_MODULE 1|" /lib/modules/`uname -r`/build/include/linux/autoconf.h

Download the xtables-addons source:

# IMPORTANT: Check your server's Linux kernel version with  
uname -r

# Define the base URL for downloading from SourceForge
base_url=http://sourceforge.net/projects/xtables-addons/files/Xtables-addons

# Choose ONE from these commands based on the kernel version.
# For Linux kernels < 3.7 (including 2.6.x):
wget -t 3 -T 30 -qO- $base_url/xtables-addons-1.47.1.tar.xz | tar xJv  
# Otherwise, if kernel version >= 3.7:
wget -t 3 -T 30 -qO- $base_url/xtables-addons-2.12.tar.xz | tar xJv  

Compile and install xtables-addons:

cd xtables-addons-*  
./configure
make && make install  
depmod  

Fetch and build the GeoIP database:

cd geoip/  
./xt_geoip_dl
./xt_geoip_build GeoIPCountryWhois.csv
mkdir -p /usr/share/xt_geoip/  
cp -r {BE,LE} /usr/share/xt_geoip/  

Now test the GeoIP module. If no error, then the install was successful.

iptables -I INPUT -m geoip --src-cc US  
iptables -D INPUT -m geoip --src-cc US  

If you use the geoip module, don't forget to update its database monthly from MaxMind. Here's an example update script and cron job.

To use port scan detection, here's an example IPTables rule:

-A INPUT -m psd --psd-weight-threshold 15 --psd-hi-ports-weight 3 -j DROP  

Explanation: For incoming packets from any single host, if at least 5 ports on your server are hit within 3 seconds (default delay), then treat it as a port scan and drop further packets. The parameters are all customizable.

The following is from the manual page of xtables-addons:

 psd  
   Attempt to detect TCP and UDP port scans. 
   This match was derived from Solar Designer’s scanlogd.    
   --psd-weight-threshold threshold
     Total weight of the latest TCP/UDP packets with different
     destination ports coming from the same host to be treated
     as port scan sequence.
   --psd-delay-threshold delay
     Delay (in hundredths of second) for the packets with different 
     destination ports coming from the same host to be treated
     as possible port scan subsequence.
   --psd-lo-ports-weight weight
     Weight of the packet with privileged (<= 1024) destination port.
   --psd-hi-ports-weight weight
     Weight of the packet with non-priviliged destination port.

Here are the default values for these parameters:

weight-threshold: 21, delay-threshold: 300  
lo-ports-weight: 3,   hi-ports-weight: 1  

If you use this psd module and change your SSH port to a non-standard one (e.g. generate a random port at random.org), it would be more difficult for an attacker to discover the new port by port scanning. Technically, you can pick any port between 1 and 65535. However, some people argue that choosing a port less than 1024 could potentially enhance server security.

Besides geoip and psd, the pknock module is for easy port knocking, and tarpit is for keeping TCP connections "open" to waste an attacker's resources (someone even used it to "defend against" DDoS). To view detailed usage instructions for all modules, run man xtables-addons after install, or browse to this online manual.

Please share this post if you like it, and do not hesitate to write your comments or questions in the Disqus form below.


Next article: Securing Your Server using IPSet and Dynamic Blocklists
Previous article: Check Your Server for Malware from SSH Attacks

Return to Lin's Tech Blog Homepage



View or Post


Disclaimer: All content provided on this blog is for informational purposes only. The owner of this blog makes no representations as to the accuracy or completeness of any information on this site or found by following any link on this site. All trademarks mentioned herein belong to their respective owners.
    The owner of this blog will not be liable for any errors or omissions in this information nor for the availability of it. The owner will not be liable for any losses, injuries, or damages from the display or use of this information.

Your name:

Email address:

Website URL:

Please leave a comment:

You agree that this form is for A N T I-S P A M B O T S!
     D O-N O T-S U B M I T !