पाठ 15 / 25

Redirects, HSTS and Canonical Hosts

Redirect HTTP to HTTPS, choose a canonical host and enable HSTS safely.

One canonical, secure address

Serve every site on one canonical URL: redirect HTTP to HTTPS and pick either www.example.com or example.com, redirecting the other, which avoids duplicate content and cookie confusion. Use return 301 for permanent redirects and keep the path and query string with $request_uri. Prefer return over rewrite whenever possible; rewrite uses regular expressions and is needed only for pattern-based URL changes. Use 308 instead of 301 when a redirect must preserve the HTTP method and body (for example API POST requests). HTTP Strict Transport Security (HSTS), the Strict-Transport-Security header, tells browsers to use HTTPS for your domain for a period, blocking downgrade attacks; start with a short max-age, then increase it to a year once everything works, and only add includeSubDomains and preload when every subdomain supports HTTPS, because preloading is hard to undo. Leave the HTTP-to-HTTPS redirect server able to answer ACME challenges if you use HTTP-01 certificate validation.

Redirect HTTP and the bare domain to one HTTPS host

ACME challenges still work over plain HTTP.

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    location /.well-known/acme-challenge/ { root /var/www/certbot; }
    location / { return 301 https://www.example.com$request_uri; }
}

server {
    listen 443 ssl;
    http2 on;
    server_name example.com;
    ssl_certificate     /etc/ssl/example/fullchain.pem;
    ssl_certificate_key /etc/ssl/example/privkey.pem;
    return 301 https://www.example.com$request_uri;
}

server {
    listen 443 ssl;
    http2 on;
    server_name www.example.com;
    ssl_certificate     /etc/ssl/example/fullchain.pem;
    ssl_certificate_key /etc/ssl/example/privkey.pem;
    add_header Strict-Transport-Security "max-age=31536000" always;
    root /var/www/example;
}

Roll out HSTS gradually

A long HSTS max-age with includeSubDomains instantly breaks any subdomain still on HTTP, and browsers remember it for months. Start with max-age=300, verify, then raise it.

त्वरित जाँच: Which is the simplest correct way to redirect all HTTP traffic to HTTPS while keeping the path?

  • rewrite ^ https://$host;
  • proxy_pass https://$host;
  • return 301 https://$host$request_uri;
  • try_files https://$host;
Answer

return 301 https://$host$request_uri; — return with $request_uri preserves the path and query string without regex processing.