Skip to end of metadata
Go to start of metadata

In this guide, we'll show you one of the most effective tools you can use for securing your VPS: an active firewall.

Active vs. Static Firewalls

When most of us think "firewall," we think of a configuration where certain ports are blocked or allowed and this list does not change.  The best practice is to close all ports and deny access to them by default, and then open only those which are needed.  So if you're running a web server, you may open ports 80 and 443 for http/https, and perhaps a port for ssh to manage the system, and then every other port would be closed.

However, this approach is not optimal for security.  There are some ports that you may need to open such as POP3, IMAP, FTP, or ssh, and once they're opened, they're open to everyone on the Internet.  Hackers can run scripts to try passwords endlessly until they find an account which has chosen a poor password.  While you may choose a good password, your less technically sophisticated customers may not.  You can't decide to run POP3 or IMAP on nonstandard ports, otherwise customer's mail clients won't work, so you're stuck taking the risk of having these Internet-facing ports open.

Fortunately, there is a solution: active firewalls.  With an active firewall, the ruleset is dynamic and can change instantly when the software detects a threat.  For example, it will watch your service logs and notice that a particular IP on the Internet is repeatedly trying to login to different accounts.  After a number of failures, it can insert a rule dynamically that blocks that IP, either for a period of time (such as 15 minutes) or permanently.  This greatly slows down attacks to the point where they are either no longer feasible or are blocked entirely.

This is a very powerful tool because it eliminates attempts to brute-force passwords, one of the easiest and most common hacking attacks. Note that active firewalls are not a silver bullet for security - nothing is.  But in concert with other tools and techniques, active firewalls are a valuable piece of your server's armor.

ConfigServer Firewall

ConfigServer Firewall (CSF) is a very popular active firewall tool.  It is free.

To set it up, first install some required perl modules.  On Debian-based systems, issue this command as root:

On CentOS-based systems:

yum -y install perl-libwww-perl.noarch perl-LWP-Protocol-https.noarch perl-GDGraph

If you’re running CentOS, that distro’s native firewall (firewalld) comes pre-enabled.  You need to disable it before setting up CSF:

systemctl stop firewalld
systemctl disable firewalld

Now download and extract CSF:

cd /usr/src
tar xzf csf.tgz
cd csf

Next make sure you have all the required kernel modules:

# perl /usr/local/csf/bin/ 
Testing ip_tables/iptable_filter...OK
Testing ipt_LOG...OK
Testing ipt_multiport/xt_multiport...OK
Testing ipt_REJECT...OK
Testing ipt_state/xt_state...OK
Testing ipt_limit/xt_limit...OK
Testing ipt_recent...OK
Testing xt_connlimit...OK
Testing ipt_owner/xt_owner...OK
Testing iptable_nat/ipt_REDIRECT...OK
Testing iptable_nat/ipt_DNAT...OK
RESULT: csf should function on this server

If you're running a current version of Debian or CentOS, you should see the "csf should function on this server" message.

CSF's Daemons

CSF runs two daemons:

  • csfd is the main CSF daemon that handles firewall changes and configuration changes.
  • lfd is the "Login Failure Daemon" that watches your server logs for brute-force attempts.  It runs continuously so even short burst attacks are noted and dealt with.

Configuring CSF

One thing to keep in mind is that CSF can lock you out just as easily as it locks out a hacker.  To prevent this, CSF starts in TESTING mode.  This allows you to tweak the config before it starts defending your server.

Start by editing /etc/csf/csf.conf.  It is beautifully commented and it's worth your time to read through the comments to understand what each configuration item controls.  When in doubt, leave as-is, but here are some things you should initially look at:

  • TCP_IN is the list of ports that you allow.  Examine this list carefully and remove any ports that aren't needed.  If you have other ports that you need open (for example, if you're running ssh on a port other than port 22), be sure to add it to this list.
  • TCP_OUT should match TCP_IN unless you have a reason not to.
  • Do the same for UDP_IN and UDP_OUT.  Keep in mind that that UDP port 53 is DNS, which you likely want to leave open.
  • If you're not using IPV6, set IPV6 to 0, otherwise adjust TCP6_IN, UDP6_IN, etc. to match their IPV4 parallels.
  • Set LF_ALERT_TO to your email address so that you receive alerts when IPs are blocked

Avoiding Lockout

There are a few tricks you can put in place to avoid locking yourself out accidentally.

First, disable csf and lfd from automatically starting until you are sure your configuration is solid:

systemctl disable csf
systemctl disable lfd

This way, if you get locked out, you can go to your VM control panel and reboot your VM, and when it restarts, the CSF daemons won't be running.

Also, CSF does not block console connections, so you can login to your console (in your VM control panel) and issue these commands to stop CSF:

systemctl stop csf
systemctl stop lfd

Note that in normal operation, you should have CSF running all the time.  These are only emergency measures in case you've misconfigured CSF and need to regain access to your server.

Going Live with CSF

To enable CSF in full protection mode, edit /etc/csf/csf.conf and changing TESTING to 0.  Then restart the daemons:

systemctl restart csf
systemctl restart lfd

Watching CSF

Before long, you will see messages like this in /var/log/lfd.log (the IP address has been anonymized here as x.x.x.x):

Sep  26 12:00:00 myserver lfd[1234]: (sshd) Failed SSH login from x.x.x.x (US/United States/ 5 in the last 3600 secs - *Blocked in csf* [LF_SSHD]

This means that lfd saw multiple ssh login failures from that IP (x.x.x.x) and took action by adding a firewall rule to block it.

You'll see the same rule in /etc/csf/csf.deny, so that if the system restarts the firewall ruleset is recreated exactly as it was before reboot.

x.x.x.x # lfd: (sshd) Failed SSH login from x.x.x.x (US/United States/ 5 in the last 3600 secs - Sat Sep 26 12:00:00 2020

Assuming you entered and email in the LF_ALERT_TO field, you'll get an email like this:

Time:     Sat Sep 26 12:00:00 2020 -0700
IP:       x.x.x.x (US/United States/
Failures: 5 (sshd)
Interval: 3600 seconds
Blocked:  Permanent Block [LF_SSHD]
Log entries:
Sep 26 12:00:00 myserver sshd[1234]: Invalid user nonexistant from x.x.x.x port 42858
Sep 26 12:00:01 myserver sshd[1234]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=x.x.x.x
Sep 26 12:00:02 myserver sshd[1234]: Failed password for invalid user nonexistant from x.x.x.x port 42858 ssh2
Sep 26 12:00:03 myserver sshd[1234]: Failed password for invalid user nonexistant from x.x.x.x port 42858 ssh2
Sep 26 12:00:04 myserver sshd[1234]: Failed password for invalid user nonexistant from x.x.x.x port 42858 ssh2

If you want to see the entire CSF ruleset, you can use this command:

csf -l

Unblocking and Whitelisting IPs

If you need to unblock an IP that CSF has blocked, issue this command:

csf --denyrm x.x.x.x

You will see a message like this:

Removing rule...
DROP  all opt -- in !lo out *  x.x.x.x  -> 
LOGDROPOUT  all opt -- in * out !lo  -> x.x.x.x

If you want to permanently whitelist an IP, you can do so by adding it to /etc/csf/csf.allow.

Enabling CSF

Once you're comfortable that CSF is working as expected, be sure to enable CSF/LFD so it always starts on system boot:

systemctl enable csf
systemctl enable lfd

For More Information

Write a comment…