Enabling Fail2Ban
Harden your setup against intrusions with Fail2Ban
To harden both the SSH port and the web interface of your Proxmox VE standalone server further, install the intrusion prevention Fail2Ban tool to protect those interfaces from anomalous login attempts trying to brute-force their way into your system.
Installing Fail2Ban
Login with mgrsys, and execute the apt install command:
$ sudo apt install -y fail2banConfiguring Fail2Ban
The usual method for configuring Fail2Ban is by making a .local version of the /etc/fail2ban/jail.conf file and just editing that version. This way, you have all your particular Fail2Ban rules in one file. But, if you want to separate concerns in different files, you can do it by creating a file per concern under the /etc/fail2ban/jail.d folder.
Configuring the jail for the SSH service
Open a shell with your
sudouser (mgrsysin this guide),cdto/etc/fail2ban/jail.dand create an empty file called01_sshd.conf:$ cd /etc/fail2ban/jail.d $ sudo touch 01_sshd.confEdit the
01_sshd.conffile by inserting the configuration lines below:[sshd] enabled = true backend = systemd port = 22 maxretry = 3Regarding the configuration above:
[sshd]
Identifies the service this jail is applied to.enabled
Enables the jail for thesshdservice. This line is also present in the/etc/fail2ban/jail.d/defaults-debian.conf.backend
The Debian Linux where Proxmox VE comes installed is systemd-based, which means that many of the traditional logs you could use with Fail2Ban to detect attacks have been replaced by the Journal logging system. Hence, you have to enable thesystemdbackend so Fail2Ban can access the logs it needs to monitor to do its job.port
Should be the same as the one you’ve configured for yoursshdservice. In this guide’s PVE setup is the standard SSH one.maxretry
Number of failed authentication attempts allowed before applying a ban to an IP. Remember to make it the same as theMaxAuthTriesin yoursshdconfiguration, so they correlate.
Save the changes and restart the Fail2Ban service:
$ sudo systemctl restart fail2ban.service
Testing the sshd jail configuration
To test the jail configuration for the SSH service, you should provoke a ban:
Use another computer for this test if you can. This is to avoid banning the client system from which you usually connect to your Proxmox VE server.
Try to connect through SSH with a non-existing test user, until you use up the attempts allowed in your configuration.
With the default configuration, the ban time lasts 3600 seconds (one hour).
After the banning time is over, the banned IP will be unbanned automatically.
In your server, check the
/var/log/fail2ban.log. At the end of the file you should find as the most recent lines the logs indicating what has happened with the banned IP:2025-08-27 16:43:52,822 fail2ban.filter [2825]: INFO [sshd] Found 10.3.0.1 - 2025-08-27 16:43:52 2025-08-27 16:44:17,117 fail2ban.filter [2825]: INFO [sshd] Found 10.3.0.1 - 2025-08-27 16:44:17 2025-08-27 16:44:17,117 fail2ban.filter [2825]: INFO [sshd] Found 10.3.0.1 - 2025-08-27 16:44:17 2025-08-27 16:44:17,521 fail2ban.actions [2825]: NOTICE [sshd] Ban 10.3.0.1 ... 2025-08-27 17:44:17,532 fail2ban.actions [2825]: NOTICE [sshd] Unban 10.3.0.1The configuration allows three login attempts through SSH, which correspond with the three
INFOlines shown in the log output above. After them, you can see the firstNOTICEline of the same attempting IP being banned. The finalNOTICElog line corresponds to the unbanning of the IP after one hour.
Configuring the Proxmox VE jail
cdto/etc/fail2ban/jail.dand create an empty file called02_proxmox.conf:$ cd /etc/fail2ban/jail.d $ sudo touch 02_proxmox.confEdit the
02_proxmox.conffile by inserting the configuration lines below:[proxmox] enabled = true port = https,http,8006 filter = proxmox backend = systemd maxretry = 3 findtime = 2d bantime = 1hRegarding the configuration above:
[proxmox]
Identifies the service this jail is applied to.enabled
Enables the jail for theproxmoxservice.backend
Indicates Fail2Ban the system where to find the logging information it needs to run, in this casesystemd.port
Lists all the ports that your Proxmox VE platform is currently using.filter
Specifies which filter to use to look for failed authentication attempts in the PVE platform.maxretry
Number of failed authentication attempts allowed before applying a ban to an IP.findtime
Time window Fail2Ban will monitor for repeated failed login attempts. In the configuration used in this guide, it will take into account all the attempts that happened in the last two days.bantime
Indicates how long the ban should last for any banned IP.
cdto/etc/fail2ban/filter.dand create an empty file calledproxmox.conf:$ cd /etc/fail2ban/filter.d $ sudo touch proxmox.confEdit the
proxmox.conffile by inserting the configuration lines below:[Definition] failregex = pvedaemon\[.*authentication failure; rhost=<HOST> user=.* msg=.* ignoreregex = journalmatch = _SYSTEMD_UNIT=pvedaemon.serviceThe
[Definition]above establishes the filtering pattern to detect anomalous attempts at login into the Proxmox VE system:failregex
To specify the regular expressions that help detect in the Proxmox VE log the anomalous authentication attempts.ignoreregex
To set the regular expressions for detecting false positives, in case they are known to happen.journalmatch
Indicates thesystemdservice to monitor in the Journal logs. In this case is Proxmox VE’s daemon.
Save the changes and restart the Fail2Ban service:
$ sudo systemctl restart fail2ban.service
Testing the Proxmox VE jail configuration
To test the configuration, you should provoke a ban:
For this test use another computer if you can, to avoid banning your usual client system from where you connect to your Proxmox VE server.
Then try to log in the PVE web console, with a non-existing test user, until you use up the attempts allowed in your configuration.
When your IP is banned, you will see that your browser is not be able to connect with the PVE web console at all.
After the banning time is over, the banned IP will be unbanned automatically.
In your server, check the
/var/log/fail2ban.log. At the end of the file you should find the lines that indicate you what happened with the banned IP:2025-08-27 16:58:49,881 fail2ban.filter [5927]: INFO [proxmox] Found 10.3.0.1 - 2025-08-27 16:58:49 2025-08-27 16:58:55,690 fail2ban.filter [5927]: INFO [proxmox] Found 10.3.0.1 - 2025-08-27 16:58:55 2025-08-27 16:59:00,107 fail2ban.filter [5927]: INFO [proxmox] Found 10.3.0.1 - 2025-08-27 16:58:59 2025-08-27 16:59:00,647 fail2ban.actions [5927]: NOTICE [proxmox] Ban 10.3.0.1 ... 2025-08-27 17:59:00,653 fail2ban.actions [5927]: NOTICE [proxmox] Unban 10.3.0.1The configuration for accessing Proxmox VE allows three attempts, which correspond with the three
INFOlines shown in the log snippet above. After them, you can see the firstNOTICEwarning of the same attempting IP being banned. The lastNOTICEentry informs you of the unbanning of the IP after one hour.
Considerations regarding Fail2Ban
First, to know more about how to configure fail2ban, check the manual for jail.conf:
$ man jail.confFail2Ban client
Fail2Ban comes with the fail2ban-client program to monitor its status. For instance, after applying the configuration explained in this guide, you would see the following:
$ sudo fail2ban-client status
Status
|- Number of jail: 2
`- Jail list: proxmox, sshdAlso, you can also check each jail independently with fail2ban-client:
$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- Journal matches: _SYSTEMD_UNIT=ssh.service + _COMM=sshd
`- Actions
|- Currently banned: 0
|- Total banned: 1
`- Banned IP list:$ sudo fail2ban-client status proxmox
Status for the jail: proxmox
|- Filter
| |- Currently failed: 0
| |- Total failed: 3
| `- Journal matches: _SYSTEMD_UNIT=pvedaemon.service
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 10.3.0.1On the other hand, fail2ban-client can also be used to handle the underlying Fail2Ban server. It is the fail2ban-server daemon that monitors the system logs.
Fail2Ban configuration files are read in order
The Fail2Ban configuration files are read in a particular order: first the .conf files, then the .local ones. And the configuration files within the .d/ folders are read in alphabetical order. So, the reading order for the jail files would be:
jail.confjail.d/*.conf(in alphabetical order)jail.localjail.d/*.local(in alphabetical order)
Fail2Ban uses nftables to enforce the bans
Fail2Ban monitors the log files of the services you tell it to and, if it detects banneable IPs under the criteria of its configuration, it will block any offending IP with the nftables firewall integrated in your Proxmox VE server. The rules applied through nftables can be seen with the nft command:
First, you must get the name of the table where the Fail2Ban rules are kept:
$ sudo nft list tables table inet f2b-tableNotice that there is only one table active in the
nftablesfirewall, the one for Fail2Ban:table
Just indicates that the object listed in the output is a table of rules.inet
Indicate to which address family the rules apply. In this case the rules of the table only apply to IPv4 addresses.f2b-table
The name of the Fail2Ban (f2b) table.
Once you know the family and name of the Fail2Ban table, you can see the rules in it with the
nftcommand:$ sudo nft list table inet f2b-table table inet f2b-table { set addr-set-sshd { type ipv4_addr } set addr-set-proxmox { type ipv4_addr elements = { 10.3.0.1 } } chain f2b-chain { type filter hook input priority filter - 1; policy accept; tcp dport 22 ip saddr @addr-set-sshd reject with icmp port-unreachable tcp dport { 80, 443, 8006 } ip saddr @addr-set-proxmox reject with icmp port-unreachable } }The output reveals both sets of banned addresses and the chains of rules applied:
The
addr-set-sshdandaddr-set-proxmoxsets each correspond to one of the jails enabled in Fail2Ban. Notice how in theaddr-set-proxmoxthere is already one IP included in the set, meaning that nftables has blocked its access to the Proxmox VE server ports.The
f2b-chainblock contains the rules that block access to the sshd and Proxmox VE servers to banned IPs.
Manual banning or unbanning of IPs
You can manually unban an IP with the following command:
$ sudo fail2ban-client set <jail> banip/unbanip <ip address>Notice how you have to specify on which <jail> you want to place a ban or lift it. An example of unbanning an IP from the sshd jail would be like this:
$ sudo fail2ban-client set sshd unbanip 10.3.0.1
1Notice that the unbanip command will return a number that indicates how many IPs have been unbanned. In the example, just one has been releases from the sshd jail.
Checking a jail’s filter
The filter of a jail is just a regular expression that weeds out from a given log the lines that indicates to Fail2Ban if an IP should be banned.
To check that the regular expression of a jail’s filter works, you have to use the fail2ban-regex command:
fail2ban-regex [/path/to/log.file | systemd-journal] /path/to/fail2ban/filter/configuration.fileNotice that you can test any filter against any log file, or the systemd Journal. For instance, if you were to check the proxmox filter previously explained in this guide, you would do this:
$ sudo fail2ban-regex systemd-journal /etc/fail2ban/filter.d/proxmox.confThe output of the command above should be something like the following:
Running tests
=============
Use filter file : proxmox, basedir: /etc/fail2ban
Use systemd journal
Use encoding : UTF-8
Use journal match : _SYSTEMD_UNIT=pvedaemon.service
Results
=======
Failregex: 8 total
|- #) [# of hits] regular expression
| 1) [8] pvedaemon\[.*authentication failure; rhost=<HOST> user=.* msg=.*
`-
Ignoreregex: 0 total
Lines: 356 lines, 0 ignored, 8 matched, 348 missed
[processed in 0.14 sec]
Missed line(s): too many to print. Use --print-all-missed to print all 348 linesNotice how the fail2ban-regex command reports a total of eight matches in the Failregex line.
Relevant system paths
Directories
/etc/fail2ban/etc/fail2ban/filter.d/etc/fail2ban/jail.d
Files
/etc/fail2ban/filter.d/proxmox.conf/etc/fail2ban/jail.d/01_sshd.conf/etc/fail2ban/jail.d/02_proxmox.conf