- Simplify DHT encoding: use JSON instead of DNS packets (drop simple-dns) - Fix mainline crate API: SigningKey takes 32 bytes, get_mutable returns Result - Add missing dht_did field to IdentityRecord constructor - Store DID Document as JSON in DHT (DNS encoding deferred) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1009 lines
40 KiB
Plaintext
1009 lines
40 KiB
Plaintext
server {
|
|
listen 80;
|
|
listen 100.91.10.103:80;
|
|
server_name _;
|
|
|
|
root /opt/archipelago/web-ui;
|
|
index index.html;
|
|
|
|
# Security headers
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' ws: wss:; frame-src *" always;
|
|
|
|
# AIUI SPA (Chat mode iframe)
|
|
# Use =404 fallback instead of index.html to prevent serving HTML with wrong
|
|
# MIME type when JS/CSS files are missing (causes module script MIME errors)
|
|
location /aiui/ {
|
|
alias /opt/archipelago/web-ui/aiui/;
|
|
index index.html;
|
|
try_files $uri $uri/ /aiui/index.html;
|
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
|
}
|
|
|
|
# AIUI assets fallback — AIUI may reference /assets/ without /aiui/ prefix
|
|
location /aiui-assets/ {
|
|
alias /opt/archipelago/web-ui/aiui/assets/;
|
|
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
}
|
|
|
|
# AIUI Claude API proxy — requires valid session cookie
|
|
location /aiui/api/claude/ {
|
|
if ($cookie_session = "") {
|
|
return 401 '{"error":"Unauthorized"}';
|
|
}
|
|
proxy_pass http://127.0.0.1:3142/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
# Connection header managed by nginx default
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_buffering off;
|
|
proxy_cache off;
|
|
proxy_connect_timeout 120s;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 120s;
|
|
}
|
|
|
|
# AIUI OpenRouter API proxy — requires valid session cookie
|
|
location /aiui/api/openrouter/ {
|
|
if ($cookie_session = "") {
|
|
return 401 '{"error":"Unauthorized"}';
|
|
}
|
|
proxy_pass https://openrouter.ai/api/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host openrouter.ai;
|
|
# Connection header managed by nginx default
|
|
proxy_ssl_server_name on;
|
|
proxy_connect_timeout 120s;
|
|
proxy_read_timeout 120s;
|
|
proxy_send_timeout 120s;
|
|
}
|
|
|
|
# AIUI Ollama (local AI) proxy — localhost:11434
|
|
location /aiui/api/ollama/ {
|
|
if ($cookie_session = "") {
|
|
return 401 '{"error":"Unauthorized"}';
|
|
}
|
|
proxy_pass http://127.0.0.1:11434/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_buffering off;
|
|
proxy_cache off;
|
|
proxy_connect_timeout 120s;
|
|
proxy_read_timeout 300s;
|
|
# Connection header managed by nginx default
|
|
}
|
|
|
|
# AIUI web search proxy — SearXNG on port 8888
|
|
location /aiui/api/web-search {
|
|
if ($cookie_session = "") {
|
|
return 401 '{"error":"Unauthorized"}';
|
|
}
|
|
proxy_pass http://127.0.0.1:8888/search;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_connect_timeout 30s;
|
|
proxy_read_timeout 30s;
|
|
error_page 502 503 =503 @searxng_unavailable;
|
|
}
|
|
location @searxng_unavailable {
|
|
default_type application/json;
|
|
return 503 '{"error":"SearXNG is not running"}';
|
|
}
|
|
|
|
# Icons, favicon, manifest — always revalidate (no heuristic caching)
|
|
location ~* ^/(favicon\.ico|manifest\.webmanifest|assets/icon/) {
|
|
add_header Cache-Control "no-cache, must-revalidate";
|
|
try_files $uri =404;
|
|
}
|
|
|
|
# Serve static files (Vue.js SPA)
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
|
|
# Peer-to-peer node messaging (receives from other nodes over Tor)
|
|
location /archipelago/ {
|
|
proxy_pass http://127.0.0.1:5678;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
}
|
|
|
|
# Proxy API requests to backend
|
|
location /rpc/ {
|
|
proxy_pass http://127.0.0.1:5678;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
# Connection header managed by nginx default
|
|
|
|
# Limit request body to 1MB for RPC calls
|
|
client_max_body_size 1m;
|
|
|
|
# Increase timeout for long-running operations (e.g., Docker image pulls)
|
|
proxy_connect_timeout 600s;
|
|
proxy_send_timeout 600s;
|
|
proxy_read_timeout 600s;
|
|
}
|
|
|
|
# Backend status endpoints (must be before the SPA catch-all)
|
|
location /health {
|
|
proxy_pass http://127.0.0.1:5678/health;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
}
|
|
location /electrs-status {
|
|
proxy_pass http://127.0.0.1:5678/electrs-status;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
# CORS handled by backend
|
|
}
|
|
|
|
# Content sharing — peer access over Tor (no auth)
|
|
location /content {
|
|
proxy_pass http://127.0.0.1:5678;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
}
|
|
|
|
# DWN endpoints — peer access over Tor (no auth)
|
|
location /dwn {
|
|
proxy_pass http://127.0.0.1:5678;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
}
|
|
|
|
# Proxy apps that set X-Frame-Options - strip header so iframe works
|
|
location /app/nextcloud/ {
|
|
proxy_pass http://127.0.0.1:8085/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 300s;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/vaultwarden/ {
|
|
proxy_pass http://127.0.0.1:8082/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/immich/ {
|
|
proxy_pass http://127.0.0.1:2283/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 300s;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/penpot/ {
|
|
proxy_pass http://127.0.0.1:9001/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 300s;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
# Block path traversal attempts before they reach FileBrowser
|
|
location ~* /app/filebrowser/api/resources/.*/\.\. {
|
|
return 403;
|
|
}
|
|
location ~* /app/filebrowser/api/raw/.*/\.\. {
|
|
return 403;
|
|
}
|
|
location /app/filebrowser/ {
|
|
client_max_body_size 10G;
|
|
proxy_pass http://127.0.0.1:8083/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_request_buffering off;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/grafana/ {
|
|
proxy_pass http://127.0.0.1:3000/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/jellyfin/ {
|
|
proxy_pass http://127.0.0.1:8096/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/uptime-kuma/ {
|
|
proxy_pass http://127.0.0.1:3001/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/portainer/ {
|
|
proxy_pass http://127.0.0.1:9000/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/onlyoffice/ {
|
|
proxy_pass http://127.0.0.1:9980/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
# Remaining apps (also available on HTTPS via snippet include)
|
|
location /app/searxng/ {
|
|
proxy_pass http://127.0.0.1:8888/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/lnd/ {
|
|
proxy_pass http://127.0.0.1:8081/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 300s;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/mempool/ {
|
|
proxy_pass http://127.0.0.1:4080/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 300s;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/photoprism/ {
|
|
proxy_pass http://127.0.0.1:2342/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/fedimint/ {
|
|
proxy_pass http://127.0.0.1:8175/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 300s;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/fedimint-gateway/ {
|
|
proxy_pass http://127.0.0.1:8176/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 300s;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/tailscale/ {
|
|
proxy_pass http://127.0.0.1:8240/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/ollama/ {
|
|
proxy_pass http://127.0.0.1:11434/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/bitcoin-ui/ {
|
|
proxy_pass http://127.0.0.1:8334/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/electrs/ {
|
|
proxy_pass http://127.0.0.1:50002/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/endurain/ {
|
|
proxy_pass http://127.0.0.1:8080/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/nginx-proxy-manager/ {
|
|
proxy_pass http://127.0.0.1:81/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/btcpay/ {
|
|
proxy_pass http://127.0.0.1:23000/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/homeassistant/ {
|
|
proxy_pass http://127.0.0.1:8123/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_read_timeout 86400s;
|
|
proxy_send_timeout 86400s;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
|
|
# External site proxies — strip X-Frame-Options so iframe embedding works.
|
|
# add_header here prevents inheritance of server-level X-Frame-Options.
|
|
location /ext/botfights/ {
|
|
proxy_pass https://botfights.net/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host botfights.net;
|
|
proxy_set_header Accept-Encoding "";
|
|
proxy_ssl_server_name on;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_hide_header Cross-Origin-Embedder-Policy;
|
|
proxy_hide_header Cross-Origin-Opener-Policy;
|
|
proxy_hide_header Cross-Origin-Resource-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
sub_filter_once off;
|
|
sub_filter_types text/css application/javascript;
|
|
sub_filter 'href="/' 'href="/ext/botfights/';
|
|
sub_filter 'src="/' 'src="/ext/botfights/';
|
|
sub_filter 'action="/' 'action="/ext/botfights/';
|
|
sub_filter "href='/" "href='/ext/botfights/";
|
|
sub_filter "src='/" "src='/ext/botfights/";
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /ext/484-kitchen/ {
|
|
proxy_pass https://484.kitchen/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host 484.kitchen;
|
|
proxy_set_header Accept-Encoding "";
|
|
proxy_ssl_server_name on;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
sub_filter_once off;
|
|
sub_filter_types text/css application/javascript;
|
|
sub_filter 'href="/' 'href="/ext/484-kitchen/';
|
|
sub_filter 'src="/' 'src="/ext/484-kitchen/';
|
|
sub_filter 'action="/' 'action="/ext/484-kitchen/';
|
|
sub_filter "href='/" "href='/ext/484-kitchen/";
|
|
sub_filter "src='/" "src='/ext/484-kitchen/";
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /ext/arch-presentation/ {
|
|
proxy_pass https://present.l484.com/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host present.l484.com;
|
|
proxy_set_header Accept-Encoding "";
|
|
proxy_ssl_server_name on;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
sub_filter_once off;
|
|
sub_filter_types text/css application/javascript;
|
|
sub_filter 'href="/' 'href="/ext/arch-presentation/';
|
|
sub_filter 'src="/' 'src="/ext/arch-presentation/';
|
|
sub_filter 'action="/' 'action="/ext/arch-presentation/';
|
|
sub_filter "href='/" "href='/ext/arch-presentation/";
|
|
sub_filter "src='/" "src='/ext/arch-presentation/";
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /ext/nostrudel/ {
|
|
proxy_pass https://nostrudel.ninja/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host nostrudel.ninja;
|
|
proxy_set_header Accept-Encoding "";
|
|
proxy_ssl_server_name on;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_hide_header Cross-Origin-Embedder-Policy;
|
|
proxy_hide_header Cross-Origin-Opener-Policy;
|
|
proxy_hide_header Cross-Origin-Resource-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
sub_filter_once off;
|
|
sub_filter_types text/css application/javascript;
|
|
sub_filter 'href="/' 'href="/ext/nostrudel/';
|
|
sub_filter 'src="/' 'src="/ext/nostrudel/';
|
|
sub_filter 'action="/' 'action="/ext/nostrudel/';
|
|
sub_filter "href='/" "href='/ext/nostrudel/";
|
|
sub_filter "src='/" "src='/ext/nostrudel/";
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
|
|
# Proxy WebSocket
|
|
location /ws {
|
|
proxy_pass http://127.0.0.1:5678;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header Cookie $http_cookie;
|
|
proxy_read_timeout 86400s;
|
|
}
|
|
}
|
|
|
|
# HTTPS - required for PWA install (Add to Home Screen) from dev servers
|
|
server {
|
|
listen 443 ssl;
|
|
server_name _;
|
|
|
|
ssl_certificate /etc/archipelago/ssl/archipelago.crt;
|
|
ssl_certificate_key /etc/archipelago/ssl/archipelago.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;
|
|
|
|
root /opt/archipelago/web-ui;
|
|
index index.html;
|
|
include snippets/archipelago-pwa.conf;
|
|
|
|
# Security headers
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' ws: wss:; frame-src *" always;
|
|
|
|
# AIUI SPA (Chat mode iframe)
|
|
location /aiui/ {
|
|
alias /opt/archipelago/web-ui/aiui/;
|
|
index index.html;
|
|
try_files $uri $uri/ =404;
|
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
|
}
|
|
location /aiui/api/claude/ {
|
|
if ($cookie_session = "") {
|
|
return 401 '{"error":"Unauthorized"}';
|
|
}
|
|
proxy_pass http://127.0.0.1:3142/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
# Connection header managed by nginx default
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_buffering off;
|
|
proxy_cache off;
|
|
proxy_connect_timeout 120s;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 120s;
|
|
}
|
|
location /aiui/api/ollama/ {
|
|
if ($cookie_session = "") {
|
|
return 401 '{"error":"Unauthorized"}';
|
|
}
|
|
proxy_pass http://127.0.0.1:11434/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_buffering off;
|
|
proxy_cache off;
|
|
proxy_connect_timeout 120s;
|
|
proxy_read_timeout 300s;
|
|
# Connection header managed by nginx default
|
|
}
|
|
location /aiui/api/openrouter/ {
|
|
if ($cookie_session = "") {
|
|
return 401 '{"error":"Unauthorized"}';
|
|
}
|
|
proxy_pass https://openrouter.ai/api/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host openrouter.ai;
|
|
# Connection header managed by nginx default
|
|
proxy_ssl_server_name on;
|
|
proxy_connect_timeout 120s;
|
|
proxy_read_timeout 120s;
|
|
proxy_send_timeout 120s;
|
|
}
|
|
|
|
# Icons, favicon, manifest — always revalidate (no heuristic caching)
|
|
location ~* ^/(favicon\.ico|manifest\.webmanifest|assets/icon/) {
|
|
add_header Cache-Control "no-cache, must-revalidate";
|
|
try_files $uri =404;
|
|
}
|
|
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
|
|
location /archipelago/ {
|
|
proxy_pass http://127.0.0.1:5678;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
}
|
|
|
|
location /health {
|
|
proxy_pass http://127.0.0.1:5678/health;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
}
|
|
location /electrs-status {
|
|
proxy_pass http://127.0.0.1:5678/electrs-status;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
# CORS handled by backend
|
|
}
|
|
|
|
# Content sharing — peer access over Tor (no auth)
|
|
location /content {
|
|
proxy_pass http://127.0.0.1:5678;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
}
|
|
|
|
# DWN endpoints — peer access over Tor (no auth)
|
|
location /dwn {
|
|
proxy_pass http://127.0.0.1:5678;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
}
|
|
|
|
location /rpc/ {
|
|
proxy_pass http://127.0.0.1:5678;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
# Connection header managed by nginx default
|
|
|
|
# Limit request body to 1MB for RPC calls
|
|
client_max_body_size 1m;
|
|
|
|
proxy_connect_timeout 600s;
|
|
proxy_send_timeout 600s;
|
|
proxy_read_timeout 600s;
|
|
}
|
|
|
|
location /app/nextcloud/ {
|
|
proxy_pass http://127.0.0.1:8085/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 300s;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/vaultwarden/ {
|
|
proxy_pass http://127.0.0.1:8082/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/immich/ {
|
|
proxy_pass http://127.0.0.1:2283/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 300s;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/penpot/ {
|
|
proxy_pass http://127.0.0.1:9001/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 300s;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/btcpay/ {
|
|
proxy_pass http://127.0.0.1:23000/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /app/homeassistant/ {
|
|
proxy_pass http://127.0.0.1:8123/;
|
|
proxy_http_version 1.1;
|
|
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;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_read_timeout 86400s;
|
|
proxy_send_timeout 86400s;
|
|
proxy_set_header Accept-Encoding "";
|
|
sub_filter_once on;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
# All remaining app proxies (mempool, fedimint, lnd, bitcoin-ui, etc.)
|
|
include snippets/archipelago-https-app-proxies.conf;
|
|
|
|
# External site proxies — strip X-Frame-Options so iframe embedding works.
|
|
# add_header here prevents inheritance of server-level X-Frame-Options.
|
|
location /ext/botfights/ {
|
|
proxy_pass https://botfights.net/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host botfights.net;
|
|
proxy_set_header Accept-Encoding "";
|
|
proxy_ssl_server_name on;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_hide_header Cross-Origin-Embedder-Policy;
|
|
proxy_hide_header Cross-Origin-Opener-Policy;
|
|
proxy_hide_header Cross-Origin-Resource-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
sub_filter_once off;
|
|
sub_filter_types text/css application/javascript;
|
|
sub_filter 'href="/' 'href="/ext/botfights/';
|
|
sub_filter 'src="/' 'src="/ext/botfights/';
|
|
sub_filter 'action="/' 'action="/ext/botfights/';
|
|
sub_filter "href='/" "href='/ext/botfights/";
|
|
sub_filter "src='/" "src='/ext/botfights/";
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /ext/484-kitchen/ {
|
|
proxy_pass https://484.kitchen/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host 484.kitchen;
|
|
proxy_set_header Accept-Encoding "";
|
|
proxy_ssl_server_name on;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
sub_filter_once off;
|
|
sub_filter_types text/css application/javascript;
|
|
sub_filter 'href="/' 'href="/ext/484-kitchen/';
|
|
sub_filter 'src="/' 'src="/ext/484-kitchen/';
|
|
sub_filter 'action="/' 'action="/ext/484-kitchen/';
|
|
sub_filter "href='/" "href='/ext/484-kitchen/";
|
|
sub_filter "src='/" "src='/ext/484-kitchen/";
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /ext/arch-presentation/ {
|
|
proxy_pass https://present.l484.com/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host present.l484.com;
|
|
proxy_set_header Accept-Encoding "";
|
|
proxy_ssl_server_name on;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
sub_filter_once off;
|
|
sub_filter_types text/css application/javascript;
|
|
sub_filter 'href="/' 'href="/ext/arch-presentation/';
|
|
sub_filter 'src="/' 'src="/ext/arch-presentation/';
|
|
sub_filter 'action="/' 'action="/ext/arch-presentation/';
|
|
sub_filter "href='/" "href='/ext/arch-presentation/";
|
|
sub_filter "src='/" "src='/ext/arch-presentation/";
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
location /ext/nostrudel/ {
|
|
proxy_pass https://nostrudel.ninja/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host nostrudel.ninja;
|
|
proxy_set_header Accept-Encoding "";
|
|
proxy_ssl_server_name on;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_hide_header Cross-Origin-Embedder-Policy;
|
|
proxy_hide_header Cross-Origin-Opener-Policy;
|
|
proxy_hide_header Cross-Origin-Resource-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
sub_filter_once off;
|
|
sub_filter_types text/css application/javascript;
|
|
sub_filter 'href="/' 'href="/ext/nostrudel/';
|
|
sub_filter 'src="/' 'src="/ext/nostrudel/';
|
|
sub_filter 'action="/' 'action="/ext/nostrudel/';
|
|
sub_filter "href='/" "href='/ext/nostrudel/";
|
|
sub_filter "src='/" "src='/ext/nostrudel/";
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
}
|
|
|
|
location /ws {
|
|
proxy_pass http://127.0.0.1:5678;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_read_timeout 86400s;
|
|
}
|
|
}
|
|
|
|
# External site reverse proxies — each on its own port so SPAs work at root.
|
|
# Strips X-Frame-Options to allow iframe embedding from Archipelago UI.
|
|
# Injects NIP-07 nostr-provider.js for Nostr login integration.
|
|
server {
|
|
listen 8901;
|
|
server_name _;
|
|
location / {
|
|
proxy_pass https://botfights.net;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host botfights.net;
|
|
proxy_set_header Accept-Encoding "";
|
|
proxy_ssl_server_name on;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
proxy_hide_header Cross-Origin-Embedder-Policy;
|
|
proxy_hide_header Cross-Origin-Opener-Policy;
|
|
proxy_hide_header Cross-Origin-Resource-Policy;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
sub_filter_once on;
|
|
}
|
|
# Serve nostr-provider.js from the main web-ui directory
|
|
location = /nostr-provider.js {
|
|
alias /opt/archipelago/web-ui/nostr-provider.js;
|
|
}
|
|
}
|
|
|
|
server {
|
|
listen 8902;
|
|
server_name _;
|
|
location / {
|
|
proxy_pass https://484.kitchen;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host 484.kitchen;
|
|
proxy_set_header Accept-Encoding "";
|
|
proxy_ssl_server_name on;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
sub_filter_once on;
|
|
}
|
|
location = /nostr-provider.js {
|
|
alias /opt/archipelago/web-ui/nostr-provider.js;
|
|
}
|
|
}
|
|
|
|
server {
|
|
listen 8903;
|
|
server_name _;
|
|
location / {
|
|
proxy_pass https://present.l484.com;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host present.l484.com;
|
|
proxy_set_header Accept-Encoding "";
|
|
proxy_ssl_server_name on;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header Content-Security-Policy;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
|
sub_filter_once on;
|
|
}
|
|
location = /nostr-provider.js {
|
|
alias /opt/archipelago/web-ui/nostr-provider.js;
|
|
}
|
|
}
|
|
|