> ## Content Index
> Fetch the complete content index at: https://www.ctrl.blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# How to protect SSH logins in Fedora Linux with SSHGuard and FirewallD
- URL: https://www.ctrl.blog/entry/how-to-sshguard-firewalld/
- Published: 2017-03-08T10:12:00.000Z
- Updated: 2026-08-23T22:11:01.000Z
- Description: Protect your Fedora/CentOS Linux-system against SSH brute-force credential-guessing with SSHGuard security log parser and the FirewallD firewall.
- Author: Daniel Aleksandersen
- Tags: Linux, Networking, Security

[SSHGuard 2](https://www.ctrl.blog/entry/sshguard2/) introduced a new FirewallD backend that makes it easier to work with in Linux distributions that use FirewallD tools. Here is how you install and configure SSHGuard on a distribution with FirewallD (like Fedora Linux, CentOS, RHEL.)

You can reduce the number of scripted attacks against SSH significantly by [changing the default port number](https://www.ctrl.blog/entry/how-to-alternate-ssh-port-fedora/). Obscuring where the SSH service is accessed shouldn’t be your only line of defense, however. This is where SSHGuard comes in: it will add the IP addresses of repeated attackers to the system firewall to drop the connections before they even reach your SSH service.

#### Contents

1. [Build and install](#sshguard-section-install)
2. [Configuring SSHGuard](#sshguard-section-config)
3. [Configuring your FirewallD zone](#sshguard-section-firewalld)
4. [Starting the service](#sshguard-section-service)
5. [Test and verify](#sshguard-section-verify)

### Build and install

SSHGuard isn’t packaged for Fedora Linux yet (I’ll see what I can do about that), so you’ll have to compile and install it yourself. Luckily, that isn’t a very complicated process so you should have SSHGuard up and running on your system in a few minutes by following this tutorial.

Start by installing the build dependencies using the below command. If you’re using Ubuntu or another distribution, you’ll find the appropriate `apt` command in the `INSTALL` file. You can follow along in this tutorial even if you don’t use Fedora Linux, but choose the appropriate firewall backend for your distribution.

```shell
dnf install byacc flex gcc make wget
```

Next, you need to download and uncompressed the source from the latest release tarball from [SourceForge](https://sourceforge.net/projects/sshguard/files/sshguard/?ref=ctrl.blog). The example commands below downloads [version 2.1](https://www.ctrl.blog/entry/sshguard2p1/), extracts it from the package, and changes the working directory to the source directory.

```shell
wget "https://sourceforge.net/projects/sshguard/files/sshguard/2.1.0/sshguard-2.1.0.tar.gz"
tar -xzf sshguard-2.1.0.tar.gz
cd sshguard-2.1.0/
```

Make sure you get the latest release version. Once you’ve got your very own copy of the source code from the release tarball, you can proceed to configure and build SSHGuard:

```shell
./configure --prefix="/usr/local/"
make
```

Unless you see error messages, you should be ready to install the final program as well as some example configuration resources. The following commands needs to be executed as root, and will copy the files you need to where they need to go:

```shell
make install
cp ./examples/sshguard.conf.sample /usr/local/etc/sshguard.conf
cp ./examples/sshguard.service /etc/systemd/system/
```

### Configuring SSHGuard

The example configuration file has enough inline documentation to guide you through the required configuration options. You’ll only need to configure the `BACKEND` and `LOGREADER` options. For Fedora Linux, we’ll work with FirewallD as the firewall backend and systemd journal as the log reader. Make the following changes in `/usr/local/etc/sshguard.conf`:

```ini
BACKEND="/usr/local/libexec/sshg-fw-firewalld"
LOGREADER="LANG=C /usr/bin/journalctl -afb -p info -n1 -t sshd -o cat"
```

All those `journalctl` switches tells the journal to pipe out all messages from the `sshd` process with priority info or higher with basic formatting (`syslog`\-like.)

You can look through the other configuration options in the file to see if you want to make any other changes. You may want to double the `DETECTION_TIME` code if you’re experiencing slow-paced brute-force attacks.

Next, you’ll need to make one small change in the systemd unit service file to account for the installation prefix we made during the build process. Change the `ExecStart` option in `/etc/systemd/system/sshguard.service` to the following:

```ini
ExecStart=/usr/local/sbin/sshguard
```

As you’re all done configuring the systemd unit file for SSHGuard, run the following command to let systemd know that there’s a new unit file:

```shell
systemctl daemon-reload
```

### Configuring FirewallD zone

The FirewallD backend in SSHGuard relies on the ipset feature of iptables. Blocked attackers are added to either the `sshguard4` for IPv4 or `sshguard6` for IPv6 ipsets. Additionally, SSHGuard will add a firewall rule to FirewallD that tells it to drop connections from any source IP found in either one of these ipsets.

By default, SSHGuard’s drop-rule will be added to the default FirewallD zone. Depending on your firewall zone configuration, you may want to add additional drop rules to other zones. If you only use the default `public` zone **then no further configuration is needed.** The following command would add the default rule to the `home` zone:

```shell
firewall-cmd --permanent --zone="home" --add-rich-rule="rule source ipset=sshguard4 drop"
firewall-cmd --permanent --zone="home" --add-rich-rule="rule source ipset=sshguard6 drop"
firewall-cmd --reload
```

You can inspect the blocked entries in each ipset using the following commands:

```shell
firewall-cmd --permanent --info-ipset="sshguard4"
firewall-cmd --permanent --info-ipset="sshguard6"
```

You can unblock a blocked attacker, in this example `10.10.1.10`; using the following command:

```shell
firewall-cmd --ipset="sshguard6" --permanent --remove-entry="10.10.1.10"
```

Note that SSHGuard’s two ipsets are deleted when SSHGuard flushes its own firewall rules (on exit.) This may cause a problem if FirewallD rules are loaded when the ipsets don’t exist yet. To work around this, you can either add the creation of these two ipsets to your permanent FirewallD configuration or you may want to take more control of SSHGuard’s FirewallD backend script. You can copy and modify the `sshg-fw-firewalld` script (it’s an easy to follow bash script) and configuring the `BACKEND` option to use your custom firewall backend.

### Starting the service

Now that SSHGuard is installed and configured, you can start the service and check up on it’s status with these commands:

```shell
systemctl start sshguard
systemctl status sshguard
```

Verify that it says `active (running)` in the output and that you don’t have any errors or warnings in the log output.

To have SSHGuard start at systemboot, run one last command:

```shell
systemctl enable sshguard
```

### Test and verify

At this point SSHGuard should be installed, configured, and protecting your machine. But how can you be sure that it’s working? Run the following command to follow the systemd journal log entries from sshd and sshguard:

```shell
journalctl -ef -t sshguard -t sshd
```

From another machine (or at least IP), try to login to the protected system over SSH using invalid credentials. On the protected system you should see log entries from both SSHGuard and SSH about the unsuccessful login attempts.

Continue the login attempts with invalid credentials until it stops working, and look in the log output. It should say that the IP was blocked and for how long. If you want for the block duration timeout to expire, and then continue to attempt more logins you should see that the block time gets doubled.

You should see login attempts to `sshd` and log messages from SSHGuard like “Attack from "client8.homenet.example.com" on service 100 with danger 10.” After five attacks sshguard should block the attacker with an error saying “Blocking "client8.homenet.example.com" for 600 secs (3 attacks in 75 secs, after 1 abuses over 75 secs.)”

You can repeat the test and first use the `ssh -4` switch and then repeat the test with the `ssh -6` switch when attempting to pretend login to your protected system to verify that both IPv4 and IPv6 protections are working.

You can tweak the `BLOCK_TIME` and `DETECTION_TIME` duration options in `sshguard.conf` to your liking. Note that the `BLOCK_TIME` is doubled on every subsequent block per source IP.

Reboot the system and repeat the test.

If you’ve accidentally locked yourself out, you can find the commands for releasing yourself from the block in the FirewallD section above.