diff --git a/README.md b/README.md index 743a243..4c17c5e 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ systemctl reload nginx This repository is organized by nginx context: - `http/`: snippets that must be included inside `http {}`. +- `listen/`: listener snippets for `server {}` blocks. - `fastcgi/`: FastCGI-specific snippets for `location {}` or `server {}` blocks. - `ssl/`: HTTPS and TLS snippets for `server {}` blocks. - `proxy_pass/`: reverse proxy snippets for `location {}` blocks. @@ -37,6 +38,8 @@ Include these inside a `server {}` block: ```nginx server { # ... + include kit/listen/http.conf; + include kit/listen/https-http2.conf; include snippets/cert/mydomain.com.conf; include kit/security.conf; include kit/ssl/security.conf; @@ -48,6 +51,19 @@ server { See [examples/example.com.conf](examples/example.com.conf:1) for the full server-level example. +For widest compatibility, the examples use `listen ... http2` instead of the standalone `http2 on;` directive. The standalone `http2` directive appeared in nginx `1.25.1` on `2023-06-13`, while Ubuntu-packaged nginx `1.24.x` rejects it. + +For nginx `1.25.1+`, you can use the modern split form instead: + +```nginx +server { + include kit/listen/http.conf; + include kit/listen/https.conf; + include kit/listen/http2.conf; + # ... +} +``` + ### Optional `http {}` features These snippets are independent `http {}`-level features: @@ -75,6 +91,7 @@ Plain HTTP reverse proxying only needs the `location {}`-level proxy snippets: ```nginx server { # ... + include kit/listen/http.conf; location / { include kit/proxy_pass/forwarded.conf; include kit/proxy_pass/timeout-300.conf; @@ -92,7 +109,8 @@ http { include kit/http/websocket-map.conf; server { - # ... + include kit/listen/http.conf; + include kit/listen/https-http2.conf; location /ws/ { include kit/proxy_pass/forwarded.conf; include kit/proxy_pass/websocket.conf; @@ -133,6 +151,10 @@ server { - `kit/http/gzip.conf`: gzip compression for common text-based responses. Must be included inside `http {}`. - `kit/http/websocket-map.conf`: defines `$connection_upgrade` for websocket proxying. Must be included inside `http {}`. +- `kit/listen/http.conf`: IPv4 and IPv6 HTTP listeners for `server {}`. +- `kit/listen/https.conf`: IPv4 and IPv6 HTTPS listeners for `server {}` without enabling HTTP/2. +- `kit/listen/http2.conf`: standalone `http2 on;` snippet for nginx `1.25.1+`. +- `kit/listen/https-http2.conf`: IPv4 and IPv6 HTTPS listeners with HTTP/2 for `server {}`. Uses `listen ... http2` for nginx `1.24.x` compatibility. - `kit/security.conf`: common low-risk security headers and host normalization. Intended for `server {}`. - `kit/security-legacy.conf`: optional legacy compatibility headers such as `X-Download-Options` and `X-Permitted-Cross-Domain-Policies`. - `kit/fastcgi/hide-powered-by.conf`: hides `X-Powered-By` from FastCGI upstream responses. @@ -165,3 +187,6 @@ The script validates: - `text/html` does not need to appear in `gzip_types`; nginx compresses it automatically. - Gzip over HTTPS can contribute to BREACH-style risk for responses that reflect attacker-controlled input alongside secrets. Keep that in mind for highly sensitive dynamic pages. - `kit/security.conf` intentionally does not set `X-Robots-Tag: none` or `X-XSS-Protection: 1; mode=block`; those are too risky or too obsolete for a default site-wide baseline. +- The standalone `http2 on;` directive appeared in nginx `1.25.1` on `2023-06-13`. For broader compatibility, this repository currently prefers `listen 443 ssl http2;` and `listen [::]:443 ssl http2;`. +- If you are standardizing on nginx `1.25.1+`, prefer `kit/listen/https.conf` plus `kit/listen/http2.conf` to avoid the deprecation warnings on modern nginx. +- Listener snippets are intentionally minimal. Variants such as `default_server`, `proxy_protocol`, or non-HTTP/2 HTTPS should live in separate project-specific snippets to avoid accidental conflicts. diff --git a/examples/example.com.conf b/examples/example.com.conf index eca7cbd..1a7aafe 100644 --- a/examples/example.com.conf +++ b/examples/example.com.conf @@ -1,10 +1,6 @@ server { - listen 80; - listen [::]:80; - listen 443 ssl; - listen [::]:443 ssl; - - http2 on; + include kit/listen/http.conf; + include kit/listen/https-http2.conf; server_name primary.example.com alias1.example.com diff --git a/examples/reverse-proxy.nginx.conf b/examples/reverse-proxy.nginx.conf index a80d20c..0f567a3 100644 --- a/examples/reverse-proxy.nginx.conf +++ b/examples/reverse-proxy.nginx.conf @@ -12,13 +12,9 @@ http { } server { - listen 80; - listen [::]:80; - listen 443 ssl; - listen [::]:443 ssl; + include kit/listen/http.conf; + include kit/listen/https-http2.conf; - http2 on; - server_name app.example.com; include snippets/cert/mydomain.com.conf; diff --git a/listen/http.conf b/listen/http.conf new file mode 100644 index 0000000..76cb18d --- /dev/null +++ b/listen/http.conf @@ -0,0 +1,2 @@ +listen 80; +listen [::]:80; diff --git a/listen/http2.conf b/listen/http2.conf new file mode 100644 index 0000000..a73afed --- /dev/null +++ b/listen/http2.conf @@ -0,0 +1 @@ +http2 on; diff --git a/listen/https-http2.conf b/listen/https-http2.conf new file mode 100644 index 0000000..f6091bb --- /dev/null +++ b/listen/https-http2.conf @@ -0,0 +1,2 @@ +listen 443 ssl http2; +listen [::]:443 ssl http2; diff --git a/listen/https.conf b/listen/https.conf new file mode 100644 index 0000000..018660b --- /dev/null +++ b/listen/https.conf @@ -0,0 +1,2 @@ +listen 443 ssl; +listen [::]:443 ssl; diff --git a/scripts/validate-docker.ps1 b/scripts/validate-docker.ps1 index 8276844..24db28a 100644 --- a/scripts/validate-docker.ps1 +++ b/scripts/validate-docker.ps1 @@ -46,6 +46,25 @@ $optionalSnippetConfig = @( $optionalSnippetConfigShell = $optionalSnippetConfig -replace "`n", "\\n" +$modernHttp2Config = @( + "events {}" + "" + "http {" + " include /etc/nginx/mime.types;" + " default_type application/octet-stream;" + "" + " server {" + " include /etc/nginx/kit/listen/http.conf;" + " include /etc/nginx/kit/listen/https.conf;" + " include /etc/nginx/kit/listen/http2.conf;" + " include /etc/nginx/snippets/cert/mydomain.com.conf;" + " server_name modern.example.com;" + " }" + "}" +) -join "\n" + +$modernHttp2ConfigShell = $modernHttp2Config -replace "`n", "\\n" + $containerCommand = @( "set -eu" "apk add --no-cache openssl >/dev/null" @@ -60,12 +79,15 @@ $containerCommand = @( "cp /etc/nginx/kit/examples/reverse-proxy.nginx.conf /tmp/nginx-kit/examples/reverse-proxy.nginx.conf" "printf '%b' '$serverSnippetConfigShell' > /tmp/nginx-kit/server-snippet.nginx.conf" "printf '%b' '$optionalSnippetConfigShell' > /tmp/nginx-kit/optional-snippets.nginx.conf" + "printf '%b' '$modernHttp2ConfigShell' > /tmp/nginx-kit/modern-http2.nginx.conf" "echo 'Validating examples/example.com.conf'" "nginx -t -c /tmp/nginx-kit/server-snippet.nginx.conf" "echo 'Validating examples/reverse-proxy.nginx.conf'" "nginx -t -c /tmp/nginx-kit/examples/reverse-proxy.nginx.conf" "echo 'Validating optional security and hide-powered-by snippets'" "nginx -t -c /tmp/nginx-kit/optional-snippets.nginx.conf" + "echo 'Validating modern http2 on snippets'" + "nginx -t -c /tmp/nginx-kit/modern-http2.nginx.conf" ) -join "; " docker run --rm `