diff --git a/packages/pockethost/src/cli/commands/FirewallCommand/ServeCommand/firewall/rate-limiter.ts b/packages/pockethost/src/cli/commands/FirewallCommand/ServeCommand/firewall/rate-limiter.ts index b23ddb70..a2670934 100644 --- a/packages/pockethost/src/cli/commands/FirewallCommand/ServeCommand/firewall/rate-limiter.ts +++ b/packages/pockethost/src/cli/commands/FirewallCommand/ServeCommand/firewall/rate-limiter.ts @@ -23,12 +23,19 @@ const getConnectingIp = (req: express.Request): string | undefined => { } // Middleware factory to create a rate limiting middleware -export const createRateLimiterMiddleware = (logger: Logger, userProxyIps: string[] = []) => { +export const createRateLimiterMiddleware = ( + logger: Logger, + userProxyIps: string[] = [], + userProxyWhitelistIps: string[] = [] +) => { const { dbg, warn } = logger.create(`RateLimiter`) dbg(`Creating`) if (userProxyIps.length > 0) { dbg(`User proxy IPs: ${userProxyIps.join(', ')}`) } + if (userProxyWhitelistIps.length > 0) { + dbg(`User proxy whitelist IPs (bypass rate limiting): ${userProxyWhitelistIps.join(', ')}`) + } const isUserProxy = (connectingIp: string | undefined): boolean => { if (!connectingIp) return false @@ -69,6 +76,14 @@ export const createRateLimiterMiddleware = (logger: Logger, userProxyIps: string }) return async (req: express.Request, res: express.Response, next: express.NextFunction) => { + const connectingIp = getConnectingIp(req) + + // Check if connecting IP is whitelisted - bypass all rate limiting + if (connectingIp && userProxyWhitelistIps.includes(connectingIp)) { + dbg(`Whitelisted user proxy IP detected: ${connectingIp} - bypassing rate limiting`) + return next() + } + const ip = getClientIp(req) if (isUserProxy(ip)) { dbg(`User Proxy IP detected: ${ip}`, req.headers) diff --git a/packages/pockethost/src/cli/commands/FirewallCommand/ServeCommand/firewall/server.ts b/packages/pockethost/src/cli/commands/FirewallCommand/ServeCommand/firewall/server.ts index 6edc81c5..ab37282d 100644 --- a/packages/pockethost/src/cli/commands/FirewallCommand/ServeCommand/firewall/server.ts +++ b/packages/pockethost/src/cli/commands/FirewallCommand/ServeCommand/firewall/server.ts @@ -7,6 +7,7 @@ import { MOTHERSHIP_NAME, MOTHERSHIP_PORT, PH_USER_PROXY_IPS, + PH_USER_PROXY_WHITELIST_IPS, SSL_CERT, SSL_KEY, } from '@' @@ -84,7 +85,7 @@ export const firewall = async ({ logger }: FirewallOptions) => { // Use the IP blocker middleware app.use(createIpWhitelistMiddleware(IPCIDR_LIST())) - app.use(createRateLimiterMiddleware(logger, PH_USER_PROXY_IPS())) + app.use(createRateLimiterMiddleware(logger, PH_USER_PROXY_IPS(), PH_USER_PROXY_WHITELIST_IPS())) forEach(hostnameRoutes, (target, host) => { app.use(createVhostProxyMiddleware(host, target, IS_DEV(), logger)) diff --git a/packages/pockethost/src/constants.ts b/packages/pockethost/src/constants.ts index 43621ddb..06f37f35 100644 --- a/packages/pockethost/src/constants.ts +++ b/packages/pockethost/src/constants.ts @@ -65,6 +65,7 @@ export const createSettings = () => ({ IPCIDR_LIST: mkCsvString([]), PH_USER_PROXY_IPS: mkCsvString([]), + PH_USER_PROXY_WHITELIST_IPS: mkCsvString([]), DAEMON_PORT: mkNumber(3000), DAEMON_PB_IDLE_TTL: mkNumber(1000 * 5), // 5 seconds PH_CONTAINER_LAUNCH_WARN_MS: mkNumber(200), @@ -166,6 +167,7 @@ export const APEX_DOMAIN = () => settings().APEX_DOMAIN export const IPCIDR_LIST = () => settings().IPCIDR_LIST export const PH_USER_PROXY_IPS = () => settings().PH_USER_PROXY_IPS +export const PH_USER_PROXY_WHITELIST_IPS = () => settings().PH_USER_PROXY_WHITELIST_IPS export const DAEMON_PORT = () => settings().DAEMON_PORT export const DAEMON_PB_IDLE_TTL = () => settings().DAEMON_PB_IDLE_TTL export const PH_CONTAINER_LAUNCH_WARN_MS = () => settings().PH_CONTAINER_LAUNCH_WARN_MS @@ -271,6 +273,7 @@ export const logConstants = () => { APEX_DOMAIN, IPCIDR_LIST, PH_USER_PROXY_IPS, + PH_USER_PROXY_WHITELIST_IPS, DAEMON_PORT, DAEMON_PB_IDLE_TTL, PH_CONTAINER_LAUNCH_WARN_MS,