Files
observer/asset/nginx/quantus.blackbeard.observer.conf
T
grenadeandClaude Fable 5.1 54db950957
deploy / build (push) Successful in 10m25s
deploy / deploy-web (push) Failing after 3s
deploy / deploy-api (push) Failing after 5s
infra: public node endpoints quantus. and planck.blackbeard.observer
One name per chain for the blackbeard wallet (blackbeard/wallet #53), on
the same edge proxy as the site: a CNAME to the site indirection, a Let's
Encrypt certificate, and a vhost that proxies JSON-RPC over HTTP and
WebSocket to the chain's upstream. quantus_node is our node on bob across
the mesh (bob's firewalld now admits oolon by name, lair/quantus deploy);
planck_node is Quantus's two official testnet hosts over TLS with SNI and
verification, since we run no testnet node. Upstreams and the per-client
throttle zones (20 requests a second with a burst of 40, 16 concurrent
connections, 429 on excess) live in conf.d/blackbeard-nodes.conf so each
vhost stands alone.

script/infra-setup.sh gains a nodes role that does the three steps per
name, enables the vhosts only after nginx -t passes and disables them
again if it does not, and ends by asking each name for system_chain.
Run today: both names carry certificates to 2026-12-15 and Planck
answers; the quantus record was still propagating when the script asked.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ftBXYuba8ARhQeF74oUgW
2026-09-16 09:11:11 +03:00

72 lines
3.1 KiB
Plaintext

# Public JSON-RPC and WebSocket endpoint for the Quantus chain, on the oolon
# edge proxy (kosherinata), for the blackbeard wallet (blackbeard/wallet #53).
#
# Cert: Let's Encrypt via certbot + Cloudflare DNS-01 (architecture/external-tls.md).
# Installed by script/infra-setup.sh --role nodes, never by CI: the runner has
# no rights to read certificate keys or reload nginx on a shared edge proxy.
#
# ln -sf ../sites-available/quantus.blackbeard.observer.conf /etc/nginx/sites-enabled/
#
# listen 127.0.0.1:14443 + proxy_protocol, NOT 443: an nginx stream SNI router
# owns TCP 443 on this host and hands every non-passthrough name to the local
# https tier (architecture/reverse-proxies.md §5). Copy this listen line from a
# currently ENABLED vhost; several files in sites-available have drifted.
#
# The upstream and the rate-limit zones live in conf.d/blackbeard-nodes.conf so
# every chain's vhost is independent of the others.
#
# NOTE ON EXPOSURE: this is an unauthenticated RPC, on purpose (blackbeard/wallet
# #20). `--rpc-methods safe` on the node keeps the dangerous calls off it;
# anyone can read chain state and submit signed extrinsics, which is what a
# public node is for. Fair use is enforced here, per client address.
server {
listen 127.0.0.1:14443 ssl proxy_protocol;
http2 on;
server_name quantus.blackbeard.observer;
ssl_certificate /etc/letsencrypt/live/quantus.blackbeard.observer/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/quantus.blackbeard.observer/privkey.pem;
# A public endpoint for wallets on whatever TLS stack they ship with.
ssl_protocols TLSv1.2 TLSv1.3;
absolute_redirect off;
# Fair use (zones in conf.d/blackbeard-nodes.conf). 429 rather than the
# 503 default so a client can tell "slow down" from "node down".
limit_req zone=node_rpc burst=40 nodelay;
limit_conn node_conn 16;
limit_req_status 429;
limit_conn_status 429;
# Substrate subscriptions (new heads, transaction status) are long-lived
# and idle between blocks; on a quiet PoW chain that can be minutes. The
# 60s default would drop them mid-session as an unexplained disconnect.
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
# RPC bodies are small: a signed ML-DSA extrinsic is under 10 KiB. A
# larger limit only widens the DoS surface.
client_max_body_size 1m;
# No response caching or buffering: one endpoint, streaming answers.
proxy_buffering off;
location / {
proxy_pass http://quantus_node;
proxy_http_version 1.1;
# The WebSocket upgrade. Without these two lines the socket silently
# falls back to a plain request that hangs.
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
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;
}
add_header X-Content-Type-Options nosniff always;
add_header Referrer-Policy same-origin always;
}