Back to Article List

Secure Webmin with Fail2ban, 2FA and restricted access

Secure Webmin with Fail2ban, 2FA and restricted access

Updated and tested 23 September 2026

"Is Webmin safe" gets asked on forums about once a week and gets answered with opinion. The vendor's own advisory list is a better source. Read the 2026 entries and the answer is something you can plan around. Patch first and keep port 10000 private; Fail2ban and two-factor login only matter after that.

A Webmin login is root by another name. Anyone who gets in can edit /etc/shadow, install packages, rewrite a firewall and run commands as root, so the login page deserves the treatment you give SSH. Most of what follows is about reducing the number of people who can see that page at all.

Does Webmin belong on an internet-facing server

Yes, on two conditions: a current version, and a network path that does not include the entire internet. Webmin is under active development and its release cadence through 2026 has been close to monthly. The advisory list keeps growing because people keep looking, which is the state you want a panel to be in.

The counter-argument is scope. Webmin writes configuration files for daemons it does not own, so its attack surface is roughly the union of every module installed. The Webmin and Cockpit comparison lays out the trade-offs, and if all you need is service status, storage, journals and a terminal, a smaller tool is a smaller target. Plenty of people need the DNS zone editor and the Postfix module, and for them the answer is to run Webmin properly.

Patch on the monthly cadence

Webmin was at 2.670 when this guide was tested, released on 20 September 2026. The releases before it: 2.630 in March, 2.640 and 2.641 in May, 2.650 and 2.651 in June, 2.652 and 2.653 in July, 2.660 in August. Point releases land often and some of them are security releases.

The 2026 entries on the Webmin security advisory list, ordered by the release that fixed them. The last one is the odd entry out, because its advisory points to 2.301, a version long before the rest:

  • Prior to 2.640, two factor authentication could be bypassed using HTTP basic authentication, tracked as CVE-2026-42210 and CVE-2026-56022. Accounts with 2FA switched on were reachable without the second factor.
  • Prior to 2.640, the Help feature allowed privilege escalation, letting untrusted users run commands as root regardless of what module access they had been granted.
  • Prior to 2.640, the Read User Mail module had an XSS flaw through SVG attachments, CVE-2026-49102, and a file overwrite when detaching attachments, CVE-2026-49103.
  • Prior to 2.641, the System and Server Status module carried a stored cross-site scripting flaw in its notification email templates, CVE-2026-22678, usable by a user with template permissions to compromise root.
  • Prior to 2.650, a reflected cross-site scripting flaw, CVE-2026-49243.
  • Prior to 2.652, server-side request forgery in the Upload and Download and File Manager modules, CVE-2026-102337, open to untrusted users who have download access.
  • Prior to 2.653, users with limited access to several service modules (DHCPd, MySQL, PostgreSQL, Nginx and Squid among them) could restart servers or edit configuration that their ACL denied.
  • Prior to 2.670, the Custom Commands module let an untrusted user who can run commands with parameters execute arbitrary commands as root. Commands without parameters are not affected.
  • CVE-2026-56020, SSL client certificates trusted when they shouldn't be, on a Webmin set to trust client IPs supplied by a proxy. The advisory says to upgrade to 2.301 or later, and the setting involved is Trust level for proxy headers under IP Access Control.

Two of the first three defeat a control you had already configured. Enabling 2FA on a box running 2.63x bought you a login prompt and no second factor. Restricting a junior admin to three modules on the same version bought you a list that the Help feature ignored. Configuration is not a substitute for a current version, and patching comes before everything else here.

Updates come through the package manager the repo already set up, so apt-get update && apt-get install --only-upgrade webmin on Debian and Ubuntu, or dnf upgrade webmin on the RHEL family. There is an Upgrade Webmin page under Webmin Configuration that does the same thing. On a box I am not logging into weekly, Webmin goes into unattended upgrades and the release notes get read when something breaks, which so far it has not.

Keep port 10000 off the open internet

A panel on 0.0.0.0:10000 gets found within hours by mass scanners, and from then on every authentication weakness in every version you ever run is a race between the advisory and the exploit. This is the change with the largest effect and it costs nothing. Three ways to do it, in order.

Reach Webmin over a VPN

Put WireGuard on the server and bind Webmin to the VPN interface address. Webmin becomes invisible to anything that is not already a peer, and access control turns into key management: onboarding is a peer entry, offboarding is a deletion, and neither one happens under time pressure with a firewall rule half-edited in another tab. For a team with more than one administrator, nothing else comes close.

An SSH tunnel to 127.0.0.1

Bind Webmin to 127.0.0.1 and forward the port over a session you already have open:

ssh -L 8443:127.0.0.1:10000 admin@YOUR_SERVER_IP

curl to https://127.0.0.1:8443 through the SSH tunnel returns HTTP 200

Through the tunnel, Webmin answers on the laptop's 127.0.0.1:8443.

Then browse to https://127.0.0.1:8443. The public interface answers nothing at all, and the SSH key you already protect becomes the only credential that matters. It scales badly to a team. The certificate will never match a loopback address, which is a name mismatch warning and not a fault.

An IP allowlist in Webmin

Webmin's IP Access Control page, the first entry in the Webmin Configuration module, writes the allow and deny keys in /etc/webmin/miniserv.conf. The module documentation describes choosing the Only allow from listed addresses option and typing the hostnames, IP addresses or networks into the box beside it. A firewall rule in front of it, at the host and at the provider's network layer, does the same job earlier and better.

Keep both. The Webmin port and IP access control guide has the firewall syntax for each distro, and the miniserv check still applies on the day a firewall rule gets clobbered by a package update. Neither one survives a dynamic residential address changing overnight.

Moving off the default port

Moving off 10000 is overrated as hardening, and it is not a control. Scanners sweep 10000 constantly, so a panel on 8443 sees a fraction of the traffic and the authentication log becomes short enough that somebody reads it, which is the entire benefit and it is a real one. Anyone targeting your server specifically finds the new port in a single scan, and the port number changes nothing about what happens after that. Do it for the log volume. It does not stand in for the previous section, and treating it as security is how people end up with an exposed panel they feel good about.

Give Webmin a certificate the browser trusts

The install ships a self-signed certificate, so the first login throws a warning. The walkthrough on Webmin SSL certificates covers replacing it through the SSL Provider tab, which takes a few minutes. On a tunnelled panel the security value of that is small. The value in not conditioning yourself to click through certificate warnings is not small at all, and that habit is what eventually costs you.

Two factor authentication

Webmin Configuration, then Two Factor Authentication, then enable a provider and enrol each account. Two providers ship with Webmin.

TOTP Authenticator

Standard TOTP, so Google Authenticator or any other authenticator app works and nothing leaves the server during a login. Older guides call this provider Google Authenticator; on 2.670 the drop-down says TOTP Authenticator. Enable this one. Saving it shows a green box telling you to enrol in the Webmin Users module, where each account gets an Enroll For Two-Factor Authentication button. I stopped at that button when testing this guide, because the next step needs the phone, so I can't vouch for the enrolment screen itself. The documentation calls the provider's protocol "TOPT", a long-standing typo for TOTP, in case you go looking for the term.

Green Two-Factor Authentication message: enroll in the Webmin Users module, provider TOTP Authenticator

After saving TOTP Authenticator, Webmin points you to Webmin Users to enrol.

Authy

A commercial service with its own phone app. It works, and it puts a third party in the path of your root logins on a box you chose to self-host. That trade is fine for some organisations and pointless for a single-server setup.

Enrol carefully. A phone reset with no recovery codes locks you out of your own machine. The escape hatch is webmin disable-twofactor --user USERNAME (the --user is required), documented with the rest of the webmin command line tools, which strips the second factor off an account from a shell. Webmin two factor authentication on anything older than 2.640 was bypassable over HTTP basic authentication, so the control is only as real as the package you are running.

Give your websites a server of their own

Launch a virtual server as simple as shared hosting, with guaranteed resources and stronger security.
Betalingscyclus

Personal Web Hosting

69.46 kr Save  14 %
59.52 kr Maandelijks
  • Perfect voor persoonlijke websites, blogs en portfolio’s, en biedt je een snelle en betrouwbare manier om online te gaan zonder complexiteit.
  • 40 GB NVMe opslag
  • 2 GB RAM-geheugen
  • 2 vCPU AMD EPYC
  • ✔ IPv4 & IPv6 inbegrepen IPv6-ondersteuning is momenteel niet beschikbaar in Frankrijk of Nederland.
  • ✔Onbeperkt 1 Gbps netwerk
  • ✔Gratis automatische back-up
  • ✔Firewall beheer
  • ✔Gratis server monitoring
  • ✔KVM isolatie

Business Web Hosting

238.38 kr Save  21 %
188.70 kr Maandelijks
  • Ideaal voor gevestigde websites en drukke teams, met de kracht om meerdere projecten en stabiele groei te ondersteunen.
  • 250 GB NVMe opslag
  • 8 GB RAM-geheugen
  • 4 vCPU AMD EPYC
  • ✔ IPv4 & IPv6 inbegrepen IPv6-ondersteuning is momenteel niet beschikbaar in Frankrijk of Nederland.
  • ✔Onbeperkt 1 Gbps netwerk
  • ✔Gratis automatische back-up
  • ✔Firewall beheer
  • ✔Gratis server monitoring
  • ✔KVM isolatie

Agency Web Hosting

447.06 kr Save  22 %
347.69 kr Maandelijks
  • Ontworpen voor zeer veeleisende gebruikers, met de capaciteit om eenvoudig veel klanten en zware workloads te beheren.
  • 600 GB NVMe opslag
  • 16 GB RAM-geheugen
  • 4 vCPU AMD EPYC
  • ✔ IPv4 & IPv6 inbegrepen IPv6-ondersteuning is momenteel niet beschikbaar in Frankrijk of Nederland.
  • ✔Onbeperkt 1 Gbps netwerk
  • ✔Gratis automatische back-up
  • ✔Firewall beheer
  • ✔Gratis server monitoring
  • ✔KVM isolatie

Stop everyone logging in as root

The documentation for the Webmin Users module is blunt about the starting position: a fresh install has a single user, root or admin, with access to every feature of every module. On a box with one administrator that is defensible. On a box where three people know the same password, you have lost the ability to say who did anything.

Create a named Webmin account per person and grant modules per account. It lets you hand someone the Postfix module and the log viewer without handing them Users and Groups, which is the usual reason people ask for it. Treat that as an operational boundary, given what the Help escalation did to module ACLs before 2.640.

Unix authentication or a Webmin password

Each account picks one, and the related confusion about what the default credentials are is untangled in the piece on the Webmin default login and password. The same documentation lets a user who shares a name with a Unix account pick Unix authentication, so Webmin validates the login through PAM or /etc/shadow. Otherwise Webmin stores its own hash in /etc/webmin/miniserv.users.

My preference leans towards Unix authentication for anyone who already has a shell account, because disabling the system account disables Webmin at the same moment and there is one credential to rotate. I am less sure of it on a machine with password ageing switched on, where an expired system password takes Webmin down with it at the least convenient time, and I have not run it both ways for long enough to have a settled view. An account that exists only to read a status page and should never have SSH is the easy case: give it a Webmin-stored password so no system account has to exist for it.

Trim the installed modules

A package install brings in over a hundred modules (115 directories on 2.670) and most servers use ten of them. The Webmin Modules page under Webmin Configuration removes the ones you do not want, and every module removed is code that cannot be reached through the web interface at all, which is why taking Read User Mail off a machine that has never run a mail server is the shape of decision to make, and it happens to drop two of the 2026 advisories from your exposure. Do it once, at install, and then leave it alone: the gain is real and modest, and once you are weighing up which of two file managers to keep, you have moved out of hardening and into tidying.

ls /usr/share/webmin/*/module.info | wc -l prints 115 on Webmin 2.670

A 2.670 package install brings 115 modules.

Trusted Referrers and Fail2ban for the login log

Trusted Referrers, again under Webmin Configuration, controls which external sites may link into Webmin pages. It blunts cross-site request forgery, where a page you visit elsewhere submits a form to your logged-in session without you seeing it. Leave referrer checking on, and add hosts only if you front Webmin with a proxy or an internal dashboard that legitimately links into it.

The Logging page decides what gets recorded and how long it is kept. CrowdSec and Fail2ban both watch the authentication log and ban the source, their differences are set out in the CrowdSec and Fail2ban comparison, and a Webmin Fail2ban jail is the cheapest version of this if you already run Fail2ban for SSH. Roll either one out carefully. The classic failure is banning your own office range, which the notes on avoiding lockouts during a CrowdSec rollout cover in detail. Whichever you pick, set the retention long enough that you can still look back at a week you were not paying attention.

Set up Fail2ban for Webmin with the webmin-auth jail

Ubuntu's fail2ban package already carries a [webmin-auth] jail in /etc/fail2ban/jail.conf, set to port = 10000, and leaves it off. The sshd jail is on by default. Switching the Webmin one on takes two lines, if you have no jail.local yet:

printf '[webmin-auth]\nenabled = true\n' | sudo tee /etc/fail2ban/jail.local
sudo systemctl restart fail2ban

The stock [webmin-auth] jail in /etc/fail2ban/jail.conf sets port = 10000

Fail2ban already ships a Webmin jail, scoped to port 10000.

With the stock settings it bans an address after 5 failed logins in 10 minutes, for 10 minutes and only on port 10000, so a banned address can still reach SSH. sudo fail2ban-client status webmin-auth lists who is banned and sudo fail2ban-client set webmin-auth unbanip 203.0.113.42 lets one back in.

fail2ban-client status webmin-auth after five failures: Currently banned 1, banned IP listed

The webmin-auth jail banned the address after five failed logins.

Webmin has a smaller lock of its own underneath this. After five failures from one address its login form answers blocked because of too many authentication failures. for 60 seconds. And if you install Fail2ban after Webmin, its Fail2Ban Intrusion Detector module stays under Un-used Modules until you click Refresh Modules.

Five wrong logins: four Login failed lines, then blocked because of too many authentication failures

Webmin's own lock answers the fifth failure before Fail2ban acts.

Webmin Un-used Modules list still showing Fail2Ban Intrusion Detector after fail2ban was installed

Installed after Webmin, Fail2ban stays under Un-used Modules until Refresh Modules.

Checking the result

Confirm the daemon is bound where you think it is, from the server:

ss -lntp | grep 10000

A loopback or VPN address in that output is the outcome you want. Then test from outside, on a phone off the office network or another VPS:

curl -k --max-time 5 https://YOUR_SERVER_IP:10000

A timeout or a refused connection is a pass, and a Webmin bound to loopback gives the second, Couldn't connect to server after a millisecond. A login page is a finding. Last, log in as one of the restricted accounts you created and count the modules in the sidebar; a full list means the module access saved against that user did not apply, and that wants fixing before the change gets written up as done.

Questions?

Is Webmin safe to use?

Webmin is safe to run when it is patched and not open to the whole internet, and the project's own history shows why both matter. In 2019 it disclosed that its build server had been compromised and that releases 1.882 to 1.921 contained a remote command execution flaw (CVE-2019-15231); 1.890 was exploitable on a default install and 1.930 is the fixed version. The project said it then changed its build process to use only code checked in on GitHub. Because Webmin runs as root, I'd keep its login page behind an allow list or a tunnel.

Philippe Ménard
About the author

Philippe Ménard

Some evenings Philippe is at a small community radio station in Montréal, helping with recording or presenting a late-evening music programme. He was born in Lyon and moved to Montréal for graduate studies in computer science, then stayed: application support first, then infrastructure security (where technical communication became a larger part of the job once he started producing internal material for teams). He writes about security, Linux administration, cloud infrastructure, AI, automation. His record collection is mostly jazz and French music inherited from his father.

Move your sites to a server with room to grow

Pick cPanel, Plesk or ispmanager at checkout and manage every site from the panel you know, with full root access when you need it. Support is available 24/7.