Apache2配置问题:禁止通过公网IP访问站点,仅允许通过主机名访问
Apache2配置问题:禁止通过公网IP访问站点,仅允许通过主机名访问
看起来你遇到的是Apache默认虚拟主机的典型问题——当请求没有匹配到任何ServerName/ServerAlias时,Apache会自动把第一个加载的虚拟主机作为默认站点返回。这就是为什么用公网IP访问时总是跳转到site1的原因,哪怕你禁用了site1的80端口配置,它的HTTPS配置(site1-le-ssl.conf)可能还是第一个被加载的,所以依然会被匹配到。
下面是具体的解决步骤,亲测有效:
1. 创建一个优先级最高的“拦截IP访问”虚拟主机
Apache的站点配置是按文件名顺序加载的,所以我们要创建一个以000-开头的配置文件,确保它比site1、site2的配置先加载,成为默认虚拟主机,专门处理所有未匹配到指定主机名的请求(包括公网IP访问)。
首先创建一个空目录(用来返回403,也可以不用,但这样更规范):
sudo mkdir /var/www/empty-block-dir
然后在/etc/apache2/sites-available/目录下新建000-ip-block.conf文件,内容如下:
# 处理HTTP(80端口)的IP访问请求 <VirtualHost *:80> ServerAdmin me@mydomain.com # 不设置ServerName,这样会匹配所有未指定主机名的HTTP请求 DocumentRoot /var/www/empty-block-dir <Directory /var/www/empty-block-dir> Require all denied </Directory> # 直接返回403 Forbidden,也可以自定义提示页 RewriteEngine On RewriteRule ^ - [R=403,L] ErrorLog ${APACHE_LOG_DIR}/ip_block_error.log CustomLog ${APACHE_LOG_DIR}/ip_block_access.log combined </VirtualHost> # 处理HTTPS(443端口)的IP访问请求 <IfModule mod_ssl.c> <VirtualHost *:443> ServerAdmin me@mydomain.com # 同样不设置ServerName,匹配所有未指定主机名的HTTPS请求 DocumentRoot /var/www/empty-block-dir <Directory /var/www/empty-block-dir> Require all denied </Directory> RewriteEngine On RewriteRule ^ - [R=403,L] # 这里需要配置一个SSL证书(可以用自签的,因为IP访问本来就不会有合法证书) # 如果没有自签证书,也可以用Apache默认的,或者注释掉,不过可能会有证书警告,但不影响返回403 SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key ErrorLog ${APACHE_LOG_DIR}/ip_block_ssl_error.log CustomLog ${APACHE_LOG_DIR}/ip_block_ssl_access.log combined </VirtualHost> </IfModule>
2. 启用这个拦截配置并重新加载Apache
执行以下命令:
sudo a2ensite 000-ip-block.conf sudo systemctl reload apache2
3. 验证配置是否生效
用apache2ctl -S命令查看当前虚拟主机的加载顺序,你应该能看到我们创建的000-ip-block.conf是第一个被列为默认虚拟主机的:
sudo apache2ctl -S
此时再用公网IP访问,就会返回403 Forbidden,而通过site1.mydomain.com或site2.mydomain.com访问时,依然能正常加载对应的站点。
为什么之前的操作没用?
- 禁用site1.conf后,site1-le-ssl.conf依然在启用状态,而Apache会把第一个加载的HTTPS虚拟主机作为默认,所以IP访问HTTPS时还是会匹配到site1。
- 修改
apache2.conf里的/var/www/权限,会被site1配置里的<Directory /var/www/site1>中的Require all granted覆盖,因为目录级的配置优先级更高。
备注:内容来源于stack exchange,提问作者Jason Adams
相关产品推荐
相关产品推荐

