Client Login

Contact Us

  • Sales
  • Support
  • Abuse

Close Support


VPS Protection with fail2ban and iptables

VPS Protection with fail2ban and iptables
  • 27

VPS Protection with fail2ban and iptables

VPS Protection with fail2ban and iptables.

The main tool in building the protection of a Linux VPS is the iptables firewall. The fail2ban utility also uses iptables to block packets from banned IP addresses and python to detect such addresses. For greater security, I recommend changing the standard SSH port to some exotic port. From this we begin.

Transferring an SSH server to a different port

It’s easy, and done in two short steps. First, edit the config file of the SSH daemon:

$ sudo nano /etc/ssh/sshd_config

Change Port 22 to something complex and five-valued. In order to avoid possible conflicts with other programs, it is necessary to choose from the range of dynamic ports, and these are the values from 49152 to 65535:

 # What ports, IPs and protocols we listen for
 #Port 22
 Port 49681

Save the changes (Ctrl + O), exit nano (Ctrl + X) and restart the SSH daemon:

$ sudo service ssh restart

The next time you connect, you must explicitly specify the port:

$ ssh user@host -p 49681

Block all ports except HTTP, HTTPS and SSH:

I would not recommend keeping any other services open on the server with the sites, it’s better to allocate a separate VPS for them, and configure it accordingly. In the case where the only function is web hosting, you can close all ports except those two where browsers of live visitors of the resource are usually directed – 80 (HTTP) and 443 (HTTPS), and one more where the server administrator connects to SSH (we Changed it higher at 49681). First, create a file with iptables rules:

$ sudo touch /etc/iptables.firewall-rules 
We put the following contents inside:
 # We resolve all internal traffic on the interface lo and prohibit internal traffic that does not use lo
 -A INPUT -i lo -j ACCEPT
 -A INPUT ! -i lo -d -j REJECT
 # Allow all incoming connections already established
 # Allow all outbound traffic
 # Allow all incoming HTTP and HTTPS connections
 -A INPUT -p tcp --dport 80 -j ACCEPT
 -A INPUT -p tcp --dport 443 -j ACCEPT
 # Allow connection to port 49681 for SSH
 -A INPUT -p tcp -m state --state NEW --dport 49681 -j ACCEPT
 # Allow ping
 -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
 # Let's log all the connections that were dropped by the firewall
 -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
 # We prohibit all connections that are clearly not allowed

Now you need to write a script that will apply these rules automatically when the system boots. Create an empty file and immediately make it executable:

$ sudo touch /etc/network/if-pre-up.d/firewall
$ sudo chmod +x /etc/network/if-pre-up.d/firewall 

Its contents should be something like:

/sbin/iptables-restore < /etc/iptables.firewall-rules 

The first time the command specified in the script must be executed manually from the superuser, to enable protection immediately after the configuration, and when the OS reboots the rules it will add a script. You can check which rules are added to iptables in the following way:

$ sudo iptables -L 
Dynamic protection from bots with the help of fail2ban:

Fail2ban is usually not included in the basic set of system utilities, and it needs to be installed:

For Ubuntu, Debian linux:

$ sudo apt-get install fail2ban  

For CentOS, Fedora linux:

$ yum install epel-release
$ yum install fail2ban fail2ban-systemd

Before starting work, it is recommended to make a copy of the configuration file and make changes only to it, since the original config can be overwritten during the update:

$ cd /etc/fail2ban/ && cp jail.conf jail.local 

The fail2ban utility from the box has several ready-made filters for Apache, but I would recommend creating own filters: one for the access log, and the second for the errors. Virtual hosts should be configured so that these logs for all sites are shared, which allows you to protect all sites on the server immediately with just two filters. Create empty files for filters:

$ cd /etc/fail2ban/filter.d/
$ touch apache-access.conf
$ touch apache-error.conf

Sample content for the apache-access.conf filter:

# Apache Access Filter
 failregex =
 ^.* ‹HOST› .*///.*
 ^.* ‹HOST› .*\\\.*
 ^.* ‹HOST› .*w00tw00t.*
 ^.* ‹HOST› .*WinHttpRequest.*
 ignoreregex = 

It can and should be supplemented with new lines in the failregex section based on what suspicious activity you found in the access.log. Above, queries containing the words “w00tw00t”, “WinHttpRequest” or three slashes in one direction or another are blocked.

The filter for error.log has exactly the same structure:

# Apache Error Filter
 failregex =
 ^.*\[client ‹HOST›\].**
 ^.*\[client ‹HOST›\].*Lost connection to MySQL server during query.*
 ^.*\[client ‹HOST›\].*client denied by server configuration.*
 ^.*\[client ‹HOST›\].*Invalid URI in request.*
 ^.*\[client ‹HOST›\].*/admin.php' not found or unable to stat
 ^.*\[client ‹HOST›\].*/boss-login.php' not found or unable to stat
 ^.*\[client ‹HOST›\].*/vam_rss2_info.php' not found or unable to stat
 ^.*\[client ‹HOST›\] File does no exist: .*typo3
 ^.*\[client ‹HOST›\] File does no exist: .*hostcmsfiles
 ^.*\[client ‹HOST›\] File does no exist: .*administrator
 ^.*\[client ‹HOST›\] File does no exist: .*bitrix
 ^.*\[client ‹HOST›\] File does no exist: .*bbadmin
 ^.*\[client ‹HOST›\] File does no exist: .*WebAdmin
 ^.*\[client ‹HOST›\] File does no exist: .*webmanage
 ^.*\[client ‹HOST›\] File does no exist: .*fck
 ^.*\[client ‹HOST›\] File does no exist: .*fckeditor
 ^.*\[client ‹HOST›\] File does no exist: .*web
 ignoreregex = 
In the jail.local configuration file in the HTTP servers section, you must connect the newly created filters. Correctly specify the path to the files with logs, otherwise it will not work:
 enabled = true
 port = http,https
 filter = apache-access
 logpath = /path/to/access.log
 maxretry = 1
 findtime = 600
 bantime = 86400
 enabled = true
 port = http,https
 filter = apache-error
 logpath = /path/to/error.log
 maxretry = 1
 findtime = 600
 bantime = 86400

It is useful at the same time to include (change from false to true the enabled field) preset filters [ssh] and [ssh-ddos]. In order to activate the protection, restart fail2ban:

$ sudo service fail2ban restart 

After that, the fail2ban filters and the list of blocked for bad behavior of IP-addresses can be seen in the output of the command:

sudo iptables -L 

It’s time to sum up. Our server is no longer so trusting, it does not respond to packets coming to ports other than HTTP, HTTPS and SSH. He can evaluate whether a particular client is behaving well and block otherwise. It will be protected when trying to hack SSH.

Comments are closed.