在正常情况下,使用 ProxyPass /.well-known 可以轻松设置带有 letsencrypt 例外的 apache 反向代理,用于 /.well-known !配置此例外以及后端的 ip 限制似乎变得更加困难(我碰巧在 nginx 中轻松解决了这个问题):
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
Redirect / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/bfp-all_error.log
CustomLog ${APACHE_LOG_DIR}/bfp-all_access.log combined
RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /(.*) ws://localhost:8050/$1 [P,L]
ProxyRequests Off
ProxyPreserveHost On
<Location />
ProxyPass "http://localhost:8050/"
ProxyPassReverse "http://localhost:8050/"
Require ip 10.0.0.0/24
Require ip 192.168.0.0/24
</Location>
</VirtualHost>
我尝试在该部分之前使用别名和(以及目录,似乎已经相当冗余),但请求仍然转到后端:
DocumentRoot /var/web/letsencrypt
Alias /.well-known /var/web/letsencrypt/.well-known
<Directory /var/web/letsencrypt/.well-known>
Options -Indexes
Require all granted
</Directory>
<Location /.well-known>
ProxyPass !
Require all granted
</Location>
有什么办法可以解决这个问题吗?我原本以为这是一个人们时不时会遇到的问题,但我在互联网上没有找到任何东西。
答案1
在这种情况下,让请求通过后端的“原因”是因为带有 [P] 的 RewriteRule 会绕过带有 ProxyPass 指令的 Location 块(以及其匹配范围内的任何可能的位置块)。因此,它们和其中的 Require 规则都将被忽略,并且请求将针对所有 IP 地址进行代理。
如果您省略 RewriteRule 并将 放入ws://localhost:8050/
ProxyPass 规则中<Location>
,它将按预期工作。最具体的 Location 块将在涉及 Require 设置和 ProxyPass 设置的配置合并中获胜。如果更不具体的 Location 块设置了 Require 或 ProxyPass,则能在最具体的位置块中用新的覆盖它。
Websocket 代理本身将阻止没有升级标头的请求。
从 Apache 2.4.19 开始,可以将 .well-known Alias 直接放入 Location 块中,而省略第一个参数。