diff options
Diffstat (limited to 'deploy/nginx-edge-img.conf')
| -rw-r--r-- | deploy/nginx-edge-img.conf | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/deploy/nginx-edge-img.conf b/deploy/nginx-edge-img.conf new file mode 100644 index 0000000..3d6ac16 --- /dev/null +++ b/deploy/nginx-edge-img.conf @@ -0,0 +1,68 @@ +# --- img.dieschoenewolke.de: public read-only OCI mirror --------------------- +# Merge this block into /root/Compose/Webserver/NginxEdge/nginx/default.conf +# (write in place: `cat new > default.conf`) and force-recreate edge-nginx. +# +# docker/containerd/skopeo/crane all speak plain GET+HEAD with a Go or Docker +# user agent. CRS treats those as scanners, so AppSec is off for this host - the +# CrowdSec IP bouncer still applies and the registry itself is read-only. +# `limit_except GET` is the second lock: even if zot were reconfigured, the edge +# refuses every write verb. +# +# A path-based /v2/ on git.dieschoenewolke.de is NOT an option: OCI clients +# build the repository name from <host>/<path>, so a shared host would force +# names like git.dieschoenewolke.de/distroless/static and the /v2/ base path +# would have to be stripped by the edge. docker's ping is +# GET /v2/ (not /git/v2/), so the mirror gets its own name. The wildcard +# *.dieschoenewolke.de certificate already covers it - no cert change. +server { + listen 443 ssl; + listen [::]:443 ssl; + listen 443 quic; + listen [::]:443 quic; + http2 on; + server_name img.dieschoenewolke.de; + access_log /dev/stdout edge; + + set $crowdsec_disable_appsec 1; + + add_header Alt-Svc 'h3=":443"; ma=86400' always; + + ssl_certificate /certs/edge.crt; + ssl_certificate_key /certs/edge.key; + 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; + ssl_prefer_server_ciphers off; + ssl_ecdh_curve X25519:prime256v1:secp384r1; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 1d; + ssl_session_tickets off; + + more_set_headers + "Strict-Transport-Security: max-age=31536000; includeSubDomains" + "X-Content-Type-Options: nosniff" + "Referrer-Policy: strict-origin-when-cross-origin"; + + # a manifest/index is a few hundred KB; layers are streamed, never buffered + client_max_body_size 4m; + + location / { + limit_except GET { + deny all; + } + + proxy_pass http://127.0.0.1:5000; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + # stream blobs instead of spooling them to the edge disk (28 GB root) + proxy_buffering off; + proxy_max_temp_file_size 0; + proxy_request_buffering off; + proxy_read_timeout 900s; + proxy_send_timeout 900s; + proxy_cache off; + } +} |
