Any server connected to internet will sooner or later become the target of hackers, that will try every possible vulnerability to break in and take control of it, to use it for their own purposes.
To protect the server as much as possible, it is common using some kind of firewall. In cases where an external firewall is not feasible or affordable, the iptables package that comes as default in most linux distros is one good choice to implement this functionality.
This post explains how to install and configure iptables on a Debian/Ubuntu system, together with fail2ban, that automates the detection and handling of brute force attacks.
iptables is the default firewall in Debian systems since Debian Lenny. iptables provides packet filtering and network address translation (NAT) to the system.
Mosts Debian systems include a default installation of iptables configured to allow all incoming and outgoing traffic. Even if it is already pre-installed, apt-get can be used to update the package, in case there is a more recent version available:
$ sudo apt-get install iptables Reading package lists... Done Building dependency tree Reading state information... Done iptables is already the newest version. $
The iptables command is used to configure the package. Option -L can be used to list the current rules:
# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
As can be seen, the default configuration allows all incoming and outgoing traffic (INPUT, OUTPUT), as well as any traffic that tries to use the system as a router (FORWARD).
Configuring iptables with ufw
iptables is configured by adding firewall rules, either interactively from the command line, or writing the rules in a file that is then feed to iptables. However, the syntax of these rules is complex, and it is generally advisable to used a configuration wizard, such as ufw (or its graphical frontend, gufw).
First, ufw is installed with apt-get:
$ sudo apt-get update $ sudo apt-get install ufw ... Setting up ufw (0.31.1-2) ... Creating config file /etc/ufw/before.rules with new version Creating config file /etc/ufw/before6.rules with new version Creating config file /etc/ufw/after.rules with new version Creating config file /etc/ufw/after6.rules with new version
Next, we will set up a sample configuration that rejects all accesses to the server, other than:
- Accesses to port 80 (HTTP) or 443 (HTTPS), from any address
- Acceses to port 22 (SSH) from the computer used to connect remotely to the server. In this example, we will assume that the IP address of the computer is 126.96.36.199.
The configuration is set up executing the following commands:
$ sudo ufw allow 80 $ sudo ufw allow 443 $ sudo ufw allow from 188.8.131.52 to any port 22 <- IMPORTANT, read warning below $ sudo ufw default deny incoming $ sudo ufw enable
WARNING: It is important to make sure that the IP address that will be granted SSH access is that of the computer we are using to connect to the server, because otherwise we will lose access to the server as soon as we enable the firewall.
Finally, the configuration can be verified with the command “ufw status”:
$ sudo ufw status Status: active To Action From -- ------ ---- 80 ALLOW Anywhere 443 ALLOW Anywhere 22 ALLOW 184.108.40.206 80 ALLOW Anywhere (v6) 443 ALLOW Anywhere (v6)
Configuring iptables dynamically to react to ongoing attacks
Instead of (o besides) passively protecting the server, restricting access to a limited set of IP addresses that are allowed to connect via SSH, we can use a monitoring program to detect attacks, such as repeated attempts to connect with non-existing users. When one of those attacks happens, the program adds firewall rules dynamically to the iptables configuration, to ban access from the offending IPs.
One of the programs of this type most commonly used in linux systems is fail2ban. fail2ban can work in combination with iptables, or with TCP wrappers. The usage of fail2ban with iptables is explained below.
fail2ban is easily installed on a Debian or Ubuntu system with a call to apt-get:
$ sudo apt-get install fail2ban Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: gamin libgamin0 python-gamin ...
The installation creates a set of configuration files:
- /etc/fail2ban/fail2ban.conf – basic config
- /etc/fail2ban/jail.conf – configuration for monitoring several services. In the default configuration only ssh monitoring with iptables is active.
- /etc/fail2ban/action.d/ directory – actions that will be executed to ban access from suspected IPs
Looking at the /etc/fail2bin/jail.conf file, we can find the section where ssh monitoring is configured:
[ssh] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 6
We can see that:
- ssh monitorin is enabled.
- The log file being monitored is /var/log/auth.log.
- If six consecutive failed connection attempts from the same IP address are detected, the action configured is executed to protect the server.
As there is no specific action configured in the [ssh] section, the default action defined in the [DEFAULT] section is used:
banaction = iptables-multiport action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] action = %(action_)s
In this example, the action identified as “iptables-multiport” will be executed. The commands that will be executed for this action are configured in the file /etc/fail2ban/action.d/iptables-multiport.conf:
... actionstart = ... actionstop = ... actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP ...
As we can see, the command that will be used to ban (actionban) access from a given IP address is the iptables command with option -I, to add a rule to the firewall.
After a configured time has elapsed, the action to lift the ban (actionunban) will be executed. Again, this is the iptables command, with option -D, to delete the rule previously added.
The time until the ban action es undone is configured with the “bantime” directive in the file jail.conf. The default value is set up in the [DEFAULT] section of the file:
bantime = 600
In this example, the time configured is 600 seconds (10 minutes).
- Debian Wiki – Debian Firewall
- Debian Wiki manpages – iptables
- digitalocean.com – How To Setup a Firewall with UFW on an Ubuntu and Debian Cloud Server
- Fail2ban Community Portal