我已经在我的服务器上设置了一个子域名(staging.callkneehill.ca)并且创建了一个具有以下参数的.htaccess 文件:
<RequireAny>
Require ip 70.65.194.109
</RequireAny>
ErrorDocument 403 "Restricted Access"
当我尝试访问子域时,即使我的 IP 地址与所需值匹配,也会显示 403 错误。
如果我注释掉 .htaccess 中的所有代码,index.html 就会加载。
以下是子域名的虚拟主机配置:
<VirtualHost *:80>
ServerName staging.callkneehill.ca
ServerAdmin webmaster@localhost
DocumentRoot /var/www/staging/
ErrorLog ${APACHE_LOG_DIR}/staging-error.log
CustomLog ${APACHE_LOG_DIR}/staging-access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =staging.callkneehill.ca
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<Directory /var/www/staging/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
# SetHandler "proxy:unix:/run/php/php7.4-callkneehill-fpm.sock|fcgi://localhost"
</FilesMatch>
根域上的 .htaccess 文件使用 WordPress 正常运行。我比较了虚拟主机配置文件,发现两者的一般参数都相同。
我也测试过使用 Apache 2.2 的 IP 阻止,但仍然存在同样的问题。
每次更新配置文件时,我都会重新加载并重新启动 Apache。
有人能指出我遗漏了什么吗?
更新
暂存访问日志输出
172.68.189.103 - - [18/May/2021:13:57:15 +0000] "GET / HTTP/1.1" 403 5454 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:88.0) Gecko/20100101 Firefox/88.0"
172.68.143.156 - - [18/May/2021:13:57:15 +0000] "GET /favicon.ico HTTP/1.1" 403 5454 "https://staging.callkneehill.ca/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:88.0) Gecko/20100101 Firefox/88.0"
172.68.189.229 - - [18/May/2021:14:02:11 +0000] "GET / HTTP/1.1" 301 598 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Safari/605.1.15"
172.68.132.65 - - [18/May/2021:14:02:11 +0000] "GET / HTTP/1.1" 403 5454 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Safari/605.1.15"
172.68.143.156 - - [18/May/2021:14:02:11 +0000] "GET /favicon.ico HTTP/1.1" 403 5454 "https://staging.callkneehill.ca/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Safari/605.1.15"
162.158.255.248 - - [18/May/2021:14:03:07 +0000] "GET / HTTP/1.1" 403 5454 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1"
我的 IP 地址似乎可变。这是因为我在 MacBook Pro 上使用 Cloudflare 的 1.1.1.1 作为 DNS 吗?
同样的问题影响了同一本地网络上启用/禁用 VPN 的我的 iPhone。
答案1
这是否是因为我在 MacBook Pro 上使用 Cloudflare 的 1.1.1.1 作为 DNS
不会。(但如果你的领域指向 Cloudflare 的 DNS。)
您的“更新”中列出的 IP 地址都是 Cloudflare IP。这表明您正在使用 Cloudflare CDN(即域上的 NAMESERVERS 指向 Cloudflare) - 它充当原始服务器前面的反向代理。换句话说,所有发送到原始服务器的请求都来自 Cloudflare。
实际客户端 IP 地址通过各种 HTTP 请求标头传递到您的原始服务器(取决于 Cloudflare 的配置方式)。事实上的标准标头是X-Forwarded-For
- 但请注意,这可能包含多个 IP(以逗号分隔),具体取决于请求是否通过了多个代理。并且Cloudflare附加客户端 IP 地址,而不是前缀(这违反了公约)。其他 Cloudflare 特定的(首选)标头是CF-Connecting-IP
和,True-Client-IP
其中包含单个客户IP地址。
参考:
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
- https://support.cloudflare.com/hc/en-us/articles/200170986-Cloudflare 如何处理 HTTP 请求头-
- https://support.cloudflare.com/hc/en-us/articles/206776727-Understanding-the-True-Client-IP-Header
<RequireAny> Require ip 70.65.194.109 </RequireAny> ErrorDocument 403 "Restricted Access"
因此,您不需要执行上述操作,而是需要在.htaccess
文件中执行类似以下的操作:
ErrorDocument 403 "Restricted Access"
SetEnvIf CF-Connecting-IP "^70\.65\.194\.109$" ALLOWED_IP=1
Require env ALLOWED_IP
<RequireAny>
省略时是默认值,因此这里不需要。
使用 mod_remoteip 的替代方案
但是,上述方法并不能解决日志中报告 Cloudflare IP 而不是实际客户端 IP 地址的“问题”。
或者,您可以启用 Apache 的 mod_remoteip 来告知 Apache 如何检索客户端 IP 地址(为了进行Require ip
日志记录)。
例如,一旦启用 mod_remoteip,则在您的服务器配置中:
# Header that contains the client IP address
RemoteIPHeader CF-Connecting-IP
为了增加安全性,您可以指定允许的 Cloudflare IP 列表在外部文件中:
# List of valid user-agent IPs
RemoteIPInternalProxyList /var/www/cloudflare-ips.lst
然后,您无需修改现有Require ip 70.65.194.109
指令。但您仍需要修改自定义指令,LogFormat
以便记录客户端 IP。您需要将%h
格式字符串开头的 (远程主机/ip) 更改为%a
(mod_remoteip 设置的客户端 IP)。
例如,如果您使用combined
日志格式(看起来像是),那么:
LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
参考:
- https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html
- https://httpd.apache.org/docs/current/mod/mod_log_config.html
在旁边:
RewriteEngine on RewriteCond %{SERVER_NAME} =staging.callkneehill.ca RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
您发布的 vHost 配置(针对端口 80)只是重定向到 HTTPS(端口 443) - 您未包含的配置。
但你不需要检查SERVER_NAME
这里的请求,因为它只能是分期指令定义的主机名ServerName
(假设您有一个默认vHost 已在前面定义)。事实上,你根本不需要 mod_rewrite,一个简单的 mod_aliasRedirect
指令会更好:
Redirect 301 / https://staging.callkneehill.ca/