How to block countries with ipdeny IP country blocks, ipset and iptables on EL6

An analysis of the firewall logs of one of my servers showed that more than 99% of the ssh attacks, probes and mail relay attempts come from a rather large country in the east. It also showed that the server had to endure thousands of attempts in a very short period of time. While fail2ban did take care of that eventually these attacks still (ab)used valuable resources which impacted regular users.

As a last resort you can solve this problem with a regular big hammer (block all countryX IP ranges for a certain port like ssh/22) or with a really big hammer (block all countryX IP ranges).

Both concepts make use of ipset, iptables and the IP ranges from

Install ipset:

What to choose – regular big hammer or really big hammer?

That’s basically up to you. Regular users are not very likely to try to access your server via ssh so in the interest of an Open Internet it makes sense to just block the ssh/22 port for the originating country. If other services on your server like web, mail, dns or vpn get hammered then you can always switch to totally block the originating country.

Option I: Regular big hammer – block a certain port for an entire country

Kernel modules – the following kernel modules need to be loaded:

Create a set called ‘geoblock’ or whatever you want to call it. For blocking a port for an entire country use hash:net,port as the type:

Next add the IP country blocks of your choosing:

Option II: Really big hammer – block an entire country

Kernel modules – the following kernel modules need to be loaded:

Create a set called ‘geoblock’ or whatever you want to call it. For a full IP country block use hash:net as the type:

Next add the IP country blocks of your choosing:

Add drop rule to the firewall

Finally to test things out you can add a rule to the running iptables so the src IP address gets matched against the set of IP addresses in geoblock. The rule looks like this and it is automagically inserted as the first rule:

Check that the rule is activated:

It’s also possible to do an inverse meaning that you can for example drop all connections not coming from the IP addresses in the geoblock set. The rule looks like this (note the ‘!’):

The ‘!’ is ‘not’ so anyone who is trying to access the host from an IP address not in the geoblock set will be dropped.

Saving an ipset set

You can save an ipset set with the following command:

and you can restore a saved ipset set with:

Note that the name of the set is part of the saved file (open it to see).

Making the ipset sets persistent

IMPORTANT: if you have an ipset rule hardcoded in your /etc/sysconfig/iptables and that ipset set is not loaded then service iptables start will fail and the firewall will not be active.

As far as I know EL6 has unfortunately no way to run a script before iptables is started. However you can create a script that is run at boot from /etc/rc.local where it restores the ipset sets and adds a non-persistent rule into iptables or can be run manually:

Make sure the script is executable:

IMPORTANT: as already mentioned the iptables rule that the script adds is non-persistent. This means that when you do a service iptables restart the ipset rule(s) is (are) gone. To activate the rule(s) again /usr/sbin/ must be run after the iptables service has been restarted.

Now add the /usr/sbin/ script to /etc/rc.local:

Making sure the ip_set kernel modules get loaded

If you want to make sure that the ip_set kernel modules are loaded at boot then add them to /etc/sysconfig/iptables-config in IPTABLES_MODULES:

Comments and enhancements always welcome.

How to setup OpenVPN on Fedora 19

Here is a quick howto setup OpenVPN on Fedora 19. For the sake of simplicity all steps are performed as root.

Install openvpn and easy-rsa:

Create the keys/ dir:

Create empty openvpn log files:

If you already have keys then copy them to /etc/openvpn/keys. If not then you will need to generate them. Read /usr/share/doc/easy-rsa-2.2.0/doc/README-2.0 for instructions how to do that.

Also generate the dh and ta keys:

Create a configuration called my-vpn.conf which uses TLS. It’s ok to call the config file something else but make sure to replace my-vpn in further steps below with the name you have chosen for your config file:

IMPORTANT: change the following settings above for your situation:
– server
– push “dhcp-option DOMAIN”
– push “dhcp-option SEARCH”

Make sure ipp.txt exists:

Set proper ownership of the openvpn directory, config files and keys:

Reset the SELinux labels:

Now setup systemd so openvpn starts at boot. For background information see this bug:

Start the openvpn my-vpn service:

And check if it started ok:

Which should say something like this:

Next copy your client1.key, client1.crt, ca.crt and ta.key to ~/.cert/ on the client box that will access the OpenVPN server. If your client is also a recent Fedora box and you use NetworkManager then you can create a small config file with the proper settings to access your OpenVPN server and import it in NetworkManager.

The client config VPN for NetworkManager looks like this:

IMPORTANT: replace the entries between < ...> with your settings:
– remote <your-openvpn-server> 1194
– ca /home/<you>/.cert/ca.crt
– cert /home/<you>/.cert/client1.crt
– key /home/<you>/.cert/client1.key

Now import this file into NetworkManager by going to:

On your OpenVPN server make sure that port 1194 (or whatever port you chose) is open in the firewall.
Finally on your client box click on the NetworkManager icon in the top menu bar and select my-vpn. Enjoy your new secure VPN connection. Comments and enhancements always welcome.

How to fix Clocksource tsc unstable

If you see this message on the console of your CentOS 6.x VM:

then the kernel has figured out that the clock source of your VM is unstable and reports it.

Check which clock sources are available:

Check the currently selected clock source:

To fix the “Clocksource tsc unstable” message add an alternative clock source to the kernel line in /boot/grub/grub.conf:

On CentOS 6.4 x86_64 the line looks something like:

Reboot and the message should no longer occur. If acpi_pm does not work for you then try one of the other available clock sources.

VMware has written an Information Guide with detailed information called Timekeeping in VMware Virtual Machines