Introducing Base Stack
Base Stack installs some basic applications and configs that are common to any server build. Specifically Unattended Upgrades and Firewalld with Fail2Ban for a secure server setup. I use this as the basis for all my servers installs – nameservers, web servers, file servers, any server install starts with this as a basis. Additional ports and interfaces can easily be added to the firewall as need be, and additional services/ports can be added to the Fail2Ban monitoring. The installer assumes a minimal Debian 12 server install with no extra services or packages installed.
Unattended Upgrades are enabled and configured to run daily. Automatic reboots are configured for between 1:00 and 1:55am. Unused kernels and dependencies are automatically removed.
Firewalld is installed and enabled. By default only ssh is allowed over the default public interface. A “drop” zone is created that includes a manual blacklist and a fail2ban IP set.
Fail2Ban is installed and enabled with a novel method. A new Fail2Ban action is used instead of one of the defaults available from the Fail2Ban package. First Firewalld is configured to create an IP set named fail2ban. Then Fail2Ban uses nft commands directly to add/remove IPs, instead of issuing firewalld commands. This is done for performance reasons. Firewalld has a great command line interface, but it can be a bit slow when adding/removing IPs. This is particularly noticeable on a busy server where many IPs are being blocked/unblocked in a short amount of time, or when a restart/shutdown requires unbanning a large number of IPs at once. Using individual firewalld commands can take 1/2 second or more per IP. In contrast the direct nft commands are measured in thousandths of a second, and the entire set can be unloaded with one command. On a busy server this means a shutdown or restart goes from taking minutes to a fraction of a second.
There are also some helper scripts for managing fail2an and manual blacklists:
fail2ban-unban.sh
Manually remove a specified IP from the Fail2Ban blacklist.
1 |
fail2ban-unban.sh 192.168.1.2 |
firewall-blacklist-add.sh
Adds an IP/network to a permanent blacklist.
1 2 |
firewall-blacklist-add.sh 192.168.1.2 firewall-blacklist-add.sh 192.168.1.0/24 |
firewall-blacklist-rem.sh
Remove an IP/network from the permanent blacklist.
1 2 |
firewall-blacklist-rem.sh 192.168.1.2 firewall-blacklist-rem.sh 192.168.1.0/24 |
firewall-blacklist-zone.sh
Blacklist an entire country zone using data from ipdeny.com. Simply specifiy the two letter country code like this:
1 |
firewall-blacklist-zone.sh ru |
This will download the list of IP networks for the given country (RU = Russia), create an IP set in firewalld, and add that ipset to the drop zone, blacklisting the entire country. To remove a country zone block use these individual firewalld commands:
1 2 |
firewall-cmd --zone=drop --remove-source=ipset:ipdeny-$zone-zone firewall-cmd --permanent --zone=drop --remove-source=ipset:ipdeny-$zone-zone |
The first command removes the block from the active firewall and the second command removes the block from the permanent configuration so it’s not re-added on a restart.
For example, to remove a country block for Russia (RU) run these commands:
1 2 |
firewall-cmd --zone=drop --remove-source=ipset:ipdeny-ru-zone firewall-cmd --permanent --zone=drop --remove-source=ipset:ipdeny-ru-zone |
You can get the Base Stack code here: https://git.stack-source.com/msb/base-stack