Securing Access to Webmin through an SSH Tunnel


Webmin is installed on the server that hosts this site and for the longest time I’ve been accessing it remotely through its default port at Despite connections being encrypted through SSL and having two-factor authentication enabled in Webmin this still presents a security risk.

Changing the port Webmin listens on or using Webmin’s IP Access Control to allow access to a limited number of IP addresses may reduce the risk, but not eliminate it. As I’m the only one who requires access to Webmin, it makes more sense to block remote access entirely and allow only limited local access using local port forwarding through an SSH tunnel.


Remote Access to Webmin

Remote access to webmin
Fig. 1 – Remote access to webmin



Figure 1 shows applications on a local computer – client – sending requests to a remote host – server – and the appropriate applications on the server handling those requests and sending data back to the client applications. The server’s firewall blocks all incoming requests except to those ports that have been explicitly opened.

On the server, ufw will show which ports are open:

Dummy Content
sudo ufw status 
To                         Action      From
--                         ------      ----
10000/tcp                  ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
22/tcp                     LIMIT       Anywhere
10000/tcp (v6)             ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)
22/tcp (v6)                LIMIT       Anywhere (v6)



The Webmin server – Miniserv – is listening for requests on port 10000. As port 10000 is open in the server’s firewall, any client requests on port 10000 will reach and be handled by the Webmin server rendering the Webmin login page accessible to anyone with Internet access.


Blocking Access to Webmin

The first step in securing access to Webmin is to close the port in the server firewall that the Webmin server listens on for client requests. We do this with ufw by deleting the rule that explicitly opens port 10000:

Dummy Content
sudo ufw delete allow 10000/tcp
Rule deleted
Rule deleted (v6)



Closing port 10000 to block remote access to Webmin
Fig. 2 – Closing port 10000 to block remote access to Webmin



Figure 2 shows the client browser still sending requests on port 10000 to the Webmin server and the Webmin server still listening for requests on that same port. However, as port 10000 is no longer open in the server firewall, the Webmin server will never receive the client requests.

Webmin is – for now – inaccessible to everyone.


Accessing Webmin Through an SSH Tunnel

I’m going to provide access to Webmin by routing browser requests for it through an encrypted SSH connection between the client and the server and have these requests forwarded to Webmin. Figure 3 demonstrates this process:

Securing access to Webmin through an SSH tunnel
Fig. 3 – Securing access to Webmin through an SSH tunnel



  1. The client establishes an encrypted SSH connection to the server on port 22…

  2. …simultaneously opening local port 10005 on the client.

  3. The browser no longer sends requests directly to Webmin on the server, but to local port 10005 instead.

  4. All requests received on local port 10005 are then forwarded or tunnelled through the encrypted SSH connection to the server.

  5. The server forwards the requests onward to the Webmin server on port 10000.

The advantage of this approach is the ability to limit Webmin access to only those users who can connect to the server via SSH. In addition, SSH provides an encrypted connection. Any plain text data being tunneled through it will benefit from that secure connection. This means that Webmin can be accessed over HTTP as the plain text data being sent to and from the Webmin server doesn’t need the encryption of TLS/SSL that HTTPS provides.

In general, on a macOS or Ubuntu Desktop client the command to establish local port forwarding through an SSH tunnel is:

Dummy Content
ssh -p 22 user@host -L <local-port>:<remote-host>:<remote-port> -N &



More specifically, for the example in figure 3 the command is:

Dummy Content
ssh -p 22 penny@ -L 10005: -N &
[1] 5907



Please note the following:

  • -p 22 does not need to be included in the command if the SSH server is listening on the default port 22. However, if it’s listening on say port 5522, -p 5522 would have to be part of the command.

  • Thinking that refers to a localhost on a client, it took me a while to understand why it is being used for the <remote-host> until I realised it’s viewed from the perspective of the server not the client.

  • & puts SSH into the background which is useful if you want to continue using the same Terminal window. I prefer this to the -f option which is part of ssh as I find it easier to terminate the SSH tunnel having used the former option. On a Ubuntu Desktop client you may need to press enter to drop back to the command prompt after using &.

Having established the SSH tunnel and forwarded the local client port 10005 to the remote server port 10000, Webmin can be accessed from a browser using:

Dummy Content



You may receive an error that Webmin should be accessed using https:// instead of http://. This is more than likely because SSL is enabled in the Webmin server configuration. You can continue by using https://localhost:10005, but your browser will warn you that the connection is not private.

We know that any plain text data bound for the Webmin server will be sent through the encrypted SSH tunnel, so my preferred method is to disable SSL on the Webmin server and access Webmin through http://localhost:10005.

To disable SSL on the Webmin server we need to change ssl=1 to ssl=0 in the file /etc/webmin/miniserv.conf on the server. To do this, on the server type:

Dummy Content
sudo sed -i.$(date +"%Y%m%d-%H%M%S") 's/^ssl=1$/ssl=0/' /etc/webmin/miniserv.conf



Then restart the Webmin server:

Dummy Content
sudo systemctl restart webmin




Terminating the SSH Tunnel

When you’ve finished your Webmin session, it’s good practice to terminate the SSH tunnel. If you used the & option when creating the SSH tunnel, from the same Terminal window type:

Dummy Content
[1]+  Running                 ssh -p 22 penny@ -L 10005: -N &



This will display any process running in the background each of which will start with a number in square brackets. Bring the relevant process to the foreground by typing:

Dummy Content
fg 1
ssh -p 22 penny@ -L 10005: -N



To end the process type Ctrl+C and the SSH tunnel is no more.

About the author

A native Brit exiled in Japan, Steve spends too much of his time struggling with the Japanese language, dreaming of fish & chips and writing the occasional blog post he hopes others will find helpful.

5 responses


  • Hi!
    This is some excellent content, congratulations
    I’m not a native english speaker so I’ll try my best to explain myself
    Everything was going great until “ssl=1 to ssl=0” bit, where it says
    “-e expression #1, char 15: unterminated `s’ command
    I’m not sure what it means as I copied the same command you wrote.
    On the other hand, on the previous step my user@host changed from “Myuser@myhost” to “Myuser@’host'”, as an amateur I’m not sure if this changes something and is something i must revert o to be expected.
    And finally, when accesing webming, what should I change at “http://localhost:10005”? I mean, “localhost” should now be what?
    I thank your time and expertise, as I said I’m very new at this, I understand some bits because of basic python and fortran progamming I had at college, and i would really appreciate your patience and response, thanks!

    • Hi Benjamin,

      Everything was going great until “ssl=1 to ssl=0” bit, where it says “-e expression #1, char 15: unterminated `s’ command

      This step isn’t strictly necessary. It’s to stop your browser complaining the connection isn’t secure. If you want to change it and the sed command isn’t working, you can edit the config file manually. It’s on or around line 8 in /etc/webmin/miniserv.conf on the server. You’ll still need to restart the Webmin server aftrewards.

      on the previous step my user@host changed from “Myuser@myhost” to “Myuser@’host'”,

      Not entirely sure I understand this, but you should be using the credentials you use to create an SSH connection to the remote machine that’s running the Webmin server. If I want to create an SSH connection as user steve on a remote machine with an IP address of I’d use ssh -p 22 steve@ To create the SSH tunnel I’d use ssh -p 22 steve@ -L 10005: -N &.

      when accesing webming, what should I change at “http://localhost:10005”? I mean, “localhost’ should now be what?

      You don’t need to change anything. localhost or means this (your) computer. So entering http://localhost:10005 or in your browser sends the request to port 10005 on your computer. If the SSH tunnel is setup correctly, your computer will forward any requests it receives on port 10005 through the SSH tunnel to port 10000 on the remote machine.

      Hope this helps.

      Regards, Steve.

  • Hello,

    I don’t know how old your post is but i think you may be able to help me. at least I hope so!

    I have installed WebAdmin, and it allows connections from all IPs at the moment. I can reach it through VNC remotely, and administer it with https://localhost:10000. However, I cannot tunnel into it using https://my I have added 10000 to ufw. The browser tells me it has trouble finding the site, but I cn see that the first page it shows for a few milliseconds is the “Go back”, presumably because it’s untrusted, before being replace by “Hmm”!

    I have an SSH tunnel directly to the shell, and the VNC tunnel to the destop. Any ideas greatly appreciated!

    Kind regards,

    • Hi Paul,

      I don’t fully understand what you’re trying to do nor how VNC figures in it. I have almost no experience of using VNC, but if you can SSH from your local machine to the remote where Webmin is installed and you want to limit access to Webmin can you not simply block port 10000 on the remote, forward Webmin traffic through a local port and access it via http://localhost:localport as the article suggests?

      Sorry if I’m not grasping the details.

      Regards, Steve.

1 Pingback


Recent Comments

Recent Posts