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
72 lines
3.1 KiB
Plaintext
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;
|
|
}
|