Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am using Webmin for my home server administration.

Instead of running it on the default port (https://myhost:10000), I wanted to host it inside a sub-folder (https://myhost/webmin/). This is running perfectly fine when using Apache (Apache configuration files are attached below). However, I am normally using lighttpd, and I wanted to do the same thing (running Webmin in a sub-folder) with lighttpd. However, it is not working properly. Whenever I go to https://myhost/webmin/, I get the message:

Error - Bad Request
This web server is running in SSL mode. Try the URL https://localhost:10000/ instead.

So I looked a little bit deeper into the issue. Instead of running Webmin, I used netcat to listen to port 10000. When using lighttpd, I get:

myhost@myhost:~$ nc -l 10000
GET /webmin/ HTTP/1.0
Host: myhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Cookie: testing=1
Cache-Control: max-age=0
X-Forwarded-For: 192.168.159.1
X-Host: myhost
X-Forwarded-Proto: https

Whereas when using Apache, I get:

myhost@myhost:~$ nc -l 10000
ÌÈOPù¶°$óI¢ÚH,-ånú­? ÆÀ2´ûZÀÀ
98ÀÀ5
À    ÀÀ
ÀÀ      32EDÀÀ/AÀÀÀ
ÀÿD

42
#PuTTYPuTTYPuTTY^C

As you can see, this is probably a SSL handshake. Interrupting netcat at this point also shows the Apache error message "Reason: Error during SSL Handshake with remote server", so I am pretty sure a SSL handshake is really happening here.

That means that Webmin is right, the request it receives is not a HTTPS, but a HTTP request.

So the question is, why is Apache correctly using HTTPS for proxying, whereas lighttpd uses HTTP with some X-Forwarded-Proto for proxying? How can I achieve a similar SSL proxying with lighttpd?


For the record, all changes to configuration files that I have made. I have added the following lines to /etc/webmin/config:

webprefix=/webmin
webprefixnoredir=1
referer=myhost

I have added the following for lighttpd in the lighttpd.conf (which produces the error above):

$HTTP["url"] =~ "^/webmin" {
   proxy.server  = ( "/webmin/" =>
     ( (
        "strip-request-uri" => "/webmin",
        "host" => "127.0.0.1",
        "port" => 10000,
        "fix-redirects" => 1
     ) ) )
}

And I am using the following configuration file for Apache (which is correctly working):

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so

ProxyPass /webmin/ https://myhost:10000/
ProxyPassReverse /webmin/ https://myhost:10000/
SSLProxyEngine On

<Proxy *>
allow from all
SSLRequireSSL
</Proxy>

<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        SSLEngine on
        SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
    </VirtualHost>
</IfModule>
share|improve this question
    
Webmin is expecting to receive an encrypted connection from the proxy; lighttpd is proxying as plain HTTP. It's on the loopback interface, so encryption probably doesn't matter for that leg of the communication; can you tell Webmin to accept a non-SSL connection? –  Shane Madden Mar 2 '12 at 21:34
add comment

1 Answer

up vote 2 down vote accepted

Nevermind, got it working now.


Oh wait, you thought that's all? Nope, fellow Server Fault and search engine users, here is a guide on how to set up lighttpd with Webmin running in a sub-folder. Enjoy!

Prerequisites

The goal of this guide is to set up a lighttpd installation together with Webmin, so that one can access the Webmin interface at *http://myhost/webmin.

When this guide was written, the current Webmin version was 1.580, and the lighttpd version used was 1.4.28. I assume that you already have installed both. The name "myhost" always denotes the hostname of the machine on which lighttpd runs on.

Steps

1. Webmin configuration

Like mentioned in the official guide for Apache, you have to add the following lines to /etc/webmin/config:

webprefix=/webmin
webprefixnoredir=1
referer=myhost

2. Disable SSL in Webmin

Yup, you heard right, and as Shane Madden mentioned in the comment above, this is not unsafe, as the communication looks like this:

client <----SSL----> myhost <--Loopback--> myhost:10000

Webmin will be communicating with the lighttpd instance running on myhost via the loopback device, that is inside the machine, which normally can only be obversed with super user privileges. The communication between the client and lighttpd will still be using SSL.

So and how to disable SSL in Webmin? Just edit the following line in /etc/webmin/miniserv.conf:

ssl=0

3. Lighttpd configuration

Add the following lines to your /etc/lighttpd/lighttpd.conf:

$HTTP["url"] =~ "^/webmin" {
  magnet.attract-physical-path-to = ( "/var/www/webmin/conf/webmin-rewrite.lua" )

  proxy.server  = ( "" =>
    ( (
        "host" => "127.0.0.1",
        "port" => 10000,
    ) ) )
}

As you can see, we check if the URL starts with "/webmin", and the redirect to the Webmin instance listening on 127.0.0.1:10000. However, Webmin does not expect to have the additional path ".../webmin" in its request URL, so we have to strip that from the URL. However, as we are in a $HTTP["url"]-conditional, we cannot use any URL-rewriting techniques featured by mod_rewrite. (Otherwise we would simply say "strip-request-uri" => "/webmin", but this will not work. This is a know, wont-fix issue of lighttpd 1.4. See also the mod_rewrite documentation.) However, we can use mod_magnet to rewrite the URL in a LUA script.

4. LUA Script for mod_magnet

Create /var/www/webmin/conf/webmin-rewrite.lua with the following content:

subfolder = "/webmin"
n = string.len(subfolder)

if string.sub(lighty.env["request.uri"], 1, n) == subfolder then
    lighty.env["request.uri"] = string.sub(lighty.env["request.uri"], n+1)
end

This strips the "/webmin"-prefix from the request URLs.

5. Code changes to fix redirections

This already almost works, however, there is still a bug in the redirection code of Webmin, also mentioned here. In /usr/share/webmin/miniserv.pl, change the line

&write_data("Location: $prot://$host$portstr$in{'page'}\r\n");

to

&write_data("Location: $prot://$host$config{'subfolder_prefix'}$in{'page'}\r\n");

And in /etc/webmin/miniserv.conf, add the line:

subfolder_prefix=/webmin

This fixes the Webmin login redirection, and you're done!

Further notes

Beginning with lighttpd version 1.5, you can probably replace the LUA script with mod_proxy_core, as it is capable to rewrite the request URLs. However, I didn't try that.

Furthermore, as there is no need to access port 10000 anymore from the outside, I suggest blocking it:

iptables -A INPUT -i eth0 -p tcp --dport 10000 -j REJECT --reject-with tcp-reset

However, this command can vary depending on your local configuration.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.