Introduction

Open your Proxmox VE host's logs sometime and search for failed logins. If your server is reachable from the internet at all — even just SSH on a non-standard port — you'll probably find dozens or hundreds of attempts from IPs you've never heard of, all trying random usernames and passwords. This isn't personal. It's automated bots crawling the entire internet, all day, every day, looking for exactly this.

Strong passwords help. Two-factor authentication helps more. But there's a simpler layer that catches the noise before it becomes a real problem: automatically banning an IP address the moment it starts guessing. That's what fail2ban does, and it takes about ten minutes to set up on a Proxmox VE host.

What You Will Learn

  • What fail2ban actually does and how it decides to ban an IP
  • How to install it on Proxmox VE and set up a jail for the web interface (pveproxy/pvedaemon) and for SSH
  • How to test that your filter is actually catching failed logins before you trust it
  • How to check banned IPs, unban yourself if you get locked out, and whitelist your own network
  • Common mistakes that leave a jail silently doing nothing

What Is This Feature?

Fail2ban is a small service that watches log activity — either traditional log files or, on modern systemd-based systems like Proxmox VE 8 and 9, the systemd journal directly — and looks for a pattern that means "this login attempt failed."

When it sees that pattern happen too many times from the same IP within a set time window, it tells the host's firewall to drop all further traffic from that IP for a while. No human has to be watching. It just quietly does its job in the background.

A few terms you'll see repeatedly once you start configuring it:

  • Jail — the configuration block for one service you want protected, like SSH or the Proxmox web UI. Each jail pairs a filter with an action (usually "ban this IP").
  • Filter — the actual pattern (a regular expression) used to recognize a failed login line in the logs.
  • Backend — where fail2ban reads its logs from. On Proxmox VE 8/9 you'll almost always use the systemd backend, which reads straight from the journal instead of a flat log file.

Why Would You Use It?

If your Proxmox host only has SSH and the web UI reachable from your own LAN, and nothing forwarded from your router, your actual exposure is low and fail2ban is more of a nice-to-have. If you've forwarded port 8006 or 22 straight to the internet, or you're renting a dedicated server with a public IP, it's a lot closer to necessary.

I'll be honest about the limits here too: fail2ban doesn't stop a targeted attacker with unlimited IPs, and it won't fix the underlying problem if you're exposing the web UI directly to the internet in the first place — a VPN like WireGuard is the better fix for that. What fail2ban is really good at is drowning out the constant background noise of opportunistic bots, so your logs stay readable and a lucky guess doesn't get unlimited attempts.

Prerequisites

  • Root access to your Proxmox VE host, either via SSH or the web UI's Shell console.
  • Proxmox VE 8.x or 9.x (both run on systemd, so the steps below apply to either). If you're somehow still on PVE 6 or 7, you'll need the older rsyslog-based logpath instead of the systemd backend — a quick web search for your exact version will get you the equivalent syntax.
  • A working internet connection on the host so apt can fetch the package.
  • About ten minutes, plus a second device or connection you can use to safely test a failed login without locking yourself out of your only session.

Step-by-Step Tutorial

Step 1: See what you're actually dealing with

Before installing anything, take a quick look at how much attention your host is already getting. If SSH is exposed, check recent failures:

journalctl -u sshd --since "1 hour ago" | grep -i fail

For the Proxmox login service:

journalctl -u pvedaemon --since "1 hour ago" | grep -i "authentication failure"

Don't be surprised if you see nothing on a LAN-only box, or a steady trickle if you're on a public IP. Either way, now you have a baseline to compare against later.

Step 2: Install fail2ban

apt update
apt install fail2ban

This pulls in fail2ban and its dependencies. On Debian-based systems (which Proxmox VE is), it comes with a working systemd-journal reader out of the box, so there's no extra package needed for the backend we're using.

Step 3: Create your local jail config

Never edit jail.conf directly — it gets overwritten on package updates, and your changes would vanish with it. Copy it to jail.local instead, which fail2ban always reads on top of the defaults:

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Step 4: Add a jail for the Proxmox web interface

Open the new file:

nano /etc/fail2ban/jail.local

Scroll to the bottom and add this block:

[proxmox]
enabled = true
port = https,http,8006
filter = proxmox
backend = systemd
maxretry = 3
findtime = 2d
bantime = 1h

That's a ban after 3 failed attempts inside a 2-day window, lasting one hour. It's a reasonable starting point — tight enough to actually deter bots, loose enough that a couple of typos on your own end won't lock you out for long. Save and exit (Ctrl+O, Enter, Ctrl+X in nano).

Step 5: Create the filter that recognizes a failed Proxmox login

The jail above references a filter called proxmox, which needs its own file:

nano /etc/fail2ban/filter.d/proxmox.conf

Paste in:

[Definition]
failregex = pvedaemon\[.*authentication failure; rhost= user=.* msg=.*
ignoreregex =
journalmatch = _SYSTEMD_UNIT=pvedaemon.service

This tells fail2ban exactly which journal entries from the pvedaemon service count as a failed login, and which part of that line contains the offending IP address (the <HOST> placeholder).

Step 6: Restart fail2ban and check it loaded correctly

systemctl restart fail2ban
systemctl enable fail2ban
fail2ban-client status

You should see proxmox listed alongside sshd in the list of jails (sshd is usually enabled by default in jail.conf already). If proxmox isn't listed, there's a syntax problem in one of the two files you just edited — check Step 8 below.

Step 7: Test the filter without waiting for a real attacker

fail2ban-regex systemd-journal /etc/fail2ban/filter.d/proxmox.conf

This runs your filter against the actual journal on the host and tells you how many matching lines it found. If you've had any failed logins recently, you'll see a non-zero match count here. If you want a clean test, open the Proxmox login page in an incognito window and deliberately enter a wrong password three times, then re-run the command.

Step 8: Confirm the ban actually happened

fail2ban-client status proxmox

This shows the current failed-attempt count and any currently banned IPs for that jail specifically. If you triggered a test ban from your own IP, you'll see it listed here — which is your cue to unban yourself before you get locked out of the web UI too:

fail2ban-client unban YOUR_IP_ADDRESS

Commands Explained

CommandWhat it does
fail2ban-client statusLists every active jail, so you can confirm your config actually loaded.
fail2ban-client status proxmoxShows details for one specific jail: total failures seen and any IPs currently banned.
fail2ban-regexRuns a filter against real log data without banning anyone, purely to check your regex actually matches.
fail2ban-client unban <ip>Immediately removes a ban for the given IP across jails, useful if you or a teammate gets caught by mistake.
systemctl restart fail2banReloads fail2ban with your latest config changes. Required every time you edit jail.local or a filter file.

Common Errors

  • Jail "proxmox" not found when running fail2ban-client status proxmox — the jail block wasn't saved correctly, or you forgot enabled = true. Re-check the indentation and spelling in jail.local.
  • fail2ban-regex reports 0 matches even though you know logins failed — almost always a typo in the failregex line, or the wrong service name in journalmatch. Confirm the exact unit name with systemctl status pvedaemon.
  • You locked yourself out — this happens to almost everyone once. If it's your own IP that got banned, you'll need another way in: a different network, your phone's hotspot, or physical/IPMI console access to run the unban command.
  • Package install fails with unmet dependencies — run apt update again first. This usually means your repository configuration needs attention before fail2ban's dependencies can resolve.

Troubleshooting

If jails show as enabled but nothing ever gets banned, start by confirming fail2ban is actually reading the journal at all. Run journalctl -u fail2ban -n 50 and look for errors about the backend on startup — a misconfigured backend line is the most common silent failure.

If IPv6 addresses seem to slip through a ban, check that allowipv6 is set appropriately for your fail2ban version; some older builds only track IPv4 by default, which matters if your host has a public IPv6 address alongside IPv4.

And if you're worried about banning yourself permanently while testing, add your own trusted IP or subnet to the ignoreip line in the [DEFAULT] section of jail.local before you start experimenting:

ignoreip = 127.0.0.1/8 ::1 203.0.113.10

Replace 203.0.113.10 with your actual home or office IP. Anything listed there is never banned, no matter how many times it fails a login.

Best Practices

Don't rely on fail2ban as your only line of defense. It's a good second layer, not a replacement for not exposing the web UI directly to the internet in the first place — put it behind a VPN if you can, and use SSH keys instead of passwords wherever possible.

Keep the SSH jail enabled too, not just the Proxmox one. It's usually on by default in jail.conf, but double-check with fail2ban-client status after your first install.

Review banned IPs occasionally with fail2ban-client status proxmox. A sudden spike in ban counts is a useful early signal that your host has become a more visible target than it used to be, which might be worth investigating on its own.

Resist the urge to set maxretry to 1 out of paranoia. It sounds stricter, but it also means a single mistyped password locks you out for the full ban duration. Three attempts is a sane middle ground for most people.

Frequently Asked Questions

Does fail2ban replace the Proxmox firewall?

No. The built-in Proxmox firewall controls which ports and IPs can reach your host at all. Fail2ban works after that, reacting to failed logins on services that are already reachable.

Will I get banned for mistyping my own password a couple of times?

Only if you hit the maxretry threshold within the findtime window — three tries in two days with the config above. Two typos won't trigger anything.

Does this protect SSH as well as the web interface?

Yes, as two separate jails. The sshd jail (usually already enabled in jail.conf) handles SSH, and the proxmox jail you just added handles the web UI and API logins.

Is fail2ban installed by default on Proxmox VE?

No, it's not part of the base install. You have to install it yourself with apt install fail2ban, which is exactly what we did above.

Can I make a ban permanent instead of one hour?

Yes, set bantime = -1 in the jail block for a permanent ban. I'd be cautious with that on a dynamic-IP home connection, though — you could end up banning a future legitimate visitor who inherits that IP later.

Conclusion

Fail2ban won't stop a determined, targeted attacker, and it's not a substitute for good passwords, SSH keys, or keeping your management interface off the open internet. What it does well is handle the constant, boring background noise of bots trying default credentials against every IP they can find — and on a Proxmox host with any internet exposure at all, that noise is more common than most people expect. Ten minutes of setup now saves you from ever having to think about it again.