Redirects & Rewrites
Overview
Redirects and rewrites are ordered (drag-and-drop priority) request-mutation rules scoped per listener. They run after WAF and before backend routing in the request pipeline.
Redirects
Redirects send the client to a different URL. Each redirect has:
| Property | Description |
|---|---|
| Name | Display name |
| Listener scoping | listener_ids, listener_id, frontend_match, or global |
| Priority | Drag-and-drop ordering |
| Source | Path prefix or regex to match |
| Target | Destination URL |
| Type | permanent (301), temporary (307), or regex |
| Code | HTTP status code |
Redirect Types
| Type | Status | Description |
|---|---|---|
| permanent | 301 | Permanent redirect (cached by browsers) |
| temporary | 307 | Temporary redirect (preserves method) |
| regex | 301/307 | Regex-based redirect with capture groups |
Listener Scoping
| Scope | Description |
|---|---|
| All listeners | Apply to every listener |
| Specific listeners | Apply to selected listener IDs |
| Frontend match | Apply to listeners matching a frontend name pattern |
Rewrites
Rewrites modify the request URI without sending a redirect. Each rewrite has:
| Property | Description |
|---|---|
| Name | Display name |
| Listener scoping | Same options as redirects |
| Priority | Drag-and-drop ordering |
| Source pattern | Pattern to match in the URI |
| Target | Replacement string |
| Type | Path rewrite, query rewrite, or full URI |
A redirect tells the browser to go to a new URL (the URL changes in the address bar). A rewrite changes the URI internally — the browser URL stays the same, but the backend receives a different path.
Response Headers
Response header rules modify headers on the response before it’s sent to the client. Actions:
| Action | Description |
|---|---|
| set | Set a header (overwrite if exists) |
| override | Override an existing header |
| add | Add a header (append, don’t overwrite) |
| del | Delete a header |
Response header rules support:
- Per-listener and per-backend scoping
- Optional HAProxy ACL conditions (only apply the header rule when the condition matches)
Custom Response Pages
Custom error pages can be configured for HTTP status codes 403, 429, and 500. Template variables:
| Variable | Description |
|---|---|
{{ request_id }} | HAProxy unique request ID |
{{ waf_unique_id }} | Coraza transaction ID (for 403 WAF blocks) |
{{ rate_limit_window }} | Rate limit window in seconds (for 429) |
{{ rate_limit_duration }} | Block duration (for 429 tarpit) |
Step-by-Step: Redirect HTTP to HTTPS
- Navigate to Traffic > Redirects & Rewrites
- Click Add Redirect
- Name:
http-to-https - Listener: select your HTTP listener (port 80)
- Source:
/(match all paths) - Target:
https://example.com(your domain) - Type: permanent (301)
- Save and Apply
Use 307 instead of 301 for temporary redirects. 301 is cached aggressively by browsers and search engines. If you’re not sure the redirect is permanent, use 307.
Step-by-Step: Rewrite an API Path
- Navigate to Traffic > Redirects & Rewrites > Rewrites
- Click Add Rewrite
- Name:
api-v1-to-v2 - Listener: select your listener
- Source pattern:
/api/v1/ - Target:
/api/v2/ - Type: path rewrite
- Save and Apply
Now requests to /api/v1/users are internally rewritten to /api/v2/users without changing the browser URL.
Step-by-Step: Add a Response Header
- Navigate to Traffic > Redirects & Rewrites > Response Headers
- Click Add Header Rule
- Name:
security-headers - Action: set
- Header:
X-Content-Type-Options - Value:
nosniff - Scope: all listeners
- Save and Apply
Step-by-Step: Custom 403 Page
- Navigate to Traffic > Redirects & Rewrites > Error Pages
- Select status code: 403
- Upload or paste your HTML template
- Use
{{ request_id }}for support correlation - Save and Apply
Verification
-
Test a redirect:
curl -k -v http://localhost/ 2>&1 | grep -i 'location\|301\|307' -
Test a rewrite:
curl -k -v https://localhost/api/v1/users 2>&1 | grep -i 'request'The backend should receive
/api/v2/userswhile the client URL shows/api/v1/users. -
Test response headers:
curl -k -sI https://localhost/ | grep -i x-content-type -
Test custom error page:
curl -k https://localhost/forbidden-endpointExpect your custom 403 page with the request_id rendered.
Next Steps
- Listeners & Backends — Configure listener bindings
- Security Rules — Layer access control
- Page Protect — Security headers via CSP management