1
1
mirror of https://gitlab.archlinux.org/archlinux/infrastructure.git synced 2025-01-18 08:06:16 +01:00
infrastructure/roles/archweb/templates/nginx.d.conf.j2
Kristian Klausen 8dfa7e8c3e
nginx: Add plumbing for enabling HTTP/3 conditionally
We want to roll out HTTP/3 slowly, so this adds the necessary plumbing
and makes it possible to enable it per host.

Instead of adding the conditional logic to each nginx template, the 443
listen config is moved out into a snippet which is managed by the nginx
role.

HTTP/3 uses QUIC which is built on UDP. UDP is connectionless and
therefore reuseport[1][2] must be used to ensure that UDP packets for
the same QUIC connection is directed to the same worker. reuseport can
only be enabled once, so a default_server is added to the
"inventory_hostname vhost" for SSL/QUIC (reuseport is only enabled for
the latter). ssl_reject_handshake[3] is enabled as that allows enabling
SSL/QUIC without specifying a certificate.

[1] https://nginx.org/en/docs/http/ngx_http_core_module.html#listen
[2] https://lwn.net/Articles/542629/
[3] http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_reject_handshake

Ref #606
2024-08-17 21:53:32 +02:00

246 lines
7.1 KiB
Django/Jinja

# limit rss requests to 1 r/m
limit_req_zone $binary_remote_addr zone=rsslimit:8m rate=1r/m;
# limit mirrors/status/json requests to 1 r/m
limit_req_zone $binary_remote_addr zone=mirrorstatuslimit:8m rate=1r/m;
# limit general requests to 5 r/s to block DoS attempts.
limit_req_zone $binary_remote_addr zone=archweblimit:10m rate=5r/s;
limit_req_status 429;
uwsgi_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=archwebcache:10m inactive=60m;
uwsgi_cache_key "$scheme$host$request_uri";
map $uri $cache_key {
default $scheme$host$request_uri;
/devel/mirrorauth/ $scheme$host$request_uri$http_authorization;
}
upstream archweb {
server unix:///run/uwsgi/archweb.sock;
}
{% if archweb_domains_templates -%}
{% for domain in archweb_domains_templates | dict2items(key_name='domain_name', value_name='template_name') %}
{% include domain['template_name'] %}
{% endfor %}
{%- endif %}
{% if archweb_domains_redirects %}
{% for domain in archweb_domains_redirects | dict2items(key_name='domain', value_name='redirect') %}
server {
listen 80;
listen [::]:80;
server_name {{ domain['domain'] }};
access_log /var/log/nginx/{{ archweb_domain }}/access.log reduced;
access_log /var/log/nginx/{{ archweb_domain }}/access.log.json json_reduced;
error_log /var/log/nginx/{{ archweb_domain }}/error.log;
include snippets/letsencrypt.conf;
location /.well-known/ {
include snippets/headers.conf;
add_header Access-Control-Allow-Origin *;
return 301 https://$server_name$request_uri;
}
location / {
access_log off;
return 301 https://$server_name$request_uri;
}
}
server {
include snippets/listen-443.conf;
server_name {{ domain['domain'] }};
access_log /var/log/nginx/{{ archweb_domain }}/access.log reduced;
access_log /var/log/nginx/{{ archweb_domain }}/access.log.json json_reduced;
error_log /var/log/nginx/{{ archweb_domain }}/error.log;
ssl_certificate /etc/letsencrypt/live/{{ archweb_domain }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ archweb_domain }}/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/{{ archweb_domain }}/chain.pem;
location /.well-known/ {
include snippets/headers.conf;
add_header Access-Control-Allow-Origin *;
return 301 https://{{ archweb_domain }}{{ domain['redirect']|default('$request_uri') }};
}
location / {
access_log off;
return 301 https://{{ archweb_domain }}{{ domain['redirect']|default('$request_uri') }};
}
}
{% endfor %}
server {
{% else %}
server {
{% endif %}
listen 80;
listen [::]:80;
server_name {{ archweb_domain }};
access_log /var/log/nginx/{{ archweb_domain }}/access.log reduced;
access_log /var/log/nginx/{{ archweb_domain }}/access.log.json json_reduced;
error_log /var/log/nginx/{{ archweb_domain }}/error.log;
include snippets/letsencrypt.conf;
location / {
access_log off;
return 301 https://$server_name$request_uri;
}
}
server {
include snippets/listen-443.conf;
server_name {{ archweb_domain }};
access_log /var/log/nginx/{{ archweb_domain }}/access.log reduced;
access_log /var/log/nginx/{{ archweb_domain }}/access.log.json json_reduced;
error_log /var/log/nginx/{{ archweb_domain }}/error.log;
ssl_certificate /etc/letsencrypt/live/{{ archweb_domain }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ archweb_domain }}/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/{{ archweb_domain }}/chain.pem;
location = /.well-known/matrix/server {
default_type application/json;
return 200 '{"m.server": "{{ matrix_domain }}:443"}';
}
location = /.well-known/matrix/client {
default_type application/json;
include snippets/headers.conf;
add_header Access-Control-Allow-Origin *;
return 200 '{"m.homeserver": {"base_url": "https://{{ matrix_domain }}"}, "m.identity_server": {"base_url": "https://matrix.org"} }';
}
location = /robots.txt {
alias {{ archweb_dir }}/archlinux.org/robots.txt;
}
location = /humans.txt {
alias {{ archweb_dir }}/archlinux.org/humans.txt;
}
location = /google7827eadf026b4a87.html {
alias {{ archweb_dir }}/archlinux.org/google7827eadf026b4a87.html;
}
location = /BingSiteAuth.xml {
alias {{ archweb_dir }}/archlinux.org/BingSiteAuth.xml;
}
location = /favicon.ico {
alias {{ archweb_dir }}/collected_static/favicon.ico;
}
location ~ ^/pacman/(.*)$ {
return 301 https://pacman.archlinux.page/$1;
}
location /netcfg/ {
alias {{ archweb_dir }}/archlinux.org/netcfg/;
}
location /logos/ {
alias {{ archweb_dir }}/archlinux.org/logos/;
}
location /iso/ {
alias {{ archweb_rsync_iso_dir }};
location ~ ^/iso/.*\.(sig|torrent|txt)$ {
}
location /iso/ {
deny all;
}
}
# Cache django's css, js and png files.
location /static/ {
expires 30d;
include snippets/headers.conf;
add_header Pragma public;
add_header Cache-Control "public";
alias {{ archweb_dir }}/collected_static/;
}
location /img/ {
alias {{ archweb_dir }}/media/img/;
}
location /retro/ {
alias {{ archweb_retro_dir }};
}
# Rate limit all RSS feeds
location ~ (^/feeds/|\.xml$) {
include uwsgi_params;
uwsgi_pass archweb;
uwsgi_cache archwebcache;
uwsgi_cache_revalidate on;
include snippets/headers.conf;
add_header X-Cache-Status $upstream_cache_status;
limit_req zone=rsslimit burst=10 nodelay;
}
# Rate limit mirror status json endpoint
location /mirrors/status/json {
include uwsgi_params;
uwsgi_pass archweb;
uwsgi_cache archwebcache;
uwsgi_cache_revalidate on;
uwsgi_cache_key $cache_key;
include snippets/headers.conf;
add_header X-Cache-Status $upstream_cache_status;
limit_req zone=mirrorstatuslimit burst=10 nodelay;
}
# Temporary redirects
location /people/trusted-user-fellows/ {
return 301 /people/package-maintainer-fellows/;
}
location /people/trusted-users/ {
return 301 /people/package-maintainers/;
}
location = /metrics {
if ($http_authorization != "Bearer {{ vault_archweb_metrics_token }}") {
return 403;
}
include uwsgi_params;
uwsgi_pass archweb;
}
location / {
access_log /var/log/nginx/{{ archweb_domain }}/access.log main;
access_log /var/log/nginx/{{ archweb_domain }}/access.log.json json_main;
include uwsgi_params;
uwsgi_pass archweb;
uwsgi_cache archwebcache;
uwsgi_cache_revalidate on;
uwsgi_cache_key $cache_key;
include snippets/headers.conf;
add_header X-Cache-Status $upstream_cache_status;
limit_req zone=archweblimit burst=10 nodelay;
}
}