Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ Kubernetes
----------

See more in the [kubernetes/ directory](kubernetes/)

Webserver
---------

The [webserver / directory](webserver/) provides examples for e.g. nginx configuration
17 changes: 17 additions & 0 deletions webserver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Webserver Examples
==================

nginx
-----

**The nginx example needs at least nginx version 1.20.**

When you want to use the nginx example, including caching, you need to create the specific directories first, so that nginx will not run into errors:

```bash
mkdir -p /usr/share/nginx/takahe/{static,cache,logs}
```

If you don't want caching, remove the lines starting with `proxy_cache_`, `add_header X-Cache $upstream_cache_status;` and `proxy_ignore_headers X-Accel-Expires Expires Cache-Control;`

Remember to use the command `nginx -t` to check, if the configuration works.
196 changes: 196 additions & 0 deletions webserver/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
limit_req_zone $binary_remote_addr zone=taka_proxy:20m rate=200r/s;
limit_req_zone $binary_remote_addr zone=taka_media:20m rate=50r/s;
limit_req_zone $binary_remote_addr zone=taka_ratelimit:20m rate=25r/s;
proxy_cache_path /usr/share/nginx/takahe/cache levels=1:2 keys_zone=TAKAHE:20m inactive=14d max_size=1g;

upstream takahe {
server "127.0.0.1:8000";
}

server {
listen 80;
listen [::]:80;
server_name _;

# Let's Encrypt SSL challenge directory
location ^~ /.well-known/acme-challenge {
default_type text/plain;
alias /usr/share/nginx/tmp/.well-known/acme-challenge;
}

return 301 https://$server_name/$request_uri;
}

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name _;

root /usr/share/nginx/takahe/static;
index index.html;

access_log /usr/share/nginx/takahe/logs/access.log combined;
error_log /usr/share/nginx/takahe/logs/error.log;

# Let's Encrypt SSL challenge directory
location ^~ /.well-known/acme-challenge {
default_type text/plain;
alias /usr/share/nginx/tmp/.well-known/acme-challenge;
}

ssl_protocols TLSv1.2 TLSv1.3;

# Using the recommended cipher suite from: https://wiki.mozilla.org/Security/Server_Side_TLS
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';

ssl_session_timeout 10m;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;

# Specifies a curve for ECDHE ciphers.
ssl_ecdh_curve prime256v1;
# Server should determine the ciphers, not the client
ssl_prefer_server_ciphers on;

ssl_stapling on;
ssl_stapling_verify on;

# GZIP Section
gzip on;
gzip_disable "msie6";

gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types text/xml text/javascript font/ttf font/eot font/otf application/x-javascript application/atom+xml application/javascript application/json application/manifest+json application/rss+xml application/x-web-app-manifest+json application/xhtml+xml application/xml image/svg+xml image/x-icon text/css text/plain;

ignore_invalid_headers on;
proxy_connect_timeout 900;

ssl_certificate /root/.acme.sh/takahe_host/fullchain.cer;
ssl_certificate_key /root/.acme.sh/takahe_host/takahe_host.key;
ssl_trusted_certificate /root/.acme.sh/takahe_host/ca.cer;
ssl_dhparam /etc/ssl/dhparams_4096.pem;

proxy_headers_hash_max_size 1024;
proxy_headers_hash_bucket_size 128;

client_max_body_size 512M;
client_body_buffer_size 128k;
charset utf-8;

proxy_set_header Host $http_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 $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 15m;
proxy_send_timeout 15m;

proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_cookie_flags ~ secure HttpOnly;

add_header 'Content-Security-Policy' "default-src 'none'; connect-src 'self'; font-src 'self'; img-src *; script-src 'self' 'unsafe-inline'; object-src 'self'; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests;";
add_header 'X-Robots-Tag' "index, follow, noimageindex, notranslate, noarchive";
add_header 'Strict-Transport-Security' 'max-age=63072000; includeSubDomains; preload';
add_header 'X-XSS-Protection' '1; mode=block';
add_header 'Permissions-Policy' 'geolocation=(), microphone=()';
add_header 'Access-Control-Allow-Origin' '*';

location = /robots.txt {
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /proxy/\nDisallow: /static/\nDisallow: /media/\nCrawl-delay: 1";
}

location = /.well-known/gpc.json {
add_header Content-Type application/json;
return 200 '{"gpc": true,"version": 1,"lastUpdate": "2022-12-16"}';
}

location ~* ^/(media|static) {
http2_push_preload on;
limit_req zone=taka_media burst=5 nodelay;
proxy_cache TAKAHE;
proxy_buffering on;
proxy_request_buffering on;
proxy_cache_convert_head off;

proxy_cache_key $host$uri;
proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
proxy_hide_header Set-Cookie;
proxy_hide_header X-Robots-Tag;

proxy_cache_revalidate on;
proxy_cache_lock on;
proxy_cache_valid 200 304 720h;
proxy_cache_valid 301 307 12h;
proxy_cache_valid 500 502 503 504 0s;
proxy_cache_valid any 72h;
proxy_cache_min_uses 1;
proxy_cache_use_stale error timeout updating http_500 http_502
http_503 http_504;
proxy_cache_background_update on;
proxy_cache_methods GET HEAD;

add_header X-Cache $upstream_cache_status;

proxy_pass http://takahe;
}

location ~* ^/proxy {
http2_push_preload on;
limit_req zone=taka_proxy burst=50 delay=20;
proxy_cache TAKAHE;
proxy_buffering on;
proxy_request_buffering on;
proxy_cache_convert_head off;

proxy_cache_key $host$uri;
proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
proxy_hide_header Set-Cookie;
proxy_hide_header X-Robots-Tag;

proxy_cache_revalidate on;
proxy_cache_lock on;
proxy_cache_valid 200 304 720h;
proxy_cache_valid 301 307 12h;
proxy_cache_valid 500 502 503 504 0s;
proxy_cache_valid any 72h;
proxy_cache_min_uses 1;
proxy_cache_use_stale error timeout updating http_500 http_502
http_503 http_504;
proxy_cache_background_update on;
proxy_cache_methods GET HEAD;

add_header X-Cache $upstream_cache_status;
proxy_pass http://takahe;
}

location ~* ^/(djadmin|api) {
http2_push_preload off;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://takahe;
}

location / {
limit_req zone=taka_ratelimit burst=15 delay=5;
sub_filter '</head>' '<meta name="robots" content="index, follow, noimageindex, notranslate, noarchive"></head>';
sub_filter_once on;

http2_push_preload on;

proxy_redirect off;
proxy_buffering off;
proxy_pass http://takahe;
}
}