Add Strict-Transport-Security (max-age 1y, includeSubDomains) to every TLS server block in both vhost templates. Combined with the existing port-80 301 redirect, browsers refuse plain HTTP to these names after first visit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
94 lines
3.7 KiB
Cheetah
94 lines
3.7 KiB
Cheetah
# ──────────────────────────────────────────────────────────────────
|
|
# Ulicraft host nginx — TLS ingress with Let's Encrypt certs.
|
|
# ──────────────────────────────────────────────────────────────────
|
|
# Template. Render with BOTH vars then install:
|
|
#
|
|
# APP_DIR=/home/ubuntu/mc/ulicraft-server-v1 BASE_DOMAIN=ulicraft.net \
|
|
# envsubst '$APP_DIR $BASE_DOMAIN' \
|
|
# < nginx/ulicraft.conf.tmpl | sudo tee /etc/nginx/sites-available/ulicraft.conf
|
|
# sudo ln -sf /etc/nginx/sites-available/ulicraft.conf /etc/nginx/sites-enabled/
|
|
# sudo nginx -t && sudo systemctl reload nginx
|
|
#
|
|
# Prereqs:
|
|
# - certs issued: tooling/issue-letsencrypt.sh -> $APP_DIR/certs/<name>/{cert,key}.pem
|
|
# - the docker stack up with the nginx override (publishes drasl on 127.0.0.1:25585):
|
|
# docker compose -f docker-compose.yml -f docker-compose.nginx.yml up -d
|
|
# - nginx's user (www-data) can READ $APP_DIR/{www,pack,custom,certs}
|
|
# ──────────────────────────────────────────────────────────────────
|
|
|
|
# HTTP -> HTTPS for every name.
|
|
server {
|
|
listen 80;
|
|
listen [::]:80;
|
|
server_name ${BASE_DOMAIN} auth.${BASE_DOMAIN} pack.${BASE_DOMAIN};
|
|
return 301 https://$host$request_uri;
|
|
}
|
|
|
|
# Apex — static landing page (./www) + launcher downloads (./mirror/launcher).
|
|
# /ca.crt from the caddy path is intentionally omitted: LE certs are publicly
|
|
# trusted, so guests need no CA import.
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name ${BASE_DOMAIN};
|
|
|
|
ssl_certificate ${APP_DIR}/certs/${BASE_DOMAIN}/cert.pem;
|
|
ssl_certificate_key ${APP_DIR}/certs/${BASE_DOMAIN}/key.pem;
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
|
|
# Launcher downloads (populated by tooling/fetch-launcher.sh -> ./mirror/launcher).
|
|
location /launcher/ {
|
|
alias ${APP_DIR}/mirror/launcher/;
|
|
autoindex on;
|
|
}
|
|
|
|
location / {
|
|
root ${APP_DIR}/www;
|
|
index index.html;
|
|
try_files $uri $uri/ =404;
|
|
}
|
|
}
|
|
|
|
# Pack — packwiz metadata (./pack) + custom jars (./custom at /custom/).
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name pack.${BASE_DOMAIN};
|
|
|
|
ssl_certificate ${APP_DIR}/certs/pack.${BASE_DOMAIN}/cert.pem;
|
|
ssl_certificate_key ${APP_DIR}/certs/pack.${BASE_DOMAIN}/key.pem;
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
|
|
# Locally-hosted custom mod jars live outside ./pack; expose them at /custom/.
|
|
location /custom/ {
|
|
alias ${APP_DIR}/custom/;
|
|
autoindex on;
|
|
}
|
|
|
|
location / {
|
|
root ${APP_DIR}/pack;
|
|
autoindex on;
|
|
}
|
|
}
|
|
|
|
# Auth — reverse proxy to drasl (published on localhost by the nginx override).
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name auth.${BASE_DOMAIN};
|
|
|
|
ssl_certificate ${APP_DIR}/certs/auth.${BASE_DOMAIN}/cert.pem;
|
|
ssl_certificate_key ${APP_DIR}/certs/auth.${BASE_DOMAIN}/key.pem;
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
|
|
client_max_body_size 4m; # skin uploads
|
|
|
|
location / {
|
|
proxy_pass http://127.0.0.1:25585;
|
|
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 $scheme;
|
|
}
|
|
}
|