Apache 速查:VirtualHost、mod_rewrite 与 .htaccess 配置实战
围绕 Apache HTTP Server 日常运维,讲清虚拟主机按域名分站、mod_rewrite 重写规则、.htaccess 取舍、反向代理与 403 排查,附真实配置片段和常用命令。
Apache 速查:VirtualHost、mod_rewrite 与 .htaccess 配置实战
Apache HTTP Server 跑了二十多年,配置语法稳定到几乎不变,但真正上手时,麻烦往往不在语法,而在于记不住指令该写在哪、改完怎么安全重载、报错从哪看。这篇把日常会反复查的几块配置串起来:虚拟主机分站、重写规则、.htaccess 取舍、反向代理,以及最常见的 403 怎么定位。
虚拟主机:一台机器按域名分站
一台服务器同时托管多个站点,靠的就是 VirtualHost。Apache 在收到请求时,先看 Host 头,再匹配 ServerName 和 ServerAlias,把请求路由到对应的 vhost。这就是「按域名分站」的核心:同一个 IP、同一个 80 端口,a.com 和 b.com 各自指向不同的 DocumentRoot。
一段最小可用的配置长这样:
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
DocumentRoot /var/www/example
<Directory "/var/www/example">
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example_error.log
CustomLog ${APACHE_LOG_DIR}/example_access.log combined
</VirtualHost>
这里有几个点值得记牢。Require all granted 是 Apache 2.4 的放行写法,旧版的 Order allow,deny 已经不用了。Options -Indexes 关掉目录列表,公共目录没有 index 文件时就不会把整个目录暴露成下载页。AllowOverride None 表示这个目录不读 .htaccess,性能更好,也更可控。
多站点时,每个站一个 vhost 文件,放在 Debian 的 sites-available/ 再 a2ensite 启用,或 RHEL 的 conf.d/ 里直接生效。结构清楚,排查时也快。
mod_rewrite:重写规则怎么写才不绕
重写是 Apache 里最容易写错的部分。RewriteRule 的两个参数是「匹配模式」和「替换目标」,配合 RewriteCond 做条件判断。一个常见需求是把所有 HTTP 跳到 HTTPS:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
[R=301,L] 里的 R=301 是永久重定向,L 表示这是最后一条规则、命中后停止。写重写时最容易踩的坑是忘了 L,导致规则继续往下跑,跳转链莫名其妙。另一个是路径前导斜杠:在 vhost 里 RewriteRule 的模式带 /,在 .htaccess 里则不带,因为目录上下文已经把前缀剥掉了。
.htaccess:什么时候该用,什么时候别用
如果你能改主配置,就别用 .htaccess。主配置能用 apachectl configtest 提前检查语法,能走代码审查,性能也更好,因为不需要每个请求都去目录里扫一遍 .htaccess。只有在共享主机、改不了 httpd.conf,或确实需要按目录做覆盖时,.htaccess 才是合适选择。
要让 .htaccess 生效,对应目录的 AllowOverride 必须放开相应能力,比如重写需要 AllowOverride FileInfo。但别图省事写成 AllowOverride All,那会让每个请求都全量扫描 .htaccess,还允许目录规则覆盖你审过的 vhost 配置。能收窄就收窄。
反向代理与 403 排查
把应用服务接到 Apache 后面,用的是 ProxyPass 和 ProxyPassReverse。这两条要成对写:前者把请求转给上游,后者把上游返回的重定向头改回对外的地址,否则上游的内网主机名会漏给用户。
ProxyPass /api http://127.0.0.1:8080/
ProxyPassReverse /api http://127.0.0.1:8080/
我自己排 403 时有个固定顺序:先看匹配到的 <Directory> 块有没有 Require all granted,再确认 www-data 或 apache 用户能不能读到 DocumentRoot 和文件,最后 tail -f error log 看 Apache 实际尝试打开的是哪条路径。十有八九是权限或某条 .htaccess 把 vhost 规则盖掉了,日志里那行报错会直接点名。
改完配置别急着 restart,先 apachectl configtest,看到 Syntax OK 再用 apachectl graceful 或 systemctl reload apache2 优雅重载,已有连接不会被掐断。
把上面这些指令和命令分类查、随手复制,可以直接打开 Apache 速查表,粘一小段配置还能检测已识别指令和常见风险。如果你的栈是 Nginx,对照着看 Nginx 速查表 会更顺手。
Made by Toolora · Updated 2026-06-13