在Linux系统中,Apache HTTP服务器支持基于IP地址的虚拟主机配置,其核心机制是通过识别客户端请求到达的不同IP地址,将流量路由至对应的文档根目录,实现多个网站共存于同一台服务器但使用不同公网IP的效果,此功能依赖于主配置文件(通常为/etc/httpd/conf/httpd.conf或/etc/apache2/apache2.conf)中的监听指令和<VirtualHost>块定义。
环境准备
系统要求
| 组件 | 版本建议 | 备注 |
|---|---|---|
| Linux内核 | ≥2.6 | 现代发行版均满足 |
| Web服务器 | Apache | 推荐使用默认安装包管理工具安装(如yum/apt) |
| 网卡配置 | 多块物理接口或别名 | 需提前绑定额外IP到网络接口 |
添加辅助IP示例(以CentOS为例)
# 查看当前网络接口名称(假设主网卡为ens33) ip link show # 给ens33添加第二个IPv4地址192.168.1.100/24 nmcli connection modify "System ens33" +ipv4.addresses 192.168.1.100/24 # 重启网络服务使生效 systemctl restart NetworkManager
验证命令:
ip a show dev ens33应显示新增的IPv4地址。
配置步骤详解
修改主配置文件
编辑Apache主配置文件(路径可能因发行版而异):
vi /etc/httpd/conf/httpd.conf
定位到Listen指令部分,默认仅监听所有接口的80端口:
Listen 80
改为明确指定主域名对应的IP+端口组合(例如主站用默认网关IP):
Listen 192.168.1.50:80 # 原主站IP Listen 192.168.1.100:80 # 新增虚拟主机IP
️ 注意:若使用IPv6需添加方括号包裹地址如
[::1]:80。
创建虚拟主机条目
在文件末尾追加<VirtualHost>块:
<VirtualHost 192.168.1.100:80>
ServerAdmin admin@example.com
DocumentRoot "/var/www/html_vhost1" # 该站点的网页存放路径
ErrorLog logs/vhost1_error.log # 错误日志路径
CustomLog logs/vhost1_access.log combined # 访问日志格式
<Directory "/var/www/html_vhost1">
AllowOverride None # 禁止.htaccess覆盖配置
Require all granted # 允许所有用户访问
</Directory>
</VirtualHost>
同步更新原始默认虚拟主机配置(通常已存在):
<VirtualHost 192.168.1.50:80>
DocumentRoot "/var/www/html" # 默认站点路径
...其他原有设置...
</VirtualHost>
目录权限设置
确保新创建的文档目录归属正确且具备读权限:
mkdir -p /var/www/html_vhost1 chown -R apache:apache /var/www/html_vhost1 # CentOS系用户组名可能为www-data(Debian/Ubuntu) chmod -R 755 /var/www/html_vhost1 # 限制执行权限增强安全性
测试配置文件有效性
执行以下命令检查语法错误:
apachectl configtest # CentOS/RHEL apache2ctl configtest # Debian/Ubuntu
输出应显示Syntax OK,否则根据报错信息修正配置。
服务重启与验证
平滑重启Web服务
systemctl restart httpd # CentOS/RHEL systemctl restart apache2 # Debian/Ubuntu
客户端测试方法
| 测试方式 | 操作示例 | 预期结果 |
|---|---|---|
| CURL命令 | curl -I http://192.168.1.100 |
HTTP头中应包含Server字段 |
| 浏览器访问 | 输入URL http://192.168.1.100 |
显示对应目录下的默认页面 |
| Netstat监听端口确认 | netstat -tunlp | grep :80 |
看到两个PID分别绑定不同IP的80端口 |
常见问题排查指南
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 访问IP报404 Not Found | DocumentRoot路径错误 | 检查路径是否存在且拼写正确 |
| 日志无记录 | ErrorLog/CustomLog路径未授权 | 确保日志目录可写且路径绝对化(如/var/log/httpd/...) |
| 端口被防火墙拦截 | firewalld未放行新IP的流量 | 执行firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address=192.168.1.100/32 port protocol=tcp port=80 accept' && firewall-cmd reload |
| SELinux阻止访问 | 安全策略限制 | 临时关闭测试:setsebool -P httpd_enable_homedirs on;长期方案见官方文档 |
相关问题与解答
Q1: 如果两个虚拟主机使用相同端口会怎样?
A: Linux网络栈允许同一台设备的不同IP绑定到相同端口(如TCP四元组中的源IP不同),因此只要每个<VirtualHost>指定唯一的IP地址,即可正常共存,但若尝试在同一IP上绑定多个服务,则必须使用不同端口号。
Q2: 修改配置后重启Apache报错“Address already in use”,如何处理?
A: 此错误通常由以下原因导致:①残留进程占用端口(用lsof -i :80查找并kill -9 PID);②配置文件中重复定义了相同的IP+端口组合(检查所有Listen指令和<VirtualHost>块的唯一性);③系统级防火墙规则冲突(通过iptables -L -n或firewalld --list-all排查),建议逐步排查上述可能性,优先终止异常进程并修正配置文件
