单服务器部署两个网站,访问服务器IP为何指向其中一个而非根目录?
场景说明
你在Apache服务器上配置了两个虚拟主机,目录结构如下:
/var/www/html/ | ---- domain1.com/ | |___ index.html | ... 其他站点内容 | ---- domain2.com/ | |___ index.html | ... 其他站点内容
启用的两个虚拟主机配置文件:
- domain1.com.conf
<VirtualHost *:80> ServerAdmin admin@domain1.com DocumentRoot /var/www/html/domain1.com ServerName domain1.com </VirtualHost>
- domain2.com.conf
<VirtualHost *:80> ServerAdmin admin@domain2.com DocumentRoot /var/www/html/domain2.com ServerName domain2.com </VirtualHost>
执行以下命令启用站点并重载Apache后,访问两个域名正常,但访问服务器IP时显示domain1.com的内容:
a2ensite domain1.com.conf domain2.com.conf systemctl reload apache2
原因分析
这是因为Apache会将第一个加载的虚拟主机作为默认站点。当客户端请求的Host头(比如访问IP时,Host头为服务器IP,无法匹配任何虚拟主机的ServerName或ServerAlias)未命中已配置的虚拟主机时,Apache就会使用这个默认站点响应请求。
你通过a2ensite同时启用两个站点时,Apache会按/etc/apache2/sites-enabled/目录下文件名的字母顺序加载配置,domain1.com.conf的字母排序早于domain2.com.conf,因此它被优先加载,成为默认站点。这就导致访问IP时,请求没有匹配到对应域名,直接返回domain1的内容。
解决办法
1. 调整默认站点的加载顺序
如果想让其他站点(比如domain2)成为IP访问的默认响应站点,可以修改目标配置文件的文件名,让它的字母排序最靠前。例如将domain2.com.conf改名为000-domain2.com.conf(数字开头的文件名会排在字母开头的文件之前)。
修改后重载Apache生效:
systemctl reload apache2
此时domain2会成为默认站点,访问IP时会触发它的访问认证。
2. 创建专门的IP访问处理站点
如果不想让业务站点响应IP访问,可以创建一个单独的虚拟主机配置文件(比如000-ip-default.conf),用来处理IP请求,比如返回自定义提示或404页面:
<VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/html/ip-default # 可以指定ServerName为你的服务器IP ServerName 192.168.x.x # 自定义访问提示 ErrorDocument 404 /index.html </VirtualHost>
创建对应目录和页面,启用站点并重载:
mkdir /var/www/html/ip-default echo "<h1>Invalid Access</h1>" > /var/www/html/ip-default/index.html a2ensite 000-ip-default.conf systemctl reload apache2
之后访问服务器IP时会返回这个自定义页面,不会再显示业务站点内容。
内容的提问来源于stack exchange,提问作者Another Dude

