diff --git a/.env.example b/.env.example index 0d0a44b41f0..f3deef299a2 100644 --- a/.env.example +++ b/.env.example @@ -5,6 +5,9 @@ PROTO='http' SERVER_SECRET='key_SERVER_SECRET' # Cluster node number 0 - 1023. Must be unique per process. SERVER_ID='1' +# Used to read the client IP from the X-Forwarded-For header, if not set, it will use the first IP in the list. +# If configured, it must match the number of proxies in the stack, otherwise it might rate limit all traffic coming from the proxy. +# TRUSTED_PROXY_COUNT='1' # Websocket port for the websocket server, only used in development (yarn dev) SOCKET_PORT='3001' diff --git a/packages/server/utils/uwsGetIP.ts b/packages/server/utils/uwsGetIP.ts index 034b266a3c9..b41765b100d 100644 --- a/packages/server/utils/uwsGetIP.ts +++ b/packages/server/utils/uwsGetIP.ts @@ -1,7 +1,11 @@ import {HttpRequest, HttpResponse} from 'uWebSockets.js' +const TRUSTED_PROXY_COUNT = Number(process.env.TRUSTED_PROXY_COUNT) +// if TRUSTED_PROXY_COUNT is not configured correctly we fall back to reading the first IP to avoid rate limiting our proxy +const CLIENT_IP_POS = isNaN(TRUSTED_PROXY_COUNT) ? 0 : -1 - TRUSTED_PROXY_COUNT + const uwsGetIP = (res: HttpResponse, req: HttpRequest) => { - const clientIp = req.getHeader('x-forwarded-for')?.split(',')[0] + const clientIp = req.getHeader('x-forwarded-for')?.split(',').at(CLIENT_IP_POS) if (clientIp) return clientIp // returns ipv6 e.g. '0000:0000:0000:0000:0000:ffff:ac11:0001' return Buffer.from(res.getRemoteAddressAsText()).toString()