Configuring Apache with mod_rewrite for URL redirection
Apache’s mod_rewrite module maps incoming request paths to replacement URLs, making it useful for moving content, forcing HTTPS, and consolidating duplicate hostnames. A rewrite rule is evaluated before the requested page is served, allowing Apache to return a permanent status with a Location header that points browsers, crawlers, and API clients to the new address.
For Australian administrators, the usual goal is to move an existing .com.au or .au site without breaking bookmarks, search rankings, or campaign links. Australian English spelling and terms such as “organisation” may already appear in those URLs, so redirects should preserve meaningful paths rather than apply a blanket rule. Teams commonly place workloads in Sydney or Melbourne, including AWS’s ap-southeast-2 region, while maintaining one canonical hostname.
Enable rewrite support
On Fedora, RHEL, and CentOS Stream, install and start Apache, then confirm that its rewrite module is loaded:
sudo dnf install httpd
sudo systemctl enable --now httpd
sudo httpd -M | grep -i rewrite
Current releases commonly include the module within the httpd package. If the output is empty, install the repository’s mod_rewrite package where available or enable the packaged module under /etc/httpd/conf.modules.d/. Keep global rules in a dedicated file such as /etc/httpd/conf.d/redirects.conf, writable only by root. Files outside the default document root may also require the correct SELinux context.
Build predictable redirect rules
Create a separate configuration file and replace the example domain and paths with values from the organisation’s URL inventory. This example sends an old path directly to its new HTTPS location, removes the www hostname, and upgrades remaining HTTP requests:
RewriteEngine On
RewriteRule ^legacy/(.*)$ https://example.com.au/new/$1 [R=301,L,NE]
RewriteCond %{HTTP_HOST} ^www\.example\.com\.au$ [NC]
RewriteRule ^ https://example.com.au%{REQUEST_URI} [R=301,L,NE]
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com\.au$ [NC]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://example.com.au%{REQUEST_URI} [R=301,L,NE]
The 301 status is appropriate for permanent changes, while L stops further rule processing. Because the substitutions contain no question mark, Apache normally carries the original query string forward; appending ? deliberately discards it. Use a 302 response during initial testing, and avoid broad host conditions that could make an untrusted Host header influence the destination.
TLS may terminate at a reverse proxy rather than Apache. In that arrangement, %{HTTPS} can remain off. Set the HTTPS environment value from X-Forwarded-Proto only when requests arrive through a trusted proxy, as incorrect trust settings can create redirect loops.
Choose per-directory rules carefully
Global configuration provides predictable ordering and avoids parsing .htaccess files for every request. It is also easier to protect with file ownership and review through version control. These advantages make it preferable for public sites and infrastructure managed by an administration team.
Shared hosting may require .htaccess. Within the existing Apache directory block, allow the required overrides without replacing its access controls:
<Directory "/var/www/html">
AllowOverride FileInfo Options
</Directory>
Keep Options FollowSymLinks enabled, then add a narrowly scoped rule to the relevant .htaccess file. Per-directory patterns are relative to that directory, so a root-level request may match ^old/(.*)$ rather than ^/old/(.*)$. Absolute destination URLs also prevent differences between server and per-directory rewriting contexts.
Test redirects before and after reload
Validate the complete configuration before reloading the service, then inspect both the initial response and the final destination:
sudo apachectl configtest
sudo systemctl reload httpd
curl -sS -o /dev/null -D - \
'http://www.example.com.au/legacy/article?id=42'
curl -sS -L --max-redirs 5 -o /dev/null \
-w '%{url_effective}\n' \
'http://www.example.com.au/legacy/article?id=42'
The first request should return a 301 with an HTTPS Location header. The second should finish at the expected path and retain the required query parameter. Test trailing slashes, encoded characters, missing pages, and repeated requests because browser caching can conceal an incorrect redirect chain. For broader regression ideas, the serious-code.net testing notes complement these checks.
Apache normally writes access logs in UTC, while an Australian support team may be working in AEST or AEDT. Convert timestamps carefully because daylight-saving changes make a fixed offset unreliable. The effective URL, response status, and complete redirect chain matter more than the time shown in a browser.
Generate rules from structured data
A redirect inventory often starts as JSON, particularly when applications or marketing teams maintain route mappings. The jq parsing guide explains how to extract structured fields without relying on fragile text slicing:
jq -r '.routes[] | [.from, .to] | @tsv' redirects.json
A shell loop can convert each tab-separated pair into an Apache rule. Validate source and destination paths before generating configuration, rejecting whitespace, quotes, newlines, and unintended regular-expression characters. Write the result to a temporary file, run apachectl configtest, and only then replace the active configuration and reload Apache. This prevents a malformed inventory entry from stopping the service.
Production safeguards for Australian deployments
A Fedora virtual machine provides a useful pre-production target. The Fedora KVM walkthrough covers local virtualisation for teams that want to give it a go before changing a busy Sydney or Melbourne workload.
- Standardise every public request on one canonical hostname.
- Reserve
301responses for changes that are genuinely permanent. - Preserve required query parameters while removing tracking tokens and identifiers.
- Test HTTP, HTTPS, host aliases, query strings, and encoded paths.
- Store redirect configuration under version control with a rollback copy.
Redirect targets and access logs can contain personal information. For Australian organisations covered by the Privacy Act 1988 and the Australian Privacy Principles, limit query-string logging, remove email addresses or reset tokens from destinations, and apply suitable retention controls. Domain migrations should also account for the visibility of .com.au and .au addresses in Australian search results and outbound campaigns.
The practical takeaway is to treat every redirect as a versioned routing contract: validate it with apachectl configtest, reload only after a successful check, and confirm the final status and Location before production traffic follows it.