Apache
Apache rewrite strategy
Use deterministic, auditable rewrite behavior to avoid semantic drift, redirect loops, and canonicalization attacks.
Last updated: 2026-05-10. Owners: operations and service teams.
On this page
Doctrine
- Prefer single canonical host + path ownership for each virtual host.
- Keep rewrite logic in one block and gate every rule with explicit `RewriteRule`, `RewriteCond`, and comments.
- Preserve query strings by default unless intentionally remapped.
- Use HTTPS-aware conditions first, then canonicalization, then routing.
Decision tree
- Need to change user-visible path or query behavior?
- Yes → define expected input/output pairs in a local test matrix before changing config.
- No → keep existing rewrite contract and only add safety checks.
- Is request already normalized?
- Yes → apply auth and cache handling; then routing rule.
- No → normalize host, slash, and encoded path first.
- Any potential loop?
- Yes → add terminal condition (`L`, `R=301`, and explicit exclusion matches) before rollout.
- No → continue with staged enablement and live probes.
Diagnostics pathway
- Validate rule graph parsing:
apachectl configtest - Track current effective rule chain:
tail -f /var/log/httpd/error_log | rg --line-buffered "rewrite|redirect|canonical" - Reproduce rewrite path from a client:
curl -I -L https://example.com/path?x=1 - Check loop or double-hop signs:
curl -I -L -X GET "https://example.com/health?trace=1"
Operational checks
- Before change: capture baseline HTTP status distribution for top 20 routes.
- After change: confirm no new 3xx cycles or TLS downgrade transitions.
- Every redirect decision must map to a documented business rationale and rollback command.
Rollback: disable affected RewriteRule blocks and reload once, keeping cache headers unchanged.