Hardening a Debian 13 Rsyslog Server with UFW and Fail2Ban

In a previous tutorial you set up a basic rsyslog server on Debian 13 to receive logs from remote Linux clients. That is a great start, but an open syslog port on the network can quickly become a target for scanners, misconfigured clients, or even abuse.

In this guide, you will learn how to secure your Debian 13 syslog server with:

  • UFW (Uncomplicated Firewall) to restrict which IP ranges can reach your syslog ports and SSH.
  • Fail2Ban to block brute-force SSH attempts and optionally rate-limit noisy syslog clients.

We will go step by step and explain each configuration line so you understand not only what you are typing, but also why.

Prerequisites

Before you start, make sure you have:

  • A working Debian 13 server with rsyslog already configured to receive remote logs (UDP and/or TCP on port 514).
  • Root or sudo access to the server.
  • IP addresses or subnets of the trusted clients that are allowed to send logs.

In the examples, we will use these sample networks:

  • Syslog server: 192.168.0.123

Step 1: Install and Configure UFW Firewall

UFW (Uncomplicated Firewall) is a user-friendly frontend for iptables/nftables. It is perfect for a dedicated syslog server where you want clear, readable rules.

1.1 Install UFW

sudo apt update 
sudo apt install ufw -y

Line by line explanation:

  • sudo apt update – refreshes the package index so your server knows about the latest available packages.
  • sudo apt install ufw -y – installs UFW and automatically answers “yes” to the installation prompt.

1.2 Set Default Firewall Policies

sudo ufw default deny incoming 
sudo ufw default allow outgoing

Line by line explanation:

  • sudo ufw default deny incoming – blocks all incoming connections by default. Later you will explicitly allow only the ports and networks you trust.
  • sudo ufw default allow outgoing – allows outgoing connections (DNS, updates, NTP, etc.) so the server can still reach the internet and internal services.

This default deny policy is an important security baseline: nothing can reach your server unless you explicitly open it.

Step 2: Secure SSH Access

Before you enable UFW, you must make sure that you do not lock yourself out of SSH. The safest approach is to allow SSH only from your admin network or static IP.

2.1 Allow SSH from a Trusted Subnet

sudo ufw allow from 192.168.0.0/24 to any port 22 proto tcp

Explanation:

  • from 192.168.0.0/24 – only hosts in the 192.168.0.0–192.168.0.255 range are allowed.
  • to any – “any” means any IP address on this server (useful if the server has multiple interfaces).
  • port 22 – open only SSH port 22.
  • proto tcp – match TCP protocol (SSH uses TCP).

If you have a single static public IP, you can restrict SSH even more tightly:

sudo ufw allow from 1.2.3.4 to any port 22 proto tcp

Replace 1.2.3.4 with your real admin IP address.

Step 3: Allow Syslog Traffic Only from Trusted Clients

Now you will allow access to the syslog ports (UDP and optionally TCP on port 514) only from trusted branch networks.

3.1 Allow UDP 514 from Trusted Subnets

sudo ufw allow from 192.168.0.0/24 to any port 514 proto udp 
sudo ufw allow from 192.168.1.0/24 to any port 514 proto udp 

Explanation (applies to each line):

  • from 192.168.1.0/24 – allows packets from the TN branch subnet (replace with your real network).
  • to any port 514 – opens port 514 on your syslog server.
  • proto udp – matches only UDP packets (standard syslog uses UDP by default).

Repeat for each subnet that should be allowed to send logs. Any other source IP trying to reach UDP/514 will be blocked by the default deny incoming policy.

3.2 Allow TCP 514 if Your Rsyslog Uses TCP

If you also configured rsyslog to receive logs via TCP (for example for more reliable delivery), add similar rules for TCP:

sudo ufw allow from 192.168.0.0/24 to any port 514 proto tcp 
sudo ufw allow from 192.168.1.0/24 to any port 514 proto tcp 

If your syslog server listens only on UDP, you can skip the TCP rules entirely.

Step 4: Enable UFW and Check the Rules

Once SSH and syslog rules are in place, you can safely enable the firewall.

sudo ufw enable

Explanation: sudo ufw enable activates UFW with your defined rules. UFW will now start at boot and apply these rules automatically.

To see the active rules, run:

sudo ufw status verbose

Any other incoming traffic is blocked by default, which is exactly what you want for a hardened syslog server.

Step 5: Install Fail2Ban

UFW blocks or allows traffic based on IP and port, but it does not track behavior over time. Fail2Ban watches your log files, detects suspicious patterns (like repeated failed logins) and dynamically adds firewall rules to block offenders.

5.1 Install the Package

sudo apt install fail2ban -y

Explanation: This installs the Fail2Ban service and some default jail configurations for common services (SSH, etc.).

5.2 Create a Local Fail2Ban Configuration

Fail2Ban uses a main configuration file /etc/fail2ban/jail.conf, but you should not modify it directly. Instead, create /etc/fail2ban/jail.local to override or extend the defaults.

sudo nano /etc/fail2ban/jail.local

Paste the following content:

[DEFAULT] 
destemail = root@localhost 
sender = fail2ban@syslog-server.local 
mta = sendmail 
bantime = 1h 
findtime = 10m maxretry = 5 
[sshd] enabled = true 
port = 22 
logpath = /var/log/auth.log 
backend = systemd

Now let’s go through this configuration line by line.

5.3 Understanding the [DEFAULT] Section

  • [DEFAULT] – defines settings that apply to all jails unless they are overridden in a specific jail section.
  • destemail = root@localhost – email address where Fail2Ban will send notifications (you can change this to an admin email).
  • sender = fail2ban@syslog-server.local – “From” address used in Fail2Ban emails. It should match your server’s hostname or domain.
  • mta = sendmail – mail transfer agent used to send emails. You can change this to postfix or another MTA if you prefer.
  • bantime = 1h – how long an offending IP address is banned (1 hour). You can set values like 10m, 24h or 1d.
  • findtime = 10m – time window in which Fail2Ban counts failed attempts. Here it checks the last 10 minutes of log entries.
  • maxretry = 5 – maximum number of failed attempts within the findtime window before an IP is banned.

5.4 Understanding the [sshd] Jail

  • [sshd] – jail definition for the SSH daemon service.
  • enabled = true – activates this jail. If you set false, Fail2Ban will ignore SSH logs.
  • port = 22 – port Fail2Ban protects. If you changed your SSH port (for example to 2222), you must update this value.
  • logpath = /var/log/auth.log – path to the log file where SSH authentication attempts are stored on Debian.
  • backend = systemd – tells Fail2Ban to use systemd’s journal as the backend (good default on modern Debian systems).

With this configuration, if someone tries and fails to log in via SSH more than five times within ten minutes, their IP will be banned for one hour.

Step 6: (Optional) Prepare a Jail for Noisy Syslog Clients

This step is optional and more advanced. The idea is:

  • Log all remote syslog messages from port 514 into a dedicated log file.
  • Use Fail2Ban to watch this file and ban IPs that match a suspicious pattern or generate too much noise.

6.1 Add a Dedicated Rsyslog Ruleset for Remote Logs

Create a new rsyslog config file:

sudo nano /etc/rsyslog.d/10-remote-514.conf

Paste this example configuration:

module(load="imudp") input(type="imudp" port="514" ruleset="remote514") ruleset(name="remote514") { action(type="omfile" file="/var/log/remote-514.log") }

Line by line:

  • module(load="imudp") – loads the imudp module so rsyslog can receive syslog messages over UDP.
  • input(type="imudp" port="514" ruleset="remote514") – defines a UDP input on port 514 and tells rsyslog to process messages with the remote514 ruleset.
  • ruleset(name="remote514") { ... } – defines a custom ruleset named remote514 for all messages received on this input.
  • action(type="omfile" file="/var/log/remote-514.log") – inside the ruleset, this action writes all messages to /var/log/remote-514.log.

After saving the file, restart rsyslog:

sudo systemctl restart rsyslog

Now all remote syslog traffic on UDP/514 will be stored in /var/log/remote-514.log, which you can later parse with Fail2Ban.

6.2 Create a Fail2Ban Jail Template for Syslog Traffic

Add this jail to your /etc/fail2ban/jail.local file (below the SSH jail):

[rsyslog-remote] 
enabled = false 
filter = rsyslog-remote 
logpath = /var/log/remote-514.log 
maxretry = 100 
findtime = 600 
bantime = 1h 
backend = auto

Line by line:

  • [rsyslog-remote] – defines a new jail named rsyslog-remote.
  • enabled = false – disables the jail for now. You will enable it later when your filter is ready.
  • filter = rsyslog-remote – tells Fail2Ban to use a filter definition from /etc/fail2ban/filter.d/rsyslog-remote.conf.
  • logpath = /var/log/remote-514.log – points the jail at the log file created by your rsyslog ruleset.
  • maxretry = 100 – allows up to 100 matching log entries within the findtime window before banning.
  • findtime = 600 – 600 seconds is 10 minutes; Fail2Ban looks at this time window.
  • bantime = 1h – bans a misbehaving client IP for one hour.
  • backend = auto – lets Fail2Ban auto-detect the best backend for reading the log file.

To activate this jail safely, you need a well-defined filter that matches only truly problematic patterns. This depends heavily on your environment, so by default we keep it disabled.

Step 7: Restart Fail2Ban and Verify Jails

After editing jail.local, restart Fail2Ban to apply the changes:

sudo systemctl restart fail2ban 
sudo systemctl status fail2ban

Explanation:

  • sudo systemctl restart fail2ban – reloads the configuration and restarts the Fail2Ban service.
  • sudo systemctl status fail2ban – shows the current status so you can confirm that it is running and there are no errors.

To see active jails:

sudo fail2ban-client status

This will list all jails and show which ones are currently enabled. For SSH details:

sudo fail2ban-client status sshd

You should see a list of currently banned IP addresses (if any) and basic statistics for the jail.

Step 8: Testing Your Hardened Syslog Server

After configuring UFW and Fail2Ban, it is important to test both legitimate and blocked scenarios.

  • Test SSH from a trusted admin IP – confirm that you can still log in via SSH.
  • Test syslog from allowed networks – from a trusted client, send a test log message and verify it appears in your rsyslog logs.
  • Test blocked access – from an untrusted IP (or a test machine outside allowed subnets), try connecting to UDP/514 or SSH and confirm that the connection is denied.
  • Simulate failed SSH logins – from a test machine, intentionally enter wrong SSH credentials multiple times and watch Fail2Ban ban the IP:
sudo tail -f /var/log/fail2ban.log

You should see log entries indicating that the IP has been banned for the configured bantime.

Conclusion

By combining UFW and Fail2Ban, you have significantly hardened your Debian 13 rsyslog server:

  • Only trusted networks can send logs to your syslog ports.
  • SSH is restricted to specific IPs or subnets and protected by Fail2Ban.
  • Optional integration with dedicated syslog logs allows you to detect and block noisy or malicious clients.

This setup keeps your logging infrastructure minimal, secure and maintainable. As your environment grows, you can extend the same pattern to other services on this server or use the same approach on additional log collectors.

If you want to go further, consider adding TLS-encrypted syslog traffic, central log analysis tools (like ELK or Loki), and more advanced Fail2Ban filters tailored to your specific applications.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.