diff --git a/crates/utils/translations b/crates/utils/translations index f5d6f0eab..454debaed 160000 --- a/crates/utils/translations +++ b/crates/utils/translations @@ -1 +1 @@ -Subproject commit f5d6f0eabafd559417bf8f203fd655f7858bffcf +Subproject commit 454debaede4cc932ac15fea9bf620cf1daf1ae4c diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml index 9a9cead62..a0fe5cfeb 100644 --- a/docker/prod/docker-compose.yml +++ b/docker/prod/docker-compose.yml @@ -34,6 +34,7 @@ services: networks: - lemmyinternal restart: always + environment: - RUST_LOG="warn,lemmy_server=info,lemmy_api=info,lemmy_api_common=info,lemmy_api_crud=info,lemmy_apub=info,lemmy_db_schema=info,lemmy_db_views=info,lemmy_db_views_actor=info,lemmy_db_views_moderator=info,lemmy_routes=info,lemmy_utils=info,lemmy_websocket=info" volumes: - ./lemmy.hjson:/config/config.hjson diff --git a/docker/prod/nginx.conf b/docker/prod/nginx.conf index 3e0bc3491..38d64d295 100644 --- a/docker/prod/nginx.conf +++ b/docker/prod/nginx.conf @@ -1,152 +1,147 @@ # nginx example config # replace {{yourdomain}} and review the certbot/letsencrypt config -worker_processes 1; -events { - worker_connections 1024; + +limit_req_zone $binary_remote_addr zone={{yourdomain}}_ratelimit:10m rate=1r/s; + +upstream lemmy { + # this needs to map to the lemmy (server) docker service hostname + server "lemmy:8536"; +} +upstream lemmy-ui { + # this needs to map to the lemmy-ui docker service hostname + server "lemmy-ui:1234"; } -http { - limit_req_zone $binary_remote_addr zone={{yourdomain}}_ratelimit:10m rate=1r/s; - upstream lemmy { - # this needs to map to the lemmy (server) docker service hostname - server "lemmy:8536"; +server { + # allow letsencrypt challenge + # redirect everything else to 443 + listen 80; + listen [::]:80; + server_name {{yourdomain}}; + location /.well-known/acme-challenge/ { + root /var/www/certbot; } - upstream lemmy-ui { - # this needs to map to the lemmy-ui docker service hostname - server "lemmy-ui:1234"; + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name {{yourdomain}}; + + ssl_certificate /etc/letsencrypt/live/{{yourdomain}}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{yourdomain}}/privkey.pem; + + # Various TLS hardening settings + # https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; + ssl_session_timeout 10m; + ssl_session_cache shared:SSL:10m; + ssl_session_tickets on; + ssl_stapling on; + ssl_stapling_verify on; + + # Hide nginx version + server_tokens off; + + # Enable compression for JS/CSS/HTML bundle, for improved client load times. + # It might be nice to compress JSON, but leaving that out to protect against potential + # compression+encryption information leak attacks like BREACH. + gzip on; + gzip_types text/css application/javascript image/svg+xml; + gzip_vary on; + + # Only connect to this site via HTTPS for the two years + add_header Strict-Transport-Security "max-age=63072000"; + + # Various content security headers + add_header Referrer-Policy "same-origin"; + add_header X-Content-Type-Options "nosniff"; + add_header X-Frame-Options "DENY"; + add_header X-XSS-Protection "1; mode=block"; + + # Upload limit for pictrs + client_max_body_size 20M; + + # frontend + location / { + # distinguish between ui requests and backend + # don't change lemmy-ui or lemmy here, they refer to the upstream definitions on top + set $proxpass "http://lemmy-ui"; + + if ($http_accept = "application/activity+json") { + set $proxpass "http://lemmy"; + } + if ($http_accept = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") { + set $proxpass "http://lemmy"; + } + if ($request_method = POST) { + set $proxpass "http://lemmy"; + } + proxy_pass $proxpass; + + rewrite ^(.+)/+$ $1 permanent; + + # Send actual client IP upstream + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } - server { - # allow letsencrypt challenge - # redirect everything else to 443 - listen 80; - listen [::]:80; - server_name {{yourdomain}}; - location /.well-known/acme-challenge/ { - root /var/www/certbot; - } - location / { - return 301 https://$host$request_uri; - } + # backend + location ~ ^/(api|feeds|nodeinfo|.well-known) { + proxy_pass "http://lemmy"; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # Rate limit + limit_req zone={{yourdomain}}_ratelimit burst=30 nodelay; + + # Add IP forwarding headers + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name {{yourdomain}}; + # pictrs only - for adding browser cache control. + location ~ ^/(pictrs) { + # allow browser cache, images never update, we can apply long term cache + expires 120d; + add_header Pragma "public"; + add_header Cache-Control "public"; - ssl_certificate /etc/letsencrypt/live/{{yourdomain}}/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/{{yourdomain}}/privkey.pem; + proxy_pass "http://lemmy"; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; - # Various TLS hardening settings - # https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html - ssl_protocols TLSv1.2 TLSv1.3; - ssl_prefer_server_ciphers on; - ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; - ssl_session_timeout 10m; - ssl_session_cache shared:SSL:10m; - ssl_session_tickets on; - ssl_stapling on; - ssl_stapling_verify on; + # Rate limit + limit_req zone={{yourdomain}}_ratelimit burst=30 nodelay; - # Hide nginx version - server_tokens off; - - # Enable compression for JS/CSS/HTML bundle, for improved client load times. - # It might be nice to compress JSON, but leaving that out to protect against potential - # compression+encryption information leak attacks like BREACH. - gzip on; - gzip_types text/css application/javascript image/svg+xml; - gzip_vary on; - - # Only connect to this site via HTTPS for the two years - add_header Strict-Transport-Security "max-age=63072000"; - - # Various content security headers - add_header Referrer-Policy "same-origin"; - add_header X-Content-Type-Options "nosniff"; - add_header X-Frame-Options "DENY"; - add_header X-XSS-Protection "1; mode=block"; - - # Upload limit for pictrs - client_max_body_size 20M; - - # frontend - location / { - # distinguish between ui requests and backend - # don't change lemmy-ui or lemmy here, they refer to the upstream definitions on top - set $proxpass "http://lemmy-ui"; - - if ($http_accept = "application/activity+json") { - set $proxpass "http://lemmy"; - } - if ($http_accept = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") { - set $proxpass "http://lemmy"; - } - if ($request_method = POST) { - set $proxpass "http://lemmy"; - } - proxy_pass $proxpass; - - rewrite ^(.+)/+$ $1 permanent; - - # Send actual client IP upstream - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - - # backend - location ~ ^/(api|feeds|nodeinfo|.well-known) { - proxy_pass "http://lemmy"; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # Rate limit - limit_req zone={{yourdomain}}_ratelimit burst=30 nodelay; - - # Add IP forwarding headers - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - - # pictrs only - for adding browser cache control. - location ~ ^/(pictrs) { - # allow browser cache, images never update, we can apply long term cache - expires 120d; - add_header Pragma "public"; - add_header Cache-Control "public"; - - proxy_pass "http://lemmy"; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # Rate limit - limit_req zone={{yourdomain}}_ratelimit burst=30 nodelay; - - # Add IP forwarding headers - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - - # Redirect pictshare images to pictrs - location ~ /pictshare/(.*)$ { - return 301 /pictrs/image/$1; - } + # Add IP forwarding headers + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } - # Anonymize IP addresses - # https://www.supertechcrew.com/anonymizing-logs-nginx-apache/ - map $remote_addr $remote_addr_anon { - ~(?P\d+\.\d+\.\d+)\. $ip.0; - ~(?P[^:]+:[^:]+): $ip::; - 127.0.0.1 $remote_addr; - ::1 $remote_addr; - default 0.0.0.0; + # Redirect pictshare images to pictrs + location ~ /pictshare/(.*)$ { + return 301 /pictrs/image/$1; } - access_log /var/log/nginx/access.log combined; -} \ No newline at end of file +} + +# Anonymize IP addresses +# https://www.supertechcrew.com/anonymizing-logs-nginx-apache/ +map $remote_addr $remote_addr_anon { + ~(?P\d+\.\d+\.\d+)\. $ip.0; + ~(?P[^:]+:[^:]+): $ip::; + 127.0.0.1 $remote_addr; + ::1 $remote_addr; + default 0.0.0.0; +} +access_log /var/log/nginx/access.log combined;