From 517250b78f0ed0b8b4edf90064454877aedae276 Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 19 Oct 2023 20:03:46 +0200 Subject: [PATCH] fixed handling of x-forwarded-for header in multi-proxy environments --- faucet-config.example.yaml | 3 +++ src/config/ConfigSchema.ts | 1 + src/config/DefaultConfig.ts | 1 + src/webserv/FaucetHttpServer.ts | 8 +------- src/webserv/FaucetWebApi.ts | 9 ++++++--- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/faucet-config.example.yaml b/faucet-config.example.yaml index b8fc6c0f5..f95ed66f3 100644 --- a/faucet-config.example.yaml +++ b/faucet-config.example.yaml @@ -17,6 +17,9 @@ faucetPidFile: "faucet-pid.txt" # faucet http/ws server port serverPort: 8080 +# number of http proxies in front of this faucet +httpProxyCount: 0 + # title of the faucet faucetTitle: "Goerli PoW Faucet" diff --git a/src/config/ConfigSchema.ts b/src/config/ConfigSchema.ts index 4abda0a40..309043bf7 100644 --- a/src/config/ConfigSchema.ts +++ b/src/config/ConfigSchema.ts @@ -27,6 +27,7 @@ export interface IConfigSchema { faucetLogFile: string; // logfile for faucet events / null for no log faucetLogStatsInterval: number; // print faucet stats to log interval (10min default) serverPort: number; // listener port + httpProxyCount: number; // number of http proxies in front of this faucet faucetSecret: string; // random secret string that is used by the faucet to "sign" session data, so sessions can be restored automatically by clients when faucet is restarted / crashed ethRpcHost: string; // ETH execution layer RPC host diff --git a/src/config/DefaultConfig.ts b/src/config/DefaultConfig.ts index adf1c3db5..749b5175a 100644 --- a/src/config/DefaultConfig.ts +++ b/src/config/DefaultConfig.ts @@ -28,6 +28,7 @@ export function getDefaultConfig(): IConfigSchema { faucetLogFile: null, faucetLogStatsInterval: 600, serverPort: 8080, + httpProxyCount: 0, faucetSecret: null, // mandatory ethRpcHost: null, // mandatory diff --git a/src/webserv/FaucetHttpServer.ts b/src/webserv/FaucetHttpServer.ts index 435b7d63b..daf5c9bcc 100644 --- a/src/webserv/FaucetHttpServer.ts +++ b/src/webserv/FaucetHttpServer.ts @@ -157,13 +157,7 @@ export class FaucetHttpServer { } this.wssServer.handleUpgrade(req, socket, head, (ws) => { - let remoteAddr: string = null; - if(req.headers['x-forwarded-for']) { - let proxyChain = (req.headers['x-forwarded-for'] as string).split(", "); - remoteAddr = proxyChain.pop(); - } - if(!remoteAddr) - remoteAddr = req.socket.remoteAddress; + let remoteAddr = ServiceManager.GetService(FaucetWebApi).getRemoteAddr(req); wssEndpoint.handler(req, ws, remoteAddr); }); } diff --git a/src/webserv/FaucetWebApi.ts b/src/webserv/FaucetWebApi.ts index c0b50d049..8959885b0 100644 --- a/src/webserv/FaucetWebApi.ts +++ b/src/webserv/FaucetWebApi.ts @@ -125,11 +125,14 @@ export class FaucetWebApi { return urlRes; } - private getRemoteAddr(req: IncomingMessage): string { + public getRemoteAddr(req: IncomingMessage): string { let remoteAddr: string = null; - if(req.headers['x-forwarded-for']) { + if(faucetConfig.httpProxyCount > 0 && req.headers['x-forwarded-for']) { let proxyChain = (req.headers['x-forwarded-for'] as string).split(", "); - remoteAddr = proxyChain.pop(); + let clientIpIdx = proxyChain.length - faucetConfig.httpProxyCount; + if(clientIpIdx < 0) + clientIpIdx = 0; + remoteAddr = proxyChain[clientIpIdx]; } if(!remoteAddr) remoteAddr = req.socket.remoteAddress;