生产环境apache基于域名的虚拟主机配置核心是“配得稳、查得清、扩得快、改得准”:须模块化管理站点配置、显式声明servername/serveralias、最小化目录权限、http仅重定向至https、分离日志并启用hsts。
生产环境用 apache 做基于域名的虚拟主机,核心不是“能不能配出来”,而是“配得稳、查得清、扩得快、改得准”。关键不在语法正确,而在结构清晰、权限明确、日志可溯、变更可控。
配置结构必须模块化、隔离化
不要直接改 /etc/httpd/conf/httpd.conf(RHEL/CentOS)或 /etc/apache2/apache2.conf(Debian/Ubuntu)。主配置只保留全局基础项(MPM、日志格式、模块加载),所有站点配置统一放在独立文件中:
- RHEL系:在 /etc/httpd/conf.d/ 下新建
site1.example.com.conf、site2.example.com.conf,文件名带域名便于识别 - Debian系:在 /etc/apache2/sites-available/ 下创建,再用
a2ensite启用,避免手写符号链接出错 - 每个文件只定义一个
<virtualhost></virtualhost>或<virtualhost></virtualhost>,禁止在一个文件里堆多个站点 - 用
IncludeOptional conf.d/*.conf(2.4.8+)或Include conf.d/*.conf确保加载顺序可控,不依赖文件名排序
域名虚拟主机必须显式声明 ServerName 和 ServerAlias
Apache 2.4 默认启用 NameVirtualHost,但生产环境仍需明确写出,避免隐式匹配导致优先级混乱:
-
ServerName example.com必须是完整主域名,不能省略www或协议 -
ServerAlias www.example.com *.example.com按需补充,通配符仅限子域,不支持多级泛解析(如*.dev.example.com需单独加) - 若同时跑 HTTP 和 HTTPS,两个
<virtualhost></virtualhost>块都要写全ServerName,否则重定向或证书匹配可能失败 - 测试时用
curl -H "Host: example.com" http://127.0.0.1绕过 DNS,验证路由是否准确
目录权限与访问控制必须最小化、显性化
拒绝使用宽松的 Require all granted 全局放行,每个站点根目录的 <directory></directory> 段要精确控制:
-
DocumentRoot "/var/www/example.com/public_html"路径必须存在且属主为root,web 进程用户(如apache或www-data)仅需读取权限 -
<directory></directory>内必须包含:Options -Indexes +FollowSymLinks(禁列目录,允许软链)AllowOverride None(生产禁用 .htaccess,所有规则收归主配置)Require all denied→ 再按需放开特定子路径,如<filesmatch>Require all granted</filesmatch> - 上传目录(如
/uploads)单独设<directory></directory>,禁用脚本执行:SetHandler none+Options -ExecCGI
HTTPS 虚拟主机必须强制重定向、分离日志、启用 HSTS
HTTP 站点仅作 301 跳转,真实服务全部走 HTTPS:
- HTTP
<virtualhost></virtualhost>只留跳转逻辑:Redirect permanent / https://example.com/,不加载 SSL 模块、不设 DocumentRoot - HTTPS
<virtualhost></virtualhost>单独配置:SSLEngine on、SSLCertificateFile、SSLCertificateKeyFile,证书路径用绝对路径,不依赖相对引用 - 每个站点配独立错误日志:
ErrorLog "/var/log/httpd/example.com_error.log",避免混杂难排查 - 添加安全头:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload",启用 HSTS 并提交至浏览器 HSTS 预载列表











