Skip to content

Commit

Permalink
Enable HTTP3 in nginx
Browse files Browse the repository at this point in the history
Fixes #1659
  • Loading branch information
bwbroersma committed Feb 7, 2025
1 parent 7df7202 commit 821878a
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 11 deletions.
3 changes: 2 additions & 1 deletion docker/webserver.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ RUN touch /etc/nginx/htpasswd/monitoring.htpasswd
COPY docker/webserver/10-variables.envsh /docker-entrypoint.d/
COPY docker/webserver/tls_init.sh /docker-entrypoint.d/
COPY docker/webserver/authentication.sh /docker-entrypoint.d/
COPY docker/webserver/generate_quic_host_key.sh /docker-entrypoint.d/

COPY docker/webserver/user_manage_inner.sh /

Expand All @@ -37,5 +38,5 @@ COPY interface/static/favicon.ico /var/www/internet.nl/
COPY docker/webserver/nginx_templates/* /etc/nginx/templates/
COPY docker/webserver/mime.types /etc/nginx/
COPY docker/webserver/http.headers /etc/nginx/
COPY docker/webserver/hsts.header /etc/nginx/
COPY docker/webserver/hsts_h3.headers /etc/nginx/
COPY docker/webserver/all.headers /etc/nginx/
2 changes: 1 addition & 1 deletion docker/webserver/all.headers
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
include http.headers;
include hsts.header;
include hsts_h3.headers;
include conf.d/csp.header;
10 changes: 10 additions & 0 deletions docker/webserver/generate_quic_host_key.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env sh

# See https://nginx.org/en/docs/http/ngx_http_v3_module.html#quic_host_key
# Sets a file with the secret key used to encrypt stateless reset and address validation tokens.
# By default, a random key is generated on each reload. Tokens generated with old keys are not accepted.

# The default NGX_QUIC_DEFAULT_HOST_KEY_LEN is 32 bytes (ngx_event_quic.h)
# Since reloads happen due to Certbot, set a static persistent host key per release.

openssl rand 32 > /etc/nginx/quic_host.key
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Do *not* add includeSubdomains before https://github.com/internetstandards/Internet.nl/issues/324 is resolved,
# adding includeSubdomains without adding the wildcard SSL certificates will otherwise break the connection test.
add_header 'Strict-Transport-Security' 'max-age=31536000;' always;
add_header 'Strict-Transport-Security' 'max-age=31536000' always;
add_header 'Alt-Svc' 'h3=":443"; ma=86400' always;

27 changes: 19 additions & 8 deletions docker/webserver/nginx_templates/app.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ server_names_hash_bucket_size 1024;
# override default log format to include vhost
log_format default '$remote_addr $host $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
'"$http_user_agent" "$http_x_forwarded_for" $http3';

access_log /var/log/nginx/access.log default;

# create seperate logfile, since the access.log file is a symlink to stdout
# it cannot be used by prometheus-nginxlog-exporter
log_format nginx_logs_exporter '$remote_addr $host $remote_user [$time_local] $proxy_host "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
'"$http_user_agent" "$http_x_forwarded_for" $http3';
access_log /var/log/nginx/prometheus-nginxlog-exporter/access.log nginx_logs_exporter;

# disable version in server banner
Expand All @@ -33,7 +33,10 @@ ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

http2 on;

http3 on;
quic_gso on;
quic_host_key /etc/nginx/quic_host.key;
quic_retry on;

# default server for http, primary used for ACME and https redirect
server {
Expand Down Expand Up @@ -119,7 +122,9 @@ server {

# No-www.org Class B compliance, see https://www.no-www.org/faq.php
server {
listen 443 quic reuseport;
listen 443 ssl;
listen [::]:443 quic reuseport;
listen [::]:443 ssl;

server_name www.${INTERNETNL_DOMAINNAME} ${REDIRECT_DOMAINS_LIST};
Expand All @@ -134,7 +139,9 @@ server {

# default https server
server {
listen 443 quic;
listen 443 ssl;
listen [::]:443 quic;
listen [::]:443 ssl;

# LANGUAGES_REGEX is a list of language prefixes separated by pipes, eg: `nl\.|en\.`
Expand Down Expand Up @@ -248,21 +255,21 @@ server {
# monitoring, requires authentication, override headers, since CSP is too strict
location /grafana {
include http.headers;
include hsts.header;
include hsts_h3.headers;
auth_basic "Please enter your monitoring username and password";
auth_basic_user_file /etc/nginx/htpasswd/monitoring.htpasswd;
proxy_pass http://${IPV4_IP_GRAFANA_INTERNAL}:3000;
}
location /prometheus {
include http.headers;
include hsts.header;
include hsts_h3.headers;
auth_basic "Please enter your monitoring username and password";
auth_basic_user_file /etc/nginx/htpasswd/monitoring.htpasswd;
proxy_pass http://${IPV4_IP_PROMETHEUS_INTERNAL}:9090;
}
location /alertmanager {
include http.headers;
include hsts.header;
include hsts_h3.headers;
auth_basic "Please enter your monitoring username and password";
auth_basic_user_file /etc/nginx/htpasswd/monitoring.htpasswd;
proxy_pass http://${IPV4_IP_ALERTMANAGER_INTERNAL}:9093;
Expand All @@ -272,7 +279,9 @@ server {
# Temporary (1 year) exception for conn. subdomain to disable HSTS and redirect back to HTTP for
# clients that accessed the HTTPS version in the past and got a HSTS set of 1 year.
server {
listen 443 quic;
listen 443 ssl;
listen [::]:443 quic;
listen [::]:443 ssl;

# LANGUAGES_REGEX is a list of language prefixes separated by pipes, eg: `nl\.|en\.`
Expand All @@ -292,8 +301,10 @@ server {

# reject connection to any HTTPS vhost not explicitly served
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
listen 443 default_server quic;
listen 443 default_server ssl;
listen [::]:443 default_server quic;
listen [::]:443 default_server ssl;

server_name _;

Expand Down
10 changes: 10 additions & 0 deletions documentation/Docker-DNS.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ For a domain that does not otherwise send email, use:
The `INTERNETNL_DOMAINNAME` host should also have a working MX and correct FCrDNS.
DANE records are recommended, but not required.

For modern HTTP3 support a HTTPS resource record should be added for each domain:

example.com. HTTPS 1 . alpn=h2,h3
www.example.com. HTTPS 1 . alpn=h2,h3
nl.example.com. HTTPS 1 . alpn=h2,h3
en.example.com. HTTPS 1 . alpn=h2,h3
ipv6.example.com. HTTPS 1 . alpn=h2,h3
nl.ipv6.example.com. HTTPS 1 . alpn=h2,h3
en.ipv6.example.com. HTTPS 1 . alpn=h2,h3

## Specific settings for batch mode

For batch, the connection test is not used, and the authoritative name server should not be publicly available.
Expand Down

0 comments on commit 821878a

Please sign in to comment.