Developer Tools AWS

Webmin System Administration 2.670 on AWS User Guide

| Product: Webmin System Administration 2.670 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the Webmin System Administration 2.670 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg Infrastructure as Code and Config Management listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

Webmin is the long standing web based system administration panel for Linux. From one browser session you can manage users and groups, packages and updates, systemd services, cron jobs, the firewall, disks and filesystems, web and DNS servers and much more. Webmin runs its own web server (miniserv) as root and serves the console over HTTPS on port 10000.

Webmin can do anything root can do on this server. Treat its admin password as a root password and allow port 10000 only from the addresses you manage the server from.

The cloudimg image adds:

  • A password unique to your instance, and no other way in. The only Webmin user is admin. Its password is generated on your instance's first boot, hashed straight into Webmin's user file (it never appears on a command line or in a log) and written to /root/webmin-credentials.txt, readable by root only. Logins by Unix users, by root and by sudo-capable users are switched off, and no module is reachable without signing in.
  • HTTPS only, with a certificate made on your instance. Port 10000 accepts TLS 1.2 and 1.3 only, plain HTTP on port 10000 is redirected to HTTPS, and HSTS is on. The certificate and its private key are generated on first boot, so no two instances share a key. Port 80 is served by nginx and only redirects to Webmin (plus a /healthz check); it never proxies Webmin.
  • Brute force protection. An address is blocked for 5 minutes after 5 failed logins, a user name is blocked after 5 failures, and each failure adds a growing delay before the next attempt for that user.
  • Requests from other web sites are refused. Webmin's referer check is on, and a request that arrives with no referer is refused too.
  • The host name comes from configuration, never from a request. Webmin answers only to the name it is configured for (your instance's public IP address by default) and refuses any other Host header, so its redirects and its referer check cannot be steered by a request. A helper, webmin-set-host, changes the name.
  • URL downloads cannot reach private addresses. Webmin 2.670 includes the fix for GHSA-x8qr-rx2g-f23g, and the image switches it on for admin: the Upload and Download, File Manager and Mailboxes modules refuse to download from a URL that resolves to a private, loopback, link-local or other non-public address. (Webmin checks the address after it connects, so the request itself can still reach such a host; the instance metadata service is covered separately by the block below.)
  • Instance metadata is blocked for Webmin and nginx, and the instance requires IMDSv2.
  • Exactly three ports: 22 (SSH), 80 (redirect) and 10000 (Webmin). Webmin's UDP discovery listener is off and Usermin is not installed.

What is on the image: Webmin 2.670 (installed from the official .deb, checksum verified), nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. Webmin's working data (sessions, logs, the block list) lives on its own EBS volume at /var/webmin.

Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
  • A security group that allows TCP 10000 (Webmin) and TCP 22 (SSH) from your own IP address or management network only, and optionally TCP 80 (it only redirects to Webmin). Do not open port 10000 to 0.0.0.0/0.

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Webmin System Administration 2.670 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large (Webmin itself is light; a smaller type works for a single server), your key pair and a security group as above. Keep the second EBS volume: it holds Webmin's working data.

With the AWS CLI (replace the values in angle brackets):

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=webmin}]'

Step 2: Connect to your instance

Version SSH user
Webmin System Administration 2.670 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

Step 3: Check the services and the ports

First boot takes a few seconds. Then Webmin, nginx and the two cloudimg first boot units are active:

systemctl is-active webmin nginx webmin-firstboot webmin-set-host
active
active
active
active

Webmin (miniserv.pl) listens on 10000, nginx on 80 and SSH on 22. Nothing else listens on a public address:

sudo ss -tlnp | awk 'NR==1 || /nginx|sshd|miniserv/' | awk '{print $1, $4, $6}' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g'
State Local Peer
LISTEN 0.0.0.0:22 users:(("sshd"),("systemd"))
LISTEN 0.0.0.0:80 users:(("nginx"),("nginx"),("nginx"))
LISTEN 0.0.0.0:10000 users:(("miniserv.pl"))
LISTEN [::]:22 users:(("sshd"),("systemd"))
LISTEN [::]:80 users:(("nginx"),("nginx"),("nginx"))
LISTEN [::]:10000 users:(("miniserv.pl"))

Webmin's working data is on the separate volume:

findmnt -no SOURCE,TARGET,FSTYPE /var/webmin
df -h --output=size,avail,target /var/webmin
/dev/nvme1n1 /var/webmin ext4
 Size Avail Mounted on
  20G   19G /var/webmin

Step 4: Get your URL and admin password

sudo cat /root/webmin-credentials.txt
# Webmin - generated on this instance's first boot. Unique to this instance.
# Webmin runs as root and can manage the whole server: treat these as root credentials.
WEBMIN_URL=https://<public-ip>:10000/
WEBMIN_USERNAME=admin
WEBMIN_PASSWORD=<24 letters and digits>
# The certificate is self-signed (per instance). Allow TCP 10000 only from your own IP in the security
# group. To serve Webmin under a DNS name: sudo webmin-set-host <name>   Guide: https://www.cloudimg.co.uk/guides/webmin-system-administration-2-670-on-ubuntu-24-04-aws/

Step 5: Sign in

Open the WEBMIN_URL from the credentials file in your browser, for example https://<public-ip>:10000/. The certificate is self-signed, so your browser shows a warning the first time; check the address is your instance's and continue (or install your own certificate, Step 9). Sign in as admin with the password from the file.

The Webmin sign in page asking for a username and password to log in to the server at the instance's address

The dashboard shows the server at a glance: host name, operating system, Webmin version, CPU, memory, disk and whether packages are up to date. The menu on the left opens every module.

The Webmin dashboard showing CPU, real memory and local disk gauges, system information for Ubuntu Linux 24.04 and Webmin 2.670, and the module menu on the left

System > Users and Groups manages the server's Unix accounts:

The Users and Groups module listing the local Unix users with their user IDs, groups, home directories and shells

System > Software Package Updates lists and installs pending Ubuntu updates:

The Software Package Updates module reporting that no packages are available to be updated

Webmin only answers to its configured name. If you browse to it by another name or address (for example the private IP address over a VPN), it replies Invalid HTTP hostname; set the name you use with webmin-set-host (Step 8).

Step 6: Check the sign in from the command line

This signs in over HTTPS on the instance itself, reading the password from the credentials file on standard input so it never appears on a command line, and prints the HTTP status. 302 means signed in; a wrong password gets 200 with "Login failed":

HOST=$(sudo awk -F= '$1=="musthost"{print $2}' /etc/webmin/miniserv.conf)
JAR=$(mktemp)
curl -sk -o /dev/null -c "$JAR" -H "Host: $HOST:10000" https://127.0.0.1:10000/session_login.cgi
sudo grep '^WEBMIN_PASSWORD=' /root/webmin-credentials.txt | cut -d= -f2- | tr -d '\n' | \
  curl -sk -o /dev/null -b "$JAR" -c "$JAR" -w 'sign in: %{http_code}\n' -H "Host: $HOST:10000" \
    --data-urlencode user=admin --data-urlencode pass@- --data page=/ https://127.0.0.1:10000/session_login.cgi
rm -f "$JAR"
sign in: 302

Step 7: Security checks

The Webmin server configuration: HTTPS only, plain HTTP redirected, TLS 1.0 and 1.1 off, sudo and Unix logins off, root denied, the UDP listener off, brute force blocking on and the host pinned:

sudo grep -E '^(port|ssl|ssl_enforce|ssl_hsts|no_tls1|no_tls1_1|sudo|denyusers|listen|blockhost_failures|blockhost_time|blockuser_failures|blockuser_time)=' /etc/webmin/miniserv.conf
port=10000
ssl=1
ssl_enforce=2
ssl_hsts=1
no_tls1=1
no_tls1_1=1
blockhost_failures=5
blockhost_time=300
blockuser_failures=5
blockuser_time=300
sudo=0
denyusers=root
listen=

Referer checking refuses requests with no referer, admin is the only Webmin user, and its URL downloads are limited to public addresses:

sudo grep -E '^referers_none=' /etc/webmin/config
sudo cut -d: -f1 /etc/webmin/miniserv.users
sudo cat /etc/webmin/admin.acl
referers_none=1
admin
download_address_mode=public

Only TLS 1.2 and 1.3 are accepted:

for v in tls1 tls1_1 tls1_2 tls1_3; do
  if echo | timeout 5 openssl s_client -connect 127.0.0.1:10000 -$v >/dev/null 2>&1; then echo "$v accepted"; else echo "$v refused"; fi
done
tls1 refused
tls1_1 refused
tls1_2 accepted
tls1_3 accepted

A request for any other host name is refused by Webmin (400) and by nginx (no answer, shown by curl as 000):

curl -sk -o /dev/null -w 'webmin: %{http_code}\n' -H 'Host: other.invalid:10000' https://127.0.0.1:10000/
curl -s -o /dev/null -w 'nginx: %{http_code}\n' -H 'Host: other.invalid' http://127.0.0.1/ || true
webmin: 400
nginx: 000

Webmin and nginx cannot reach the instance metadata service:

systemctl show -p IPAddressDeny webmin nginx
IPAddressDeny=168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128

IPAddressDeny=168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128

What the metadata block means for you. Everything Webmin runs, including commands from its Command Shell, downloads in Upload and Download and anything else started from the Webmin console, runs inside the webmin service and cannot read instance metadata or use the instance's IAM role. This stops a request smuggled through Webmin from reading your instance's role credentials. Run AWS CLI commands that need the instance role from an SSH session instead. Separately, Webmin's own URL downloads only reach public addresses; to download from a server on your private network, open Webmin > Webmin Users, choose Global ACL for admin (Permissions for all modules) and set URL download destinations to Public IP addresses and these exceptions, listing only the addresses or networks you trust (never 169.254.169.254) rather than All IP addresses. If you really need Webmin itself to reach the metadata service, remove /etc/systemd/system/webmin.service.d/50-cloudimg-imds-deny.conf and run sudo systemctl daemon-reload && sudo systemctl restart webmin, knowing that anyone who can sign in to Webmin can then read the role's credentials.

Step 8: Your own DNS name

Point a DNS name at the instance (an Elastic IP keeps the address stable), then tell Webmin to use it. This makes a new certificate for the name, updates Webmin's allowed host, the port 80 redirect and the URL in the credentials file, and restarts Webmin:

sudo webmin-set-host <your-domain>

Without a configured name, the instance uses its public IP address (or its private IP address when it has no public one) and picks up a new address automatically after a stop and start.

Step 9: Your own certificate

To use a certificate from your certificate authority, open Webmin > Webmin Configuration > SSL Encryption and upload the private key and certificate, or replace /etc/ssl/private/cloudimg-webmin.key and /etc/ssl/certs/cloudimg-webmin.crt (keep the key 0600 root) and run sudo systemctl restart webmin. Running webmin-set-host again replaces them with a new self-signed certificate.

Step 10: Change the admin password

Sign in and open Webmin > Webmin Users, choose admin and set a new password. The credentials file is not updated, so once you have stored the new password somewhere safe, delete the file with sudo shred -u /root/webmin-credentials.txt.

Avoid changepass.pl with the password as an argument: other users on the server can see a command line while it runs.

Step 11: Updates

Ubuntu security updates install automatically through unattended-upgrades. Webmin reports newer Webmin releases on its dashboard; upgrade with Upgrade Webmin Now or from Webmin > Webmin Configuration > Upgrade Webmin. The hardening above lives in /etc/webmin and is kept across upgrades (sudo=0 stays set, so an upgrade does not turn sudo logins back on). Recheck it after an upgrade with the commands in Step 7.

Step 12: Server components

Component Details
Webmin 2.670, /usr/share/webmin, configuration in /etc/webmin, service webmin (port 10000, HTTPS)
nginx port 80: /healthz and a redirect to Webmin only
Data volume /var/webmin (sessions, action and access logs, block list)
First boot webmin-firstboot.service (once), webmin-set-host.service (every boot)
Credentials /root/webmin-credentials.txt (root only)
Certificate /etc/ssl/certs/cloudimg-webmin.crt, key /etc/ssl/private/cloudimg-webmin.key
Logs /var/webmin/miniserv.log (requests), /var/webmin/webmin.log (actions), failed logins in the journal (journalctl -t webmin)

Step 13: Security recommendations

  • Allow TCP 10000 and 22 only from your own addresses; use a VPN or AWS Systems Manager Session Manager where you can.
  • Use a DNS name with a certificate from your certificate authority for anything beyond your own use.
  • Change the admin password after first sign in and delete the credentials file.
  • Consider Webmin > Webmin Configuration > Two-Factor Authentication.
  • Keep Webmin and Ubuntu up to date.

Support and licensing

Webmin is open source software under the BSD 3-Clause License; a copy is at /usr/share/doc/cloudimg/webmin/LICENSE. Webmin is a trademark of its respective owner; cloudimg is not affiliated with or endorsed by the Webmin project. cloudimg provides 24/7 support for this image by email at support@cloudimg.co.uk.