OverviewFilesCommitsIssuesDocsReleasesPeers

P2P-Hiverelay / deploy / public-hive-gateway / nginx.conf.template

91 lines · template ref:
# Public HTTPS Hive app edge. Render with `npm run gateway:preflight --`
# plus `--nginx-template ... --nginx-output ...`, then install the result at
# `/etc/nginx/conf.d/hiverelay-public-apps.conf` as documented in the runbook.
#
# Include the limit zones once in nginx's `http {}` context. Phase 1 disables
# per-request app logging; bounded aggregate metrics and signed probes are the
# public-edge observability surface.
limit_req_zone $binary_remote_addr zone=hive_app_rate:10m rate=20r/s;
limit_conn_zone $binary_remote_addr zone=hive_app_conn:10m;

# This must be the TLS default for the public app listener. It prevents an
# unknown/malformed SNI value from falling through to an API or other vhost.
server {
  listen 443 ssl default_server;
  listen [::]:443 ssl default_server;
  server_name _;

  ssl_certificate __HIVE_TLS_CERTIFICATE__;
  ssl_certificate_key __HIVE_TLS_CERTIFICATE_KEY__;
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_session_tickets off;

  gzip off;
  gunzip off;
  access_log off;
  error_log stderr crit;
  return 421;
}

server {
  listen 443 ssl;
  listen [::]:443 ssl;

  # One canonical z-base-32 app-key label. No base host, extra labels, or
  # unrelated virtual hosts can fall through to the compatibility gateway.
  server_name "~^(?<hive_app_key>[ybndrfg8ejkmcpqxot1uwisza345h769]{52})\.__HIVE_APP_HOST_SUFFIX_REGEX__$";

  ssl_certificate __HIVE_TLS_CERTIFICATE__;
  ssl_certificate_key __HIVE_TLS_CERTIFICATE_KEY__;
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_session_tickets off;

  access_log off;
  error_log stderr crit;
  server_tokens off;

  # The first canary is an exact-byte, no-shared-cache transport. Compression,
  # cookie injection, request bodies, and automatic upstream failover are off.
  gzip off;
  gunzip off;
  proxy_cache off;
  proxy_hide_header Set-Cookie;
  client_max_body_size 1k;
  limit_req zone=hive_app_rate burst=40 nodelay;
  limit_conn hive_app_conn 16;
  limit_req_status 429;
  limit_conn_status 429;

  if ($ssl_server_name != $host) { return 421; }

  location / {
    limit_except GET { deny all; }

    proxy_pass http://127.0.0.1:__HIVE_GATEWAY_PORT__;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_set_header Accept-Encoding "";
    proxy_set_header Host $host;

    # Treat forwarding headers from the public request as hostile input. The
    # edge overwrites client IP and attests the SNI it actually terminated.
    proxy_set_header Forwarded "";
    proxy_set_header X-Forwarded-Host "";
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Hive-Forwarded-SNI $ssl_server_name;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";

    proxy_connect_timeout 3s;
    proxy_send_timeout 65s;
    proxy_read_timeout 65s;
    proxy_next_upstream off;
    proxy_buffering off;
    proxy_request_buffering off;
  }

  add_header Strict-Transport-Security "max-age=31536000" always;
}