2.8 KiB
Bitcoin Pulse public ingress
Bitcoin Pulse uses the dedicated API hostname
bitcoin-pulse.tobiasostner.de. The native iOS client calls this hostname
without a path prefix. A same-origin path proxy is unnecessary because there is
no browser frontend, and no CORS headers are configured because native iOS
requests are not subject to browser CORS enforcement.
DNS and TLS
The bitcoin-pulse A record under tobiasostner.de points to Tobserver's public
IPv4 address, 162.55.103.218. There is no AAAA record until Tobserver has
working public IPv6 connectivity.
The NixOS nginx virtual host obtains and renews its certificate through the
existing ACME configuration and redirects plaintext HTTP to HTTPS. Only ports
80 and 443 are public ingress for the API. The application listens on
127.0.0.1:3000; port 3000 is not opened by the host firewall, so nginx is the
only public path to the backend.
Proxy policy
nginx preserves the original request path and forwards it to
http://127.0.0.1:3000. It supplies Host, X-Real-IP, X-Forwarded-For, and
X-Forwarded-Proto, and uses short local-upstream timeouts: two seconds to
connect and ten seconds to read or send.
Requests are limited per source IP to an average of 300 requests per minute, with a burst of 50 requests, and rejected with HTTP 429 when the burst is exhausted. This allows normal polling and multiple devices behind a shared NAT while bounding abusive traffic. Request bodies are limited to 16 KiB; the current public API consists only of small GET requests.
Deployment verification
After a human reviews and merges the change, deploy the resulting NixOS generation and verify locally on Tobserver:
systemctl is-active nginx.service bitcoin-pulse.service
ss -ltn '( sport = :3000 )'
curl --fail --show-error --silent http://127.0.0.1:3000/health \
| jq -e '.status == "OK"'
The socket listing must show only 127.0.0.1:3000, not 0.0.0.0:3000 or the
public address. From a machine outside Tobserver, verify DNS, HTTPS, the health
endpoint, and each functional endpoint:
dig +short A bitcoin-pulse.tobiasostner.de
curl --fail --show-error --silent \
https://bitcoin-pulse.tobiasostner.de/health \
| jq -e '.status == "OK"'
curl --fail --show-error --silent \
https://bitcoin-pulse.tobiasostner.de/block-height | jq -e .
curl --fail --show-error --silent \
https://bitcoin-pulse.tobiasostner.de/difficulty-adjustment | jq -e .
curl --fail --show-error --silent \
https://bitcoin-pulse.tobiasostner.de/price | jq -e .
The A lookup must return 162.55.103.218. The HTTPS certificate must be valid
for bitcoin-pulse.tobiasostner.de; /health must return HTTP 200 and
{"status":"OK"}. The functional endpoints must return HTTP 200 and JSON after
the collectors have populated their data. A connection from outside Tobserver
to TCP port 3000 must fail.