# podsteadr-player on its own HTTPS domain, plus the FIPS gateway. # # Install: /etc/nginx/sites-available/player-domain, symlinked into sites-enabled. # Certificate: certbot certonly --nginx -d player.atobitcoin.io (needs the port-80 # block live first — see deploy/README.md). # # The player itself runs in the podsteadr-player container on 127.0.0.1:8097. That # container is also published on the FIPS mesh (http://.fips:8097/), where it # fetches .fips feeds directly; this HTTPS copy can't (browsers block http:// from # https:// pages), so it uses the /fips/ gateway below instead. limit_req_zone $binary_remote_addr zone=player_fips_feeds:10m rate=5r/s; limit_conn_zone $binary_remote_addr zone=player_fips_conns:10m; server { listen 80; listen [::]:80; server_name player.atobitcoin.io; location /.well-known/acme-challenge/ { root /var/www/html; } location / { return 301 https://$host$request_uri; } } server { listen 443 ssl; listen [::]:443 ssl; server_name player.atobitcoin.io; ssl_certificate /etc/letsencrypt/live/player.atobitcoin.io/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/player.atobitcoin.io/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; add_header X-Content-Type-Options nosniff always; add_header Referrer-Policy no-referrer always; location / { proxy_pass http://127.0.0.1:8097; proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; } # ---- FIPS gateway ------------------------------------------------------------ # /fips/.fips// -> http://.fips:/, over this # node's own FIPS link. Deliberately NOT a general mesh proxy: anyone on the # internet can call it, and mesh peers expose things (node UIs on :80, the peer # API on :5679) that must never be reachable from here. Only podcast content # passes: podsteadr catalogs/feeds on 8095 and blossom blobs on 8098, GET/HEAD # only, no client cookies or credentials forwarded. # # .fips names resolve via the fips daemon's DNS on 127.0.0.1:5354 (AAAA only). # Not via systemd-resolved: on this node it routes ~fips to [::1]:5354, where the # daemon isn't listening. location ~ "^/fips/(?(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+fips)/8095/(?catalog\.opml|feeds/[A-Za-z0-9_-]+/feed\.xml)$" { limit_except GET { deny all; } limit_req zone=player_fips_feeds burst=20 nodelay; resolver 127.0.0.1:5354 ipv4=off valid=60s; resolver_timeout 5s; # Host is what makes podsteadr write mesh (.fips) enclosure URLs into the feed. proxy_pass http://$fips_host:8095/$fips_path; proxy_set_header Host $fips_host:8095; proxy_set_header Cookie ""; proxy_set_header Authorization ""; proxy_hide_header Set-Cookie; proxy_connect_timeout 20s; proxy_read_timeout 30s; } location ~ "^/fips/(?(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+fips)/8098/(?[0-9a-f]{64}(?:\.[a-z0-9]{1,8})?)$" { limit_except GET { deny all; } limit_conn player_fips_conns 8; resolver 127.0.0.1:5354 ipv4=off valid=60s; resolver_timeout 5s; # Range/If-Range pass through untouched, so seeking works; stream, don't buffer. proxy_pass http://$fips_host:8098/$fips_path; proxy_set_header Host $fips_host:8098; proxy_set_header Cookie ""; proxy_set_header Authorization ""; proxy_hide_header Set-Cookie; proxy_http_version 1.1; proxy_buffering off; proxy_connect_timeout 20s; proxy_read_timeout 120s; } location /fips/ { return 404; } }