Repository navigation
Expand file tree
/
Copy pathsysnode.conf.example
More file actions
135 lines (127 loc) · 7.26 KB
/
Copy pathsysnode.conf.example
File metadata and controls
135 lines (127 loc) · 7.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# Reverse-proxy vhost for a same-origin sysnode deployment.
#
# Replace `sysnode.example.com` with your real public hostname before use.
# This is a reference, not a drop-in: anything in `# managed by Certbot`
# blocks below is left for `certbot --nginx` to write on first run, so
# you typically install this skeleton, then run:
#
# sudo certbot --nginx -d sysnode.example.com
#
# and Certbot rewrites the `listen 443 ssl` block plus the HTTP→HTTPS
# redirect with the real cert paths.
#
# Layout matches the same-origin model documented in the project README:
#
# https://sysnode.example.com/ -> sysnode-info build (port 3000)
# https://sysnode.example.com/auth/* -> sysnode-backend (port 3001)
# https://sysnode.example.com/vault -> sysnode-backend (port 3001)
# https://sysnode.example.com/gov/* -> sysnode-backend (port 3001)
# https://sysnode.example.com/api/sentry/v1/* -> backend (port 3001)
# https://sysnode.example.com/mnstats -> sysnode-backend (port 3001)
# https://sysnode.example.com/mncount -> sysnode-backend (port 3001)
# https://sysnode.example.com/mnlist -> sysnode-backend (port 3001)
# https://sysnode.example.com/mnsearch -> sysnode-backend (port 3001)
# https://sysnode.example.com/govlist -> sysnode-backend (port 3001)
#
# Public anonymous routes (/mnstats, /mncount, /mnlist, /mnsearch,
# /govlist) are matched with a case-insensitive regex so the SPA's
# catch-all `location /` falls through to the React static build for
# everything else, while legacy camelCase callers (browser bookmarks,
# external integrations that predate the lowercase canonical such as
# the historical `https://syscoin.dev/mnstats` URL still referenced
# by older syshub builds) keep working through the same-origin proxy.
#
# Heads up — paths like `/governance`, `/masternodes`, `/login`, `/vault`-
# beyond-the-bare-segment are *client-side React routes* served by the
# SPA. Don't add nginx `location /governance` / `location /masternodes`
# blocks: the backend doesn't expose those paths (its public routes
# are `/govlist`, `/mnsearch`, `/mnlist`, `/mnstats`, `/mncount`), and
# proxying them to :3001 would 404 the SPA pages users navigate to.
#
# Do NOT add `add_header Strict-Transport-Security ...` here. Both apps
# emit HSTS in code (helmet on the backend, the security-header map in
# sysnode-info/server.js on the frontend); duplicating it at the edge
# produces two `Strict-Transport-Security` response headers, which is
# noisy in audits even though browsers only honour the first per
# RFC 6797 §8.1. The same applies to certbot's default
# /etc/letsencrypt/options-ssl-nginx.conf — comment its HSTS line out
# if it's set, or override it here.
server {
server_name sysnode.example.com;
# Vault PUTs are small (encrypted JSON blob), but leave room for
# the encoded ciphertext + base64 overhead.
client_max_body_size 5M;
# ---- backend (sysnode-backend on :3001) -------------------------------
# The backend mounts /auth, /vault, /gov, /api/sentry/v1 at the path root, so we proxy
# without rewriting. Trailing-slash matching (`location /auth/`) means
# only paths *under* /auth/ are proxied (e.g. /auth/me, /auth/login);
# something else at /authentication would NOT match and would fall
# through to the SPA. /vault is matched as an exact location because
# the SPA hits exactly `/vault` (GET / PUT of the encrypted blob);
# listing it as a prefix would also catch client-side routes like
# `/vault/import` that need to fall through to the SPA.
location /auth/ { proxy_pass http://127.0.0.1:3001; include /etc/nginx/snippets/sysnode-proxy.conf; }
location = /vault { proxy_pass http://127.0.0.1:3001; include /etc/nginx/snippets/sysnode-proxy.conf; }
location /gov/ { proxy_pass http://127.0.0.1:3001; include /etc/nginx/snippets/sysnode-proxy.conf; }
location /recovery/ { proxy_pass http://127.0.0.1:3001; include /etc/nginx/snippets/sysnode-proxy.conf; }
location /api/recovery/ { proxy_pass http://127.0.0.1:3001; include /etc/nginx/snippets/sysnode-proxy.conf; }
location /api/sentry/v1/ { proxy_pass http://127.0.0.1:3001; include /etc/nginx/snippets/sysnode-proxy.conf; }
# Anonymous pool-wide snapshots. Preserve the path and avoid access logs
# linking a requesting IP to a pool. No note/leaf parameters are supported.
location /api/privacy/v1/ {
access_log off;
proxy_pass http://127.0.0.1:3001;
include /etc/nginx/snippets/sysnode-proxy.conf;
}
# Public anonymous data routes. Canonical casing is lowercase
# (matches the historical `https://syscoin.dev/mnstats` URL still
# used by older syshub builds and the existing `/govlist`).
# `~*` is a case-INsensitive regex match so legacy callers using
# camelCase URLs (`/mnStats`, `/mnList`, …) keep working through
# the same-origin proxy — this mirrors Express's own default
# case-insensitive route matching at the route layer. The anchored
# `^/...$` keeps `/mnstatsfoo` etc. from being proxied so they fall
# through to the SPA's catch-all `location /` below. If you add a
# new public backend route, extend this alternation.
location ~* ^/(mnstats|mncount|mnlist|mnsearch|govlist)$ {
proxy_pass http://127.0.0.1:3001;
include /etc/nginx/snippets/sysnode-proxy.conf;
}
# ---- frontend (sysnode-info on :3000) ---------------------------------
# Catch-all for the SPA. server.js falls back to index.html for any
# path it doesn't have a static asset for, so client-side routing
# (e.g. /login, /vault, /governance/proposal/<hash>) works.
location / {
proxy_pass http://127.0.0.1:3000;
include /etc/nginx/snippets/sysnode-proxy.conf;
}
# listen 443 ssl; # managed by Certbot
# ssl_certificate /etc/letsencrypt/live/.../fullchain.pem; # managed by Certbot
# ssl_certificate_key /etc/letsencrypt/live/.../privkey.pem; # managed by Certbot
# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
# HTTP→HTTPS redirect. Certbot generates an equivalent block; this is
# here so the file is self-contained when read for review.
server {
listen 80;
listen [::]:80;
server_name sysnode.example.com;
return 301 https://$host$request_uri;
}
# ---------------------------------------------------------------------------
# Companion file: /etc/nginx/snippets/sysnode-proxy.conf
# ---------------------------------------------------------------------------
# Create the snippet referenced above so we don't repeat headers across
# every location. `proxy_set_header Host $host` and X-Forwarded-Proto
# are required for the backend's `TRUST_PROXY=1` config to recover the
# real client IP and the original https:// scheme — without them, the
# production startup assertion on `req.secure` will fail.
#
# proxy_http_version 1.1;
# 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;
# proxy_read_timeout 60s;
# proxy_send_timeout 60s;