Skip to content

Commit 77498df

Browse files
committed
fix: add TRUST_PROXY config to support deployments behind reverse proxies
Deployments behind nginx, Cloudflare, or both were logging a startup ValidationError from express-rate-limit because Express's trust proxy setting was not configured, preventing real client IPs from being resolved from X-Forwarded-For headers. Adds TRUST_PROXY to the APP config section (default: 0 = no proxy). Set to 1 for a single proxy hop (nginx or Cloudflare), or 2 for two hops (Cloudflare + nginx, typical k8s ingress). Updates README with documentation for the new setting.
1 parent ce82ed0 commit 77498df

3 files changed

Lines changed: 23 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ In the `CHIA_ROOT` directory (usually `~/.chia/mainnet` on Linux), CADT will add
256256
* **APP**: This section contains shared configuration used by both V1 and V2 APIs.
257257
* **CW_PORT**: CADT port where the API will be available. 31310 by default.
258258
* **BIND_ADDRESS**: By default, CADT listens on localhost only. To enable remote connections to CADT, change this to `0.0.0.0` to listen on all network interfaces, or to an IP address to listen on a specific network interface.
259+
* **TRUST_PROXY**: Number of reverse-proxy hops between the internet and CADT. Used to correctly identify real client IP addresses for rate limiting and logging when CADT is deployed behind one or more proxies. Set to `0` (the default) when CADT is accessed directly with no proxy in front of it. Set to `1` when behind a single proxy such as nginx or Cloudflare. Set to `2` when behind two proxies such as Cloudflare in front of nginx (a common cloud/k8s deployment). Never set to `true`; that would trust the user-supplied IP in the `X-Forwarded-For` header and defeat rate limiting.
259260
* **DATALAYER_URL**: URL and port to connect to the [Chia DataLayer RPC](https://docs.chia.net/datalayer-rpc). If Chia is installed locally with default settings, https://localhost:8562 will work.
260261
* **WALLET_URL**: URL and port to connect to the [Chia Wallet RPC](https://docs.chia.net/wallet-rpc). If Chia is installed on the same machine as CADT with default settings, https://localhost:9256 will work.
261262
* **USE_SIMULATOR**: Developer setting to populate CADT from a governance file and enable some extra APIs. Should always be "false" under normal usage.

src/middleware.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ const isReadOnlyMethodBlocked = (method) => !['GET', 'HEAD', 'OPTIONS'].includes
4747

4848
const app = express();
4949

50+
// Configure proxy trust so Express resolves real client IPs from
51+
// X-Forwarded-For headers. TRUST_PROXY counts reverse-proxy hops:
52+
// 0 – no proxy (default, direct access)
53+
// 1 – one hop (nginx OR Cloudflare-only)
54+
// 2 – two hops (Cloudflare → nginx, typical k8s ingress setup)
55+
// This also silences the express-rate-limit ValidationError that fires
56+
// when X-Forwarded-For is present but trust proxy is disabled.
57+
// Never use `true`; it trusts the user-supplied leftmost IP.
58+
const trustProxy = getConfig().APP.TRUST_PROXY ?? 0;
59+
app.set('trust proxy', trustProxy);
60+
5061
app.use(
5162
cors({
5263
exposedHeaders: Object.values(headerKeys).join(','),

src/utils/defaultConfig.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@ export const defaultConfig = {
22
APP: {
33
CW_PORT: 31310,
44
BIND_ADDRESS: 'localhost',
5+
/**
6+
* Number of reverse-proxy hops between the internet and CADT.
7+
* Passed directly to Express `trust proxy`.
8+
* 0 – no proxy (default, direct access)
9+
* 1 – one hop (nginx OR Cloudflare-only)
10+
* 2 – two hops (Cloudflare → nginx, typical k8s ingress setup)
11+
* Setting this correctly lets express-rate-limit see the real client IP
12+
* instead of the proxy IP. Never set to `true`; that trusts the
13+
* user-supplied leftmost IP and defeats rate limiting.
14+
*/
15+
TRUST_PROXY: 0,
516
DATALAYER_URL: 'https://localhost:8562',
617
WALLET_URL: 'https://localhost:9256',
718
USE_SIMULATOR: false,

0 commit comments

Comments
 (0)