Apache HTTP Server 完全指南 / 虚拟主机配置
虚拟主机配置
虚拟主机(Virtual Hosts)允许一台 Apache 服务器托管多个网站,是共享主机和多站点部署的核心功能。
1. 虚拟主机类型
Apache 支持三种虚拟主机类型:
| 类型 | 描述 | 使用场景 |
|---|---|---|
| 基于域名 | 不同域名指向同一 IP | 最常用,多站点托管 |
| 基于端口 | 不同端口提供不同服务 | 开发测试、内部服务 |
| 基于 IP | 不同 IP 地址 | SSL 传统配置(SNI 前) |
2. 基于域名的虚拟主机
2.1 基本配置
# /etc/apache2/sites-available/example.conf
# 启用基于域名的虚拟主机
NameVirtualHost *:80 # Apache 2.2 需要,2.4 自动启用
<VirtualHost *:80>
# 服务器名称
ServerName www.example.com
ServerAlias example.com www.example.net
# 管理员邮箱
ServerAdmin admin@example.com
# 文档根目录
DocumentRoot /var/www/example.com/public_html
# 日志配置
ErrorLog /var/www/example.com/logs/error.log
CustomLog /var/www/example.com/logs/access.log combined
# 目录配置
<Directory "/var/www/example.com/public_html">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
2.2 多站点配置
# /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
ServerName default.example.com
DocumentRoot /var/www/default
# 默认站点配置
</VirtualHost>
# /etc/apache2/sites-available/site1.conf
<VirtualHost *:80>
ServerName site1.example.com
DocumentRoot /var/www/site1
ErrorLog /var/www/site1/logs/error.log
CustomLog /var/www/site1/logs/access.log combined
<Directory "/var/www/site1">
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
# /etc/apache2/sites-available/site2.conf
<VirtualHost *:80>
ServerName site2.example.com
DocumentRoot /var/www/site2
ErrorLog /var/www/site2/logs/error.log
CustomLog /var/www/site2/logs/access.log combined
<Directory "/var/www/site2">
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
2.3 泛域名配置
# 匹配所有子域名
<VirtualHost *:80>
ServerName example.com
ServerAlias *.example.com
DocumentRoot /var/www/example.com/public_html
# 使用 mod_rewrite 处理子域名
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(.+)\.example\.com$ [NC]
RewriteRule ^(.*)$ /subdomains/%1$1 [L]
</IfModule>
# 子域名目录结构
# /var/www/example.com/public_html/subdomains/blog/
# /var/www/example.com/public_html/subdomains/shop/
</VirtualHost>
2.4 启用站点
# Debian/Ubuntu 方式
sudo a2ensite site1.conf
sudo a2ensite site2.conf
sudo systemctl reload apache2
# 或手动创建符号链接
sudo ln -s /etc/apache2/sites-available/site1.conf /etc/apache2/sites-enabled/
sudo systemctl reload apache2
# 禁用站点
sudo a2dissite site1.conf
sudo systemctl reload apache2
3. 基于端口的虚拟主机
3.1 配置监听端口
# /etc/apache2/ports.conf
Listen 80
Listen 8080
Listen 8443
3.2 端口虚拟主机配置
# 主站点 - 端口 80
<VirtualHost *:80>
ServerName www.example.com
DocumentRoot /var/www/main
</VirtualHost>
# 管理后台 - 端口 8080
<VirtualHost *:8080>
ServerName admin.example.com
DocumentRoot /var/www/admin
# 限制访问
<Directory "/var/www/admin">
Require ip 192.168.1.0/24
Require ip 10.0.0.0/8
</Directory>
</VirtualHost>
# API 服务 - 端口 8443
<VirtualHost *:8443>
ServerName api.example.com
DocumentRoot /var/www/api
# SSL 配置
SSLEngine on
SSLCertificateFile /etc/ssl/certs/api.example.com.crt
SSLCertificateKeyFile /etc/ssl/private/api.example.com.key
</VirtualHost>
3.3 业务场景
开发环境:
# 开发服务器 - 不同端口对应不同项目
<VirtualHost *:80>
ServerName project-a.dev
DocumentRoot /home/dev/projects/a/public
</VirtualHost>
<VirtualHost *:8080>
ServerName project-b.dev
DocumentRoot /home/dev/projects/b/public
</VirtualHost>
<VirtualHost *:3000>
ServerName project-c.dev
DocumentRoot /home/dev/projects/c/public
</VirtualHost>
4. 基于 IP 的虚拟主机
4.1 配置多个 IP
# 添加多个 IP 地址
sudo ip addr add 192.168.1.101/24 dev eth0
sudo ip addr add 192.168.1.102/24 dev eth0
# 或配置网络接口
# /etc/network/interfaces
auto eth0:0
iface eth0:0 inet static
address 192.168.1.101
netmask 255.255.255.0
auto eth0:1
iface eth0:1 inet static
address 192.168.1.102
netmask 255.255.255.0
4.2 IP 虚拟主机配置
# 站点 A - IP 192.168.1.100
<VirtualHost 192.168.1.100:80>
ServerName site-a.example.com
DocumentRoot /var/www/site-a
</VirtualHost>
# 站点 B - IP 192.168.1.101
<VirtualHost 192.168.1.101:80>
ServerName site-b.example.com
DocumentRoot /var/www/site-b
</VirtualHost>
# 站点 C - IP 192.168.1.102
<VirtualHost 192.168.1.102:80>
ServerName site-c.example.com
DocumentRoot /var/www/site-c
</VirtualHost>
4.3 通配符 IP
# 监听所有 IP
<VirtualHost *:80>
ServerName default.example.com
DocumentRoot /var/www/default
</VirtualHost>
# 监听特定 IP
<VirtualHost 192.168.1.100:80>
ServerName example.com
DocumentRoot /var/www/example
</VirtualHost>
5. SSL 虚拟主机
5.1 基本 SSL 配置
# 启用 SSL 模块
# sudo a2enmod ssl
<VirtualHost *:443>
ServerName www.example.com
DocumentRoot /var/www/example.com/public_html
# SSL 配置
SSLEngine on
SSLCertificateFile /etc/ssl/certs/www.example.com.crt
SSLCertificateKeyFile /etc/ssl/private/www.example.com.key
SSLCertificateChainFile /etc/ssl/certs/chain.pem
# SSL 协议和密码套件
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder on
# 日志
ErrorLog /var/www/example.com/logs/ssl-error.log
CustomLog /var/www/example.com/logs/ssl-access.log combined
</VirtualHost>
5.2 HTTP 到 HTTPS 重定向
# 方法 1:使用 mod_rewrite
<VirtualHost *:80>
ServerName www.example.com
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>
# 方法 2:使用 Redirect
<VirtualHost *:80>
ServerName www.example.com
Redirect permanent / https://www.example.com/
</VirtualHost>
# 方法 3:使用 mod_alias
<VirtualHost *:80>
ServerName www.example.com
RedirectMatch permanent ^/(.*)$ https://www.example.com/$1
</VirtualHost>
5.3 SNI(Server Name Indication)
SNI 允许在一个 IP 上托管多个 SSL 站点:
# 站点 A
<VirtualHost *:443>
ServerName site-a.example.com
DocumentRoot /var/www/site-a
SSLEngine on
SSLCertificateFile /etc/ssl/certs/site-a.crt
SSLCertificateKeyFile /etc/ssl/private/site-a.key
</VirtualHost>
# 站点 B
<VirtualHost *:443>
ServerName site-b.example.com
DocumentRoot /var/www/site-b
SSLEngine on
SSLCertificateFile /etc/ssl/certs/site-b.crt
SSLCertificateKeyFile /etc/ssl/private/site-b.key
</VirtualHost>
6. 虚拟主机配置最佳实践
6.1 配置模板
# /etc/apache2/sites-available/template.conf
<VirtualHost *:80>
# 基本配置
ServerName DOMAIN_NAME
ServerAlias www.DOMAIN_NAME
ServerAdmin admin@DOMAIN_NAME
DocumentRoot /var/www/DOMAIN_NAME/public_html
# 日志配置
ErrorLog /var/www/DOMAIN_NAME/logs/error.log
CustomLog /var/www/DOMAIN_NAME/logs/access.log combined
# 目录配置
<Directory "/var/www/DOMAIN_NAME/public_html">
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
</Directory>
# 安全头
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-XSS-Protection "1; mode=block"
</IfModule>
# 禁止访问隐藏文件
<FilesMatch "^\.">
Require all denied
</FilesMatch>
</VirtualHost>
6.2 脚本化配置
#!/bin/bash
# add-vhost.sh - 添加虚拟主机脚本
DOMAIN=$1
DOCROOT="/var/www/${DOMAIN}/public_html"
LOGDIR="/var/www/${DOMAIN}/logs"
# 创建目录
sudo mkdir -p ${DOCROOT} ${LOGDIR}
# 设置权限
sudo chown -R www-data:www-data /var/www/${DOMAIN}
sudo chmod -R 755 /var/www/${DOMAIN}
# 创建配置文件
sudo tee /etc/apache2/sites-available/${DOMAIN}.conf > /dev/null <<EOF
<VirtualHost *:80>
ServerName ${DOMAIN}
ServerAlias www.${DOMAIN}
DocumentRoot ${DOCROOT}
ErrorLog ${LOGDIR}/error.log
CustomLog ${LOGDIR}/access.log combined
<Directory "${DOCROOT}">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
EOF
# 启用站点
sudo a2ensite ${DOMAIN}.conf
sudo systemctl reload apache2
echo "Virtual host ${DOMAIN} created successfully!"
6.3 验证虚拟主机配置
# 检查虚拟主机配置
apachectl -S
# 输出示例:
# VirtualHost configuration:
# *:80 is a NameVirtualHost
# default server default.example.com (/etc/apache2/sites-enabled/000-default.conf:1)
# port 80 namevhost default.example.com (/etc/apache2/sites-enabled/000-default.conf:1)
# port 80 namevhost site1.example.com (/etc/apache2/sites-enabled/site1.conf:1)
# alias www.site1.example.com
# port 80 namevhost site2.example.com (/etc/apache2/sites-enabled/site2.conf:2)
# 测试配置语法
apachectl configtest
# 测试特定域名
curl -H "Host: site1.example.com" http://localhost/
7. 注意事项
- 配置顺序:Apache 按配置文件加载顺序处理虚拟主机,第一个匹配的配置生效
- 默认站点:建议配置一个默认虚拟主机作为兜底
- 日志分离:每个虚拟主机使用独立的日志文件
- 权限控制:确保 Apache 用户对所有文档根目录有读取权限
- DNS 配置:基于域名的虚拟主机需要正确的 DNS 解析
- 端口冲突:避免多个虚拟主机监听相同端口
8. 扩展阅读
9. 总结
虚拟主机是 Apache 最强大的功能之一:
- 基于域名:最常用,支持 SNI 的 SSL
- 基于端口:适合开发测试和内部服务
- 基于 IP:传统方式,现在较少使用
合理规划虚拟主机结构可以提高服务器资源利用率,简化管理。