Skip to main content

Spending RM0.00 while improving cybersecurity - Part 1

·1008 words·5 mins
Author
Dr. Suresh Ramasamy
A tech afficianado who hails from South East Asia.

This is the follow up article to the presentation at Junior DevOps meetup.

Precursor
#

Today’s day and age where technology is synonymous with budget and spending. You see lack of actual groundwork initiatives for anything, where tech is just a job to be done and not a passion nor research to be pursued. As a result, you see the notion that technology is all about spending and if you don’t spend, you can’t improve.

Cybersecurity is not absolute, but relative

Cybersecurity is multifaceted, and never a single dimension. Basic hygiene is no longer good enough. As such, one part of keeping the hygiene is keeping your apps up to date, the other part is securing the entrypoints, such as the network access. Yes, most may not be able to have dedicated firewall or network filter devices, and some run only as a few cloud servers/VPS.

With issues such as zero day attacks, one can only REALISTICALLY hope and do what’s necessary to minimise the risk of failure or breach. And this method is one of those mitigating measures.

Platform used
#

For the purpose of this article and the demo done, I’m using stock Debian version 12. If there are any additional tools used, I’ll highlight the need to install them. You’d see the coming section that I’d be heavily using GNU CoreUtils which is part of the stock standard installation. As such, you’ll have it installed by default, so no additional packages required.

Logs, eyes of the system
#

Your system, its daemons and applications are configured to give you the option to enable logging. This is a must, especially if you want to know whats happening in the system. Enabling logs means creating and preserving informa tion relevant to what’s happening to the system.

We’ll use sshd (secure shell daemon) for illustration. sshd is used for remote access, port forwarding and even file transfer. It was a more secure option compared to telnet/rservices.

sshd creates the log file auth.log in the directory /var/log. One has to have root or similar access to be able to view the file. At this or any juncture you wouldnt want to modify the log file.

All the work we do from now onwards centers around the availability and sufficient verbosity of the logs in order for action to be taken.

Ban when something is failing…
#

Enter fail2ban, an installable application which does NOT come part of the system. To install fail2ban…

$ sudo apt update
$ sudo apt install fail2ban

To check if fail2ban is installed/running

$ sudo systemctl status fail2ban.service 

You’ll get something like this to confirm…

Output
● fail2ban.service - Fail2Ban Service
     Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled
     Active: active (running) since Tue 2025-09-16 16:23:14 UTC; 27s ago
       Docs: man:fail2ban(1)
    Process: 1942 ExecStartPre=/bin/mkdir -p /run/fail2ban (code=exited, status=0/SUCCESS
   Main PID: 1943 (fail2ban-server)
      Tasks: 5 (limit: 1132)
     Memory: 15.8M
        CPU: 280ms
     CGroup: /system.slice/fail2ban.service
             └─1943 /usr/bin/python3 /usr/bin/fail2ban-server -xf start

Concept of fail2ban
#

*Note: fail2ban requires iptables in order to work. If your system doesn’t have it, please head on to the next section on instructions for installation. *

Fail2ban has a few components that you need to configure in order for it to work for your system.

Jails are virtual constructs that you use based on per-application/per-daemon. Each jail represents a set of regular expressions in a file which creates a fail, usually created based on logs produced from a system. e.g. you’d have sshd jail which is derived based on regexp patterns matching logs that indicate failures triggered by sshd. When you enable sshd jail, you are parsing /var/log/auth.conf to check for matches against the sshd regexp rules, and the IP address is then extracted.

You can define how long the ban time should be, how many times retries are allowed. You can also configure allowlist to prevent yourself from being locked out.

Next is action. Action is what fail2ban should do once it encounters an offending IP address. For example, in Linux systems, you can use iptables to block the respective traffic. You can use iptables independently or couple it with ipset. You will see me using the iptables+ipset combo extensively in the later part of this article. If you’re on a FreeBSD system, then you’d use pf or ipfw instead.

Issues with fail2ban
#

fail2ban was designed to be a rudimentary means of blocking offending IP address. It’s process flow is simplictic and easy, and often, based on “in-the-wild” observation, I found that attackers seem to understand this and continue to hammer the servers after the timeout is done.

That said, fail2ban acts as a first line of defense for immediate remediation for pesky attackers who are like mosquitoes buzzing near your ears.

iptables and ipset
#

iptables come default (unless if you specifically look for very minimal versions, then you may not have it). ipset however, as an additional addon

In the event if you do not have iptables

$ sudo apt install iptables iptables-persistent netfilter-persistent

To install ipset

$ sudo apt install ipset ipset-persistent 

Now that you have the prerequisites done, let’s move to using both together.

First, let’s configure ipset to create the necessary “buckets”.

$ sudo ipset create BlockedIP hash:ip
$ sudo ipset create BlockedSubnet hash:net

For sake of easy maintenance, I am separating the IP address bucket from the subnet bucket. Now, let’s tie in the ruleset to filter using these buckets.

$ sudo iptables -A INPUT -m set --match-set BlockedIP src -j DROP
$ sudo iptables -A INPUT -m set --match-set BlockedSubnet src -j DROP

Now, lets add some stuff into our respective buckets

$ sudo ipset add BlockedIP 3.4.5.6 comment "bad fellow"
$ sudo ipset add BlockedSubnet 8.7.7.0/24 comment "bad group"

To survive reboots and to make it persistent, we need to get this done

$ sudo netfilter-persistent save

What’s important is to make netfilter-persistent service enabled

$ sudo systemctl enable netflter-persistent
$ sudo systemctl start netfilter-persistent
$ sudo systemctl status netfilter-persistent

In the next article, we look at doing the IP based analysis using GNU Coreutils.