# Debian 12 HTTP/2 proxy templates return 421 Misdirected Request

Post Reply
mau.sav
Posts: 3
Joined: Tue May 24, 2022 5:08 pm

# Debian 12 HTTP/2 proxy templates return 421 Misdirected Request

## Summary
On a fresh upgrade or install of myVesta on Debian 12, every HTTPS site proxied by nginx to Apache returns `421 Misdirected Request` once HTTP/2 is enabled. The stock nginx SSL templates shipped with myVesta do not forward the original `Host` header or Server Name Indication (SNI) to Apache, so Apache 2.4.62 (the default in Debian 12/bookworm) rejects the traffic.

## Environment
- Debian 12.12 (bookworm)
- myVesta 0.9.9 (upgraded from 0.9.8 via `v-update-myvesta`)
- nginx 1.22 as reverse proxy
- Apache 2.4.62 serving upstream on ports 8080/8443
- myVesta upgrade script from viewtopic.php?f=28&t=877 (enables HTTP/2 in templates)

## Steps to Reproduce
1. Install myVesta on Debian 11, then run the official upgrade script above to move to Debian 12 (or install myVesta directly on Debian 12 and enable HTTP/2 for nginx SSL templates).
2. Create or rebuild any web domain that uses a proxy template (`hosting`, `force-https`, `hosting-webmail-phpmyadmin`, etc.).
3. Open the site via HTTPS.

## Observed Behaviour
- Browser shows `421 Misdirected Request` for every HTTPS vhost that goes through nginx → Apache.
- Access log on nginx shows the request, but Apache rejects it because the TLS connection is reused with the backend IP/SNI instead of the real hostname.
- No myVesta rebuild or cache purge resolves the issue.

## Root Cause
- Debian 12 ships Apache 2.4.62 with stronger HTTP/2 coalescing protections. When Apache receives a reused TLS connection whose SNI does not match the requested vhost, it responds with 421.
- The myVesta nginx SSL templates only call `proxy_pass https://%ip%:%web_ssl_port%;` and never forward `Host`, `X-Forwarded-*`, or enable `proxy_ssl_server_name` / `proxy_ssl_name`.
- The upgrade script enables `ssl http2` in all SSL templates, which makes TLS connection reuse immediate, exposing the missing headers.

## Workaround / Fix
Update every nginx SSL template that proxies to Apache and add the missing directives immediately after each `proxy_pass` statement (including nested `/webmail`, `/phpmyadmin`, and fallback blocks):

```
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_ssl_server_name on;
proxy_ssl_name $host;
```

The affected templates are:
- `hosting.stpl`
- `hosting-legacy.stpl`
- `hosting-public.stpl`
- `hosting-webmail-phpmyadmin.stpl`
- `private-hosting.stpl`
- `private-force-https.stpl`
- `force-https.stpl`
- `force-https-public.stpl`
- `force-https-webmail-phpmyadmin.stpl`
- `force-https-legacy.stpl`
- `caching.stpl`
- `default.stpl`

After applying the change, run `v-rebuild-web-domains <user> yes` (or per-domain rebuilds) and reload nginx. HTTPS starts working immediately without 421 responses.

## Additional Notes
- The same directives are already part of many reverse-proxy best practices and are required for proper HTTP/2 → HTTP/1.1 bridging on modern Apache versions.
- Users who upgraded before the fix may have patched their live vhost files manually. Without updating the templates, a subsequent rebuild will reintroduce the bug.
- No template changes are required for pure nginx+PHP-FPM templates under `nginx/php-fpm/` or the Apache PHP-FPM templates (`apache2/PHP-FPM-*`).
Post Reply