Apache 中的 Anubis 实现真的需要3个虚拟主机吗?

我正在尝试在Linux Debian + Apache服务器上配置Anubis,以满足我的需求。
具体来说,我希望能够快速为每个虚拟主机启用或禁用Anubis,同时尽可能减少与先前配置的改动。

文档中有关于Apache配置的说明页面:
https://anubis.techaro.lol/docs/admin/environments/apache

该页面提及在原有两个虚拟主机基础上新增了专用于3001端口的第三个虚拟主机。
由于我不喜欢这种做法,尝试了在保留两个虚拟主机的前提下实现的方法。

我认为通过以下方式可实现:

  1. 将首个虚拟主机定义为 <VirtualHost *:80 *:3001> 替代 <VirtualHost *:80>
  2. 在该虚拟主机的RewriteRule规则中添加条件,当远程主机为::1时触发规则。

由此重写序列呈现如下形式:

元素周期表
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REMOTE_ADDR} !^::1$
RewriteRule (.*) https://%{SERVER_NAME}$1 [R,L]
 

关于启停控制,我仅添加了如下代理指令:

<IfFile /etc/anubis/mysite.env>
     Include /etc/apache2/anubis_proxy.conf
</IfFile>

…其中/etc/apache2/anubis_proxy.conf包含标准指令:

# 这些头部必须设置,否则Anubis将抛出“管理员配置错误”。
RequestHeader set "X-Real-Ip" expr=%{REMOTE_ADDR}
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set "X-Http-Version" "%{SERVER_PROTOCOL}s"

ProxyPreserveHost On

ProxyRequests Off
ProxyVia Off

ProxyPass / http://[::1]:8923/
ProxyPassReverse / http://[::1]:8923/

通过这种方式,只需添加、重命名或删除/etc/anubis/mysite.env文件即可启用或禁用Anubis(若所有配置通用,该文件甚至可仅作为通用文件的符号链接)。

显然,该方案可行。

进一步思考时我产生疑问:
既然现已存在规则条件进行区分,是否真的必须使用3001端口?

我尝试取消端口限制,将TARGET值定义为TARGET=http://localhost:80而非TARGET=http://localhost:3001
同时将配置简化为<VirtualHost *:80>

显然,至少在我的测试服务器上,这种配置依然有效。

是否有理由不验证这种方案?是否应该避免将测试环境中看似有效的配置直接复制到生产环境?

damienvancouver:

是的,您说得对,可以跳过 :3001 虚拟主机,改用 :80 虚拟主机。

但关键点在于:在实际生产环境中,该 :80 虚拟主机正用于 HTTP 到 HTTPS 的实时重定向。当访客通过 http://example.com 访问时,需将其重定向至 https://example.com。但当 Anubis 访问 http://example.com 时,既不能重定向,还需输出所有链接(如 CSS/JS 文件及其他静态资源)均包含 “https://” 的 HTML 内容。

借助Apache的mod_rewritemod_setenvif模块,这很容易实现。以下是我的实现方法:

Apache模块:启用rewritesetenvif

Apache 80端口配置:

<VirtualHost *:80>
ServerName example.com
Serveralias www.example.com

RewriteEngine On 
# 将除LetsEncrypt外的所有HTTP流量转发至HTTPS,保持相同URL
RewriteCond %{REQUEST_URI} !^/.well-known [NC]
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
####/CTAR002 force SSL

# 否则,若此请求来自Anubis的代理请求,请设置HTTPS=on以获取HTTP链接输出:
SetEnvIf X-Forwarded-Proto https HTTPS=on

#  ... 其余虚拟主机配置内容在此处,包括日志记录、PHP设置等。操作方式与您在*:443端口上的常规配置完全相同!

</VirtualHost>

apache port 443 configuration:

<Virtualhost *:443>
  ServerName example.com
  Serveralias www.example.com

    # Proxy via anubis at 127.0.0.1:8923
       RequestHeader set "X-Real-Ip" expr=%{REMOTE_ADDR}
       RequestHeader set "X-Forwarded-For" expr=%{REMOTE_ADDR}
       RequestHeader set X-Forwarded-Proto "https"
       RequestHeader set "X-Http-Version" "%{SERVER_PROTOCOL}s"
       ProxyPreserveHost On
       ProxyRequests Off
       ProxyVia Off
       ProxyPass / http://127.0.0.1:8923/  nocanon
       ProxyPassReverse / http://127.0.0.1:8923/  nocanon

因此端口80虚拟主机有两种处理方式:

  • 若未检测到X-Forwarded-Proto=https且非LetsEncrypt证书,则将所有流量转发至SSL
  • 否则,它会启用HTTPS并通过http://localhost:80端口提供服务

端口443虚拟主机仅将所有请求代理至Anubis。若移除Anubis配置,则会恢复直接提供网站服务。

此配置的唯一缺陷在于:若配置有误,极易引发301重定向循环。虽然采用:3001方案更易部署,但我更倾向于仅使用两个虚拟主机。

GingkoFr:

这就是为什么我不使用条件语句 RewriteCond %{HTTP:X-Forwarded-Proto} !https
我采用的是 RewriteCond %{REMOTE_ADDR} !^::1$

原始请求从 ::1 地址发出的可能性极低,即便发生这种情况,通常也不需要将其重定向到 https 或 Anubis。

damienvancouver:

是的,这样应该没问题!任何能将Anubis与真实/外部80端口流量区分开的方法都可行。外部流量不可能来自本地主机。

但这仍需处理当请求来自Anubis时启用HTTPS的设置。因此您可能仍需在:80虚拟主机配置中至少添加SetEnv HTTPS=on指令。由于您已通过RewriteRule规则处理所有非Anubis流量,可能无需像我之前那样使用SetEnvIf条件语句。

?????同样的道理,是否可以直接使用 :443 端口替代:3001端口?

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注


京ICP备12002735号