mirror of
https://github.com/GrapheneOS/matrix.grapheneos.org.git
synced 2024-09-30 08:15:36 +00:00
087c1a6349
This is useless for TLSv1.3 since there's no longer any distinction in the protocol based on whether the server is using stateless or stateful session resumption. OpenSSL has a non-standard anti-replay mechanism for 0-RTT based on stateful session resumption but 0-RTT still ends up being a downgrade for the TLS security properties. nginx disables that feature since otherwise 0-RTT wouldn't work with the default stateless approach. Since this cache is only used for TLSv1.2 when stateless resumption isn't disabled and nearly all TLSv1.2 clients support tickets, it isn't getting any significant use. It provides worse forward secrecy than tickets because we implement ticket key rotation based on the expiry time and sessions aren't actively purged from the stateful cache when they expire. Cached session state varies in size and nginx ends up writing errors to the log when clearing out a session fails to make room for a new one due to it being larger. It's best to finally get rid of this flawed approach to session resumption. TLSv1.3 provides the option of forward secrecy for resumed sessions and it's the only approach that's normally enabled so we don't need to worry about this anymore once TLSv1.2 is disabled as long as we never enable 0-RTT which weakens forward secrecy and other security properties.
182 lines
5.8 KiB
Nginx Configuration File
182 lines
5.8 KiB
Nginx Configuration File
# nginx 1.20.2+
|
|
|
|
load_module modules/ngx_http_brotli_static_module.so;
|
|
|
|
worker_processes auto;
|
|
worker_rlimit_nofile 16384;
|
|
|
|
events {
|
|
worker_connections 4096;
|
|
}
|
|
|
|
http {
|
|
include mime.types;
|
|
default_type application/octet-stream;
|
|
|
|
charset utf-8;
|
|
charset_types text/css text/plain text/xml application/atom+xml application/javascript;
|
|
|
|
# sendfile + AIO is buggy without fixes from nginx master
|
|
#sendfile on;
|
|
sendfile_max_chunk 512k;
|
|
tcp_nopush on;
|
|
keepalive_timeout 3m;
|
|
server_tokens off;
|
|
msie_padding off;
|
|
|
|
client_max_body_size 1k;
|
|
client_body_buffer_size 1k;
|
|
client_header_buffer_size 1k;
|
|
large_client_header_buffers 4 4k;
|
|
http2_recv_buffer_size 128k;
|
|
|
|
client_body_timeout 30s;
|
|
client_header_timeout 30s;
|
|
send_timeout 30s;
|
|
|
|
http2_max_concurrent_streams 32;
|
|
limit_conn_status 429;
|
|
limit_conn_zone $binary_remote_addr zone=addr:10m;
|
|
limit_conn addr 256;
|
|
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256;
|
|
ssl_prefer_server_ciphers on;
|
|
ssl_conf_command Options PrioritizeChaCha;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/matrix.grapheneos.org/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/matrix.grapheneos.org/privkey.pem;
|
|
|
|
# maintained by nginx-rotate-session-ticket-keys in ramfs
|
|
ssl_session_ticket_key session-ticket-keys/4.key;
|
|
ssl_session_ticket_key session-ticket-keys/3.key;
|
|
ssl_session_ticket_key session-ticket-keys/2.key;
|
|
ssl_session_ticket_key session-ticket-keys/1.key;
|
|
ssl_session_timeout 1d;
|
|
ssl_buffer_size 4k;
|
|
|
|
ssl_trusted_certificate /etc/letsencrypt/live/matrix.grapheneos.org/chain.pem;
|
|
ssl_stapling on;
|
|
ssl_stapling_verify on;
|
|
# maintained by certbot-ocsp-fetcher
|
|
ssl_stapling_file ocsp-cache/matrix.grapheneos.org.der;
|
|
|
|
log_format main '$remote_addr - $remote_user [$time_local] '
|
|
'"$request_method $scheme://$host$request_uri $server_protocol" $status $body_bytes_sent '
|
|
'"$http_referer" "$http_user_agent"';
|
|
access_log /var/log/nginx/access.log main buffer=64k flush=1m;
|
|
error_log syslog:server=unix:/dev/log,nohostname;
|
|
log_not_found off;
|
|
|
|
gzip_proxied any;
|
|
gzip_vary on;
|
|
|
|
if_modified_since before;
|
|
|
|
aio threads;
|
|
aio_write on;
|
|
|
|
upstream backend {
|
|
zone backend 32k;
|
|
server [::1]:8008 max_conns=4096 fail_timeout=1s;
|
|
}
|
|
|
|
server {
|
|
listen 80 backlog=4096;
|
|
listen [::]:80 backlog=4096;
|
|
server_name matrix.grapheneos.org element.grapheneos.org;
|
|
|
|
root /var/empty;
|
|
|
|
return 301 https://$host$request_uri;
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl http2 backlog=4096;
|
|
listen [::]:443 ssl http2 backlog=4096;
|
|
server_name matrix.grapheneos.org;
|
|
|
|
root /var/empty;
|
|
|
|
include snippets/security-headers.conf;
|
|
add_header Cross-Origin-Resource-Policy "same-origin" always;
|
|
add_header Content-Security-Policy "font-src 'none'; manifest-src 'none'; object-src 'none'; script-src 'none'; style-src 'none'; frame-ancestors 'none'; block-all-mixed-content" always;
|
|
# obsolete and replaced with Content-Security-Policy frame-ancestors 'none'
|
|
add_header X-Frame-Options "DENY" always;
|
|
|
|
location = / {
|
|
return 301 https://grapheneos.org/articles/grapheneos-servers#matrix.grapheneos.org;
|
|
}
|
|
|
|
location ^~ /.well-known/acme-challenge/ {
|
|
root /srv/certbot;
|
|
}
|
|
|
|
location ~ ^(?:/_matrix|/_synapse/client) {
|
|
# remove security headers that are statically set to the strictest possible values below
|
|
proxy_hide_header Referrer-Policy;
|
|
proxy_hide_header X-Frame-Options;
|
|
|
|
include snippets/security-headers.conf;
|
|
add_header Cross-Origin-Resource-Policy "cross-origin" always;
|
|
add_header Content-Security-Policy "font-src 'none'; manifest-src 'none'; object-src 'none'; script-src 'none'; style-src 'none'; frame-ancestors 'none'; block-all-mixed-content" always;
|
|
# obsolete and replaced with Content-Security-Policy frame-ancestors 'none'
|
|
add_header X-Frame-Options "DENY" always;
|
|
add_header X-Robots-Tag "none";
|
|
|
|
proxy_pass http://backend;
|
|
proxy_set_header X-Forwarded-For $remote_addr;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header Host $host;
|
|
proxy_connect_timeout 5s;
|
|
proxy_read_timeout 600s;
|
|
|
|
client_max_body_size 100m;
|
|
client_body_buffer_size 16k;
|
|
}
|
|
|
|
location / {
|
|
return 404;
|
|
}
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name element.grapheneos.org;
|
|
|
|
root /srv/element.grapheneos.org;
|
|
|
|
include snippets/security-headers.conf;
|
|
add_header Cross-Origin-Resource-Policy "cross-origin" always;
|
|
add_header Content-Security-Policy "font-src 'self'; manifest-src 'self'; object-src 'none'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-ancestors 'self'; block-all-mixed-content" always;
|
|
# obsolete and replaced with Content-Security-Policy frame-ancestors 'self'
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
add_header X-Robots-Tag "none";
|
|
|
|
location ^~ /.well-known/acme-challenge/ {
|
|
root /srv/certbot;
|
|
}
|
|
|
|
location ~ '\.(?:css|html|ico|js|json|map|svg|txt|wasm|xml)$' {
|
|
gzip_static on;
|
|
brotli_static on;
|
|
}
|
|
}
|
|
|
|
server {
|
|
listen [::1]:81;
|
|
|
|
root /var/empty;
|
|
|
|
location = /nginx_status {
|
|
stub_status;
|
|
access_log off;
|
|
}
|
|
|
|
location / {
|
|
return 404;
|
|
}
|
|
}
|
|
}
|