Webmin is a web-based system administration tool for Unix-like systems. First released in 1997, it provides a graphical interface for managing system configuration, users, services, and applications. Webmin’s modular architecture and deep system integration make it popular among system administrators worldwide. While Webmin has a strong security track record with regular updates, comprehensive hardening is essential for production environments.
Webmin supports TOTP-based 2FA and U2F (hardware keys). Enable it immediately after installation.
Enable 2FA via Webmin UI:
Enable U2F hardware key support:
Force 2FA for all users:
# Edit Webmin configuration
sudo nano /etc/webmin/miniserv.conf
# Add or modify:
forced_2fa=1
# Restart Webmin
sudo systemctl restart webmin
Secure the default root/admin account:
# Change root password
sudo passwd root
# Or via Webmin UI
# Webmin → Webmin Configuration → Change Password
Best practices:
Create new admin user:
# Via Webmin UI
# Webmin → Webmin Users → Create a new Webmin user
# Set username, password, and grant "All modules" access
# Or via CLI
/usr/share/webmin/adduser.pl newadmin 'StrongPassword123!'
Delete or disable unused accounts:
# Disable user via Webmin UI
# Webmin → Webmin Users → Select user → Disable
# Or via CLI
/usr/share/webmin/deleteuser.pl oldadmin
Restrict panel access by IP using Webmin’s built-in feature:
# Edit Webmin configuration
sudo nano /etc/webmin/miniserv.conf
# Add allowed IPs (comma-separated)
allow=10.0.0.0/24,192.168.1.0/24
# Or deny specific IPs
deny=192.168.100.100,192.168.100.101
# Restart Webmin
sudo systemctl restart webmin
Configure via Webmin UI:
Using iptables:
# Allow only from management network
sudo iptables -A INPUT -p tcp --dport 10000 -s 10.0.0.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 10000 -j DROP
sudo iptables-save > /etc/iptables/rules.v4
Using firewalld:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" port port="10000" protocol="tcp" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="10000" protocol="tcp" reject'
sudo firewall-cmd --reload
Using UFW:
sudo ufw allow from 10.0.0.0/24 to any port 10000
sudo ufw deny 10000
sudo ufw enable
Configure session settings in Webmin:
300 seconds (5 minutes for admin)Edit /etc/webmin/miniserv.conf:
# Session timeout (seconds)
logout_timeout=300
# Single session
single_session=1
# Referrer checking
no_referrer=0
# Secure cookies
cookie_secure=1
cookie_httponly=1
Restart Webmin:
sudo systemctl restart webmin
Configure password requirements:
# Edit Webmin configuration
sudo nano /etc/webmin/miniserv.conf
# Password policy settings
passwd_mode=1 # Require strong passwords
passwd_length=12 # Minimum length
Enforce password history (prevent reuse):
# Install pam_pwhistory
sudo apt install libpam-pwquality # Debian/Ubuntu
sudo dnf install libpwquality # RHEL/CentOS
# Configure /etc/pam.d/common-password
password required pam_pwhistory.so use_authtok remember=12 enforce_for_root
password required pam_unix.so use_authtok sha512
Webmin uses HTTPS by default on port 10000. Replace self-signed certificate with valid certificate:
Option 1: Let’s Encrypt
sudo apt install certbot
# Generate certificate
sudo certbot certonly --standalone -d webmin.example.com
# Link to Webmin
sudo cp /etc/letsencrypt/live/webmin.example.com/fullchain.pem /etc/webmin/miniserv.pem
cat /etc/letsencrypt/live/webmin.example.com/privkey.pem >> /etc/webmin/miniserv.pem
sudo chmod 600 /etc/webmin/miniserv.pem
# Restart Webmin
sudo systemctl restart webmin
Option 2: Self-signed certificate
sudo /usr/share/webmin/restart.pl --force-new-certs
Configure SSL/TLS settings:
# Edit /etc/webmin/miniserv.conf
ssl=1
ssl_min_version=TLSv1.2
ssl_ciphers=ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
# Redirect HTTP to HTTPS
redirect_ssl=1
Default Webmin ports:
| Port | Service | Required |
|---|---|---|
| 10000 | Webmin Admin Panel | Yes |
Configure firewall:
# Using iptables
sudo iptables -A INPUT -p tcp --dport 10000 -s 10.0.0.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 10000 -j DROP
sudo iptables-save > /etc/iptables/rules.v4
# Using firewalld
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" port port="10000" protocol="tcp" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="10000" protocol="tcp" reject'
sudo firewall-cmd --reload
# Using UFW
sudo ufw allow from 10.0.0.0/24 to any port 10000
sudo ufw deny 10000
sudo ufw enable
Webmin includes built-in fail2ban integration:
Enable fail2ban protection:
# Install fail2ban (if not already installed)
sudo apt install fail2ban # Debian/Ubuntu
sudo dnf install fail2ban # RHEL/CentOS
Webmin fail2ban jails (/etc/fail2ban/jail.local):
[webmin-auth]
enabled = true
port = 10000
filter = webmin-auth
logpath = /var/log/webmin/auth.log
maxretry = 5
bantime = 3600
findtime = 300
[webmin-bruteforce]
enabled = true
port = 10000
filter = webmin-bruteforce
logpath = /var/log/webmin/auth.log
maxretry = 3
bantime = 7200
findtime = 300
Create Webmin filter (/etc/fail2ban/filter.d/webmin-auth.conf):
[Definition]
failregex = ^.*Failed login.*<HOST>.*$
^.*Authentication failure.*<HOST>.*$
^.*Invalid.*password.*<HOST>.*$
^.*Login failed.*<HOST>.*$
ignoreregex =
Restart fail2ban:
sudo systemctl restart fail2ban
View banned IPs:
fail2ban-client status webmin-auth
fail2ban-client set webmin-auth unbanip <IP>
Configure Webmin rate limiting:
# Edit /etc/webmin/miniserv.conf
# Add rate limiting
max_connections=100
max_connections_per_ip=10
# Restart Webmin
sudo systemctl restart webmin
Configure iptables rate limiting:
# Rate limit connections to Webmin
sudo iptables -A INPUT -p tcp --dport 10000 -m state --state NEW -m recent --set
sudo iptables -A INPUT -p tcp --dport 10000 -m state --state NEW -m recent --update --seconds 60 --hitcount 10 -j DROP
sudo iptables-save > /etc/iptables/rules.v4
Edit /etc/webmin/miniserv.conf:
# Security settings
# Disable debug in production
log=1
# Session security
logout_timeout=300
single_session=1
# SSL/TLS settings
ssl=1
ssl_min_version=TLSv1.2
# Login attempt limits
login_failures=5
login_lock_time=300
# File upload limits
max_upload=10485760 # 10MB
Apply configuration:
sudo systemctl restart webmin
Webmin has many modules. Disable unused ones:
# List installed modules
ls /usr/share/webmin/
# Disable unused modules via Webmin UI
# Webmin → Webmin Configuration → Modules
# Or edit /etc/webmin/installed.config
# Remove or comment out unused modules
Recommended modules for minimal install:
Secure Webmin installation:
# Webmin directory permissions
sudo chown -R root:root /usr/share/webmin
sudo chmod -R 755 /usr/share/webmin
sudo chmod 600 /etc/webmin/miniserv.conf
# Webmin data directory
sudo chmod 700 /var/webmin
sudo chown root:root /var/webmin
# SSL certificates
sudo chmod 600 /etc/webmin/miniserv.pem
Protect sensitive files:
# /etc/apache2/conf-available/webmin-hardening.conf
<FilesMatch "(miniserv\.conf|\.sql|\.log|\.bak|\.old)$">
Require all denied
</FilesMatch>
Update Webmin:
# Update via apt (Debian/Ubuntu)
sudo apt update
sudo apt upgrade webmin
# Update via yum/dnf (RHEL/CentOS)
sudo dnf update webmin
# Or via Webmin UI
# Webmin → Webmin Configuration → Check and Install Updates
Enable automatic security updates:
# Install unattended-upgrades
sudo apt install unattended-upgrades
# Configure
sudo dpkg-reconfigure --priority=low unattended-upgrades
Webmin log locations:
| Log File | Purpose |
|---|---|
/var/log/webmin/ |
Main panel logs |
/var/log/webmin/auth.log |
Authentication logs |
/var/log/webmin/miniserv.log |
Webmin server logs |
View recent activity:
# Webmin logs
tail -f /var/log/webmin/auth.log
# Filter for login events
grep -i "login\|auth" /var/log/webmin/auth.log
# Failed login attempts
grep -i "failed\|invalid" /var/log/webmin/auth.log | tail -50
Set up alerts for:
Configure log rotation:
# /etc/logrotate.d/webmin
/var/log/webmin/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 640 root adm
}
Install AIDE to detect file changes:
# Install AIDE
sudo apt install aide
# Initialize database
sudo aideinit
# Configure Webmin paths in /etc/aide/aide.conf
/usr/share/webmin/ p+i+n+u+g+s+m+c+acl+selinux+xattrs+sha512
/etc/webmin/ p+i+n+u+g+s+m+c+acl+selinux+xattrs+sha512
/var/log/webmin/ p+i+n+u+g+s+m+c+acl+selinux+xattrs+sha512
# Schedule daily checks
0 5 * * * /usr/bin/aide --check
| Control | Status | Notes |
|---|---|---|
| 2FA enabled for all admins | ☐ | Via authentication settings |
| HTTPS with valid certificate | ☐ | Let’s Encrypt recommended |
| Firewall configured | ☐ | IP restrictions in place |
| fail2ban deployed | ☐ | Webmin jails configured |
| PHP hardening applied | ☐ | If using PHP modules |
| File permissions secured | ☐ | Config 600, directories 755 |
| Unused modules disabled | ☐ | Reduce attack surface |
| Centralized logging | ☐ | Forward to SIEM |
| Regular updates scheduled | ☐ | Webmin + system packages |
| File integrity monitoring | ☐ | AIDE configured |
If you suspect a security breach:
Isolate the server
# Block external access
sudo iptables -P INPUT DROP
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Preserve evidence
cp -r /var/log/webmin /root/webmin-logs-$(date +%Y%m%d-%H%M%S)
Review recent activity
# Failed logins
grep -i "failed" /var/log/webmin/auth.log | tail -100
# Check new accounts
/usr/share/webmin/list-users.pl
Check for unauthorized changes
# Compare with AIDE database
sudo aide --check
# Look for recently modified files
find /usr/share/webmin -type f -mtime -7 -ls
Change all credentials - Admin passwords, API keys
Scan for malware
sudo apt install clamav clamav-daemon
sudo freshclam
sudo clamscan -r /var/www --move=/home/quarantine
Patch vulnerabilities - Update Webmin and all packages
Restore from clean backup - If compromise is severe
Notify affected users - If customer data was exposed