Apache 开启 AllowOverride 后报 500,日志显示 Invalid command RewriteEngine
允许读取 .htaccess 后出现 500,日志报 RewriteEngine 未识别。核对 mod_rewrite 加载,再按应用需要配置覆盖范围,并实际验证路由。
网站迁移到 Ubuntu 的 Apache 2.4 后,原来忽略 .htaccess 的配置可以打开首页;允许覆盖配置后,请求变成 500 Internal Server Error。如果错误日志写着 Invalid command 'RewriteEngine',并提示可能是拼写错误或缺少模块,先检查当前实例有没有加载 mod_rewrite。
这个场景需要区分两件事:AllowOverride 决定 .htaccess 能使用哪些配置,模块加载决定 Apache 是否认识这些指令。允许覆盖不会自动安装或加载模块;把 RewriteEngine 改成 On,也不能让一个尚未加载的模块出现。
先用请求日志确认哪一行失败
按当前站点、请求时间和实际 ErrorLog 查找对应错误,确认报错文件是应用的 .htaccess,指令确实是 RewriteEngine。浏览器的 500 本身不足以判定模块缺失,也可能由其他指令、权限或应用错误造成。
如果删掉 RewriteEngine 后,下一次变成 Invalid command 'RewriteCond',仍然指向同一模块的指令识别问题。继续删掉重写规则会让应用路由失效,并不等于修好了迁移。保存原文件,再检查模块与允许覆盖的范围。
本文的 a2enmod 操作适用于 Ubuntu、Debian 发行包的 Apache。容器、自编译安装或其他发行版可能采用不同模块管理方法,应按对应打包方式处理,不能直接创建这套发行版目录。
核对运行实例的模块,按需启用 rewrite
发行包环境可使用下面的只读检查:
sudo apache2ctl -M
查看模块列表中是否有 rewrite_module。使用 apache2ctl 可以带上发行包所需环境;还应确认检查的配置入口与运行服务一致。列表已经包含该模块,却仍报未知指令时,继续核对报错拼写、是否访问了另一个实例或未更新的容器,而不是重复启用模块。
若确认对应发行包已安装该模块、当前配置没有加载,而且应用确实依赖重写规则,可按受控变更启用:
sudo a2enmod rewrite
sudo apache2ctl configtest
a2enmod 通过 mods-enabled 中的链接启用配置,不会立即改变正在运行的进程。先保留原主配置、站点配置、.htaccess 和启用模块列表,检查通过后再沿用原服务管理方式加载。若语法检查失败,先修复明确错误,不要重启一个无法加载配置的服务。
启用模块还会影响其他使用它的站点,配置加载可能带来短暂服务变化。应安排适当窗口。不能为了让未知指令不报错,加载 vhost_alias 等无关模块或关闭错误检查。
允许应用需要的指令,不必对所有目录开放 All
当 AllowOverride 和 AllowOverrideList 都为 None 时,Apache 会忽略 .htaccess。把它们改为允许配置后,文件中原来没有被解析的错误才会显现。这解释了“修改后才报错”,不意味着 All 的大小写是根因。
RewriteEngine、RewriteCond 和 RewriteRule 属于 FileInfo 类。在确认应用 .htaccess 只需要这一类覆盖时,可以针对实际文档目录使用类似结构:
<Directory "/var/www/example/public">
AllowOverride FileInfo
</Directory>
这是受限范围的配置示例,不是所有应用的完整配置。应用若还有认证、Options 等指令,要逐项核对所需类别或采用明确的 AllowOverrideList;只允许 FileInfo 而文件含其他被禁止的指令,也会导致请求错误。不要为了处理一个站点,把根目录的 Directory 配置全部开放。
All 只允许适用于 .htaccess 的指令,不能让未加载模块的指令变得有效。AllowOverride 的允许范围和 mod_rewrite 的加载状态,都需要核对。
验收实际路由,主配置检查不能替代请求
主配置的 configtest 通过后,仍要请求会经过该 .htaccess 的页面。它不保证每次请求读取的 .htaccess 都合法。先确认对应日志不再出现 RewriteEngine 或 RewriteCond 未识别,再检查应用的动态路径、静态资源和预期跳转。
如果出现另一个未知指令或规则错误,应根据新的日志继续判断;不要因为首页恢复就略过实际路由。需要回退时恢复原文件与覆盖范围,检查后按原服务流程加载。只有确认 rewrite 是这次新增、没有其他站点依赖时,才考虑用 a2dismod rewrite 恢复模块状态;不能批量禁用相关模块来回退。


