matrix.grapheneos.org/nginx/nginx.conf
Daniel Micay 7f61787026 switch to improved custom log format
This switches to a fully custom log format instead of using a variant of
the standard combined format since we don't use any tools requiring the
logs to be a standard format. This provides a cleaner format, allows us
to freely add new fields and gets rid of legacy/redundant fields.

The redundant timestamp already provided as the syslog timestamp is
dropped along with the legacy identd field always set to a dash.

This adds the connection serial number for identifying requests coming
from the same connection. TLS version is added as a replacement for our
previous addition of the URI scheme. This also adds the total request
length and total bytes sent to the client instead of only the body bytes
sent.
2023-02-10 08:04:30 -05:00

183 lines
5.7 KiB
Nginx Configuration File

# nginx 1.22.x
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 on;
sendfile_max_chunk 512k;
tcp_nopush on;
keepalive_requests 256;
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 2 1k;
http2_chunk_size 4k;
client_body_timeout 15s;
client_header_timeout 15s;
send_timeout 30s;
resolver [::1];
resolver_timeout 15s;
http2_max_concurrent_streams 16;
limit_conn_status 429;
limit_conn_zone $binary_remote_addr zone=addr-limit:10m;
limit_conn addr-limit 128;
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 '$connection $remote_addr $remote_user $ssl_protocol $server_protocol '
'$host "$request_uri" $status $request_length $body_bytes_sent/$bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log syslog:server=unix:/dev/log,nohostname main;
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;
location /.well-known/acme-challenge/ {
root /srv/certbot;
}
location / {
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 ~ ^(?:/_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 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" always;
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_send_timeout 15s;
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" always;
location ~ '\.(?:css|html|ico|js|json|map|svg|txt|wasm|xml)$' {
gzip_static on;
brotli_static on;
}
}
server {
listen unix:/run/nginx/status.sock;
root /var/empty;
location = / {
stub_status;
access_log off;
}
location / {
return 404;
}
}
}