Apache 2.4.x如何配置以忽略Host头不匹配指定域名的请求?
嘿,你的问题很典型——其实光靠现有的两个ServerName配置是达不到你想要的“忽略不匹配请求”效果的。
Apache的虚拟主机匹配逻辑是这样的:当收到一个请求时,它会按配置文件里的顺序查找第一个ServerName(或ServerAlias)匹配Host头的虚拟主机。如果找不到任何匹配的,它会把请求交给第一个定义的虚拟主机处理。所以现在你的情况是,所有不匹配foobar.com和www.foobar.com的请求,都会被第一个foobar.com的虚拟主机接收,然后被重定向到www.foobar.com,这显然不是你想要的“忽略”结果。
要实现你要的效果,你需要添加一个默认虚拟主机,把它放在所有其他虚拟主机的最前面,专门用来捕获所有不匹配指定域名的请求,然后让Apache直接拒绝这些请求。
这里给你一个具体的配置方案:
# 这是默认虚拟主机,必须放在所有其他VirtualHost前面 <VirtualHost *:443> # 随便设一个不会被用到的ServerName就行 ServerName invalid.local # 启用RewriteEngine,用Apache特有的444状态码直接关闭连接,不返回任何响应 RewriteEngine On RewriteRule ^ - [R=444,L] # 因为监听443端口,必须配置SSL证书 # 可以用和主站相同的证书(如果证书包含你的两个域名),或者自签证书 SSLEngine on SSLCertificateFile /path/to/your/certificate.pem SSLCertificateKeyFile /path/to/your/private-key.pem </VirtualHost> # 你原有的foobar.com跳转虚拟主机 <VirtualHost *:443> ServerName foobar.com RedirectMatch /(.*) https://www.foobar.com/$1 SSLEngine on SSLCertificateFile /path/to/your/certificate.pem SSLCertificateKeyFile /path/to/your/private-key.pem # 其他原有配置... </VirtualHost> # 你原有的www.foobar.com主虚拟主机 <VirtualHost *:443> ServerName www.foobar.com ServerAdmin webmaster@localhost DocumentRoot /var/www/html SSLEngine on SSLCertificateFile /path/to/your/certificate.pem SSLCertificateKeyFile /path/to/your/private-key.pem # 其他原有配置... </VirtualHost>
这里重点说一下444状态码:这是Apache专属的状态码,它会让服务器直接关闭TCP连接,不返回任何HTTP响应,完美符合你“忽略请求”的需求。如果你用普通的404,服务器还是会返回一个404错误页面,达不到完全忽略的效果。
另外要注意,因为默认虚拟主机监听的是443端口(HTTPS),所以必须配置SSL证书。你可以直接复用主站的证书(只要证书包含foobar.com和www.foobar.com这两个域名),或者生成一个自签证书——虽然客户端访问时会弹出SSL警告,但不影响我们拒绝不匹配请求的核心功能。
配置完成后,重启Apache服务,这样所有Host头不匹配foobar.com和www.foobar.com的请求,都会被默认虚拟主机捕获,然后直接关闭连接,不会得到任何响应。
备注:内容来源于stack exchange,提问作者andynewman

