先决条件

先决条件

我正在使用 Webmin 来管理我的家庭服务器。

而不是在默认端口上运行它(https://我的主机:10000),我想将其托管在子文件夹中(https://myhost/webmin/)。使用 Apache 时,此操作运行正常(Apache 配置文件附在下面)。但是,我通常使用 lighttpd,我想用 lighttpd 做同样的事情(在子文件夹中运行 Webmin)。但是,它无法正常工作。每当我访问https://myhost/webmin/,我收到消息:

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

因此,我深入研究了这个问题。我没有运行 Webmin,而是使用 netcat 来监听端口 10000。使用 lighttpd 时,我得到:

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

而当使用 Apache 时,我得到:

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

42
#PuTTYPuTTYPuTTY^C

如您所见,这可能是 SSL 握手。此时中断 netcat 还会显示 Apache 错误消息“原因:与远程服务器进行 SSL 握手时出错”,因此我很确定这里确实发生了 SSL 握手。

也就是说Webmin是正确的,它收到的请求不是HTTPS,而是HTTP请求。

所以问题是,为什么 Apache 正确地使用 HTTPS 进行代理,而 lighttpd 使用带有一些 X-Forwarded-Proto 的 HTTP 进行代理?如何使用 lighttpd 实现类似的 SSL 代理?


为了记录,我对配置文件进行了所有更改。我在 /etc/webmin/config 中添加了以下几行:

webprefix=/webmin
webprefixnoredir=1
referer=myhost

我在 lighttpd.conf 中为 lighttpd 添加了以下内容(产生了上述错误):

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

我正在使用以下 Apache 配置文件(它可以正常工作):

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>

答案1

没关系,现在可以工作了。


哦,等等,你以为就这些了吗?不,各位 Server Fault 和搜索引擎用户,这里有一个指南,介绍如何在子文件夹中运行 Webmin 来设置 lighttpd。尽情享受吧!

先决条件

本指南的目标是设置 lighttpd 与 Webmin 的安装,以便可以通过 * 访问 Webmin 界面http://myhost/webmin

撰写本指南时,当前的 Webmin 版本为 1.580,而使用的 lighttpd 版本为 1.4.28。我假设您已经安装了这两个版本。名称“myhost”始终表示运行 lighttpd 的计算机的主机名。

脚步

1.Webmin 配置

正如 Apache 官方指南中提到的,您必须在 /etc/webmin/config 中添加以下行:

webprefix=/webmin
webprefixnoredir=1
referer=myhost

2. 在 Webmin 中禁用 SSL

是的,你没听错,正如 Shane Madden 在上面的评论中提到的那样,这并不危险,因为交流方式如下:

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

Webmin 将通过机器内部的环回设备与在 myhost 上运行的 lighttpd 实例进行通信,通常只有超级用户权限才能查看。客户端和 lighttpd 之间的通信仍将使用 SSL。

那么如何在 Webmin 中禁用 SSL?只需在 /etc/webmin/miniserv.conf 中编辑以下行:

ssl=0

3.Lighttpd配置

将以下行添加到您的 /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,
    ) ) )
}

如您所见,我们检查 URL 是否以“/webmin”开头,并重定向到监听 127.0.0.1:10000 的 Webmin 实例。但是,Webmin 不希望其请求 URL 中包含额外的路径“.../webmin”,因此我们必须从 URL 中删除该路径。但是,由于我们处于 $HTTP["url"] 条件中,因此我们不能使用 mod_rewrite 提供的任何 URL 重写技术。(否则我们只需说“strip-request-uri”=>“/webmin”,但这不起作用。这是 lighttpd 1.4 的一个已知且不会修复的问题。另请参阅 mod_rewrite 文档。)但是,我们可以使用 mod_magnet 在 LUA 脚本中重写 URL。

4. mod_magnet 的 LUA 脚本

创建 /var/www/webmin/conf/webmin-rewrite.lua,内容如下:

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

这将从请求 URL 中删除“/webmin”前缀。

5. 修改代码以修复重定向

这几乎已经起作用了,但是,Webmin 的重定向代码中仍然存在一个错误,也提到了这里在 /usr/share/webmin/miniserv.pl 中,将以下行

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

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

并在 /etc/webmin/miniserv.conf 中添加以下行:

subfolder_prefix=/webmin

这修复了 Webmin 登录重定向,您就完成了!

进一步说明

从 lighttpd 1.5 版开始,您可能可以用 mod_proxy_core 替换 LUA 脚本,因为它能够重写请求 URL。不过,我没有尝试过。

此外,由于不再需要从外部访问端口 10000,我建议阻止它:

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

但是,此命令可能因您的本地配置而异。

相关内容