From 85270f497a0cba587f6c86c81926cdf0a7df27dc Mon Sep 17 00:00:00 2001 From: Owen Date: Sun, 26 Oct 2025 18:15:39 -0700 Subject: [PATCH] Restrict raw resources and use st from config --- install/config/traefik/dynamic_config.yml | 9 ++++++ server/lib/traefik/TraefikConfigManager.ts | 27 +++++++++++++---- server/lib/traefik/getTraefikConfig.ts | 30 +++++-------------- .../private/lib/traefik/getTraefikConfig.ts | 10 +++++-- server/private/routers/hybrid.ts | 3 +- .../routers/traefik/traefikConfigProvider.ts | 3 +- 6 files changed, 50 insertions(+), 32 deletions(-) diff --git a/install/config/traefik/dynamic_config.yml b/install/config/traefik/dynamic_config.yml index 8fcf8e55..f795016b 100644 --- a/install/config/traefik/dynamic_config.yml +++ b/install/config/traefik/dynamic_config.yml @@ -51,3 +51,12 @@ http: loadBalancer: servers: - url: "http://pangolin:3000" # API/WebSocket server + +tcp: + serversTransports: + pp-transport-v1: + proxyProtocol: + version: 1 + pp-transport-v2: + proxyProtocol: + version: 2 \ No newline at end of file diff --git a/server/lib/traefik/TraefikConfigManager.ts b/server/lib/traefik/TraefikConfigManager.ts index ec4e25f4..56648559 100644 --- a/server/lib/traefik/TraefikConfigManager.ts +++ b/server/lib/traefik/TraefikConfigManager.ts @@ -309,10 +309,7 @@ export class TraefikConfigManager { this.lastActiveDomains = new Set(domains); } - if ( - process.env.USE_PANGOLIN_DNS === "true" && - build != "oss" - ) { + if (process.env.USE_PANGOLIN_DNS === "true" && build != "oss") { // Scan current local certificate state this.lastLocalCertificateState = await this.scanLocalCertificateState(); @@ -450,7 +447,8 @@ export class TraefikConfigManager { currentExitNode, config.getRawConfig().traefik.site_types, build == "oss", // filter out the namespace domains in open source - build != "oss" // generate the login pages on the cloud and hybrid + build != "oss", // generate the login pages on the cloud and hybrid, + build == "saas" ? false : config.getRawConfig().traefik.allow_raw_resources // dont allow raw resources on saas otherwise use config ); const domains = new Set(); @@ -502,6 +500,25 @@ export class TraefikConfigManager { }; } + // tcp: + // serversTransports: + // pp-transport-v1: + // proxyProtocol: + // version: 1 + // pp-transport-v2: + // proxyProtocol: + // version: 2 + + if (build != "saas") { + // add the serversTransports section if not present + if (traefikConfig.tcp && !traefikConfig.tcp.serversTransports) { + traefikConfig.tcp.serversTransports = { + "pp-transport-v1": { proxyProtocol: { version: 1 } }, + "pp-transport-v2": { proxyProtocol: { version: 2 } } + }; + } + } + return { domains, traefikConfig }; } catch (error) { // pull data out of the axios error to log diff --git a/server/lib/traefik/getTraefikConfig.ts b/server/lib/traefik/getTraefikConfig.ts index f7f56a9a..39a12156 100644 --- a/server/lib/traefik/getTraefikConfig.ts +++ b/server/lib/traefik/getTraefikConfig.ts @@ -23,7 +23,8 @@ export async function getTraefikConfig( exitNodeId: number, siteTypes: string[], filterOutNamespaceDomains = false, - generateLoginPageRouters = false + generateLoginPageRouters = false, + allowRawResources = true ): Promise { // Define extended target type with site information type TargetWithSite = Target & { @@ -103,7 +104,7 @@ export async function getTraefikConfig( isNull(targetHealthCheck.hcHealth) // Include targets with no health check record ), inArray(sites.type, siteTypes), - config.getRawConfig().traefik.allow_raw_resources + allowRawResources ? isNotNull(resources.http) // ignore the http check if allow_raw_resources is true : eq(resources.http, true) ) @@ -566,8 +567,6 @@ export async function getTraefikConfig( ...(protocol === "tcp" ? { rule: "HostSNI(`*`)" } : {}) }; - const serversTransportName = `${key}-proxy-protocol-transport`; - config_output[protocol].services[serviceName] = { loadBalancer: { servers: (() => { @@ -621,8 +620,10 @@ export async function getTraefikConfig( } }); })(), - ...(resource.proxyProtocol - ? { serversTransport: serversTransportName } + ...(resource.proxyProtocol && protocol == "tcp" + ? { + serversTransport: `pp-transport-v${resource.proxyProtocolVersion || 1}` + } : {}), ...(resource.stickySession ? { @@ -636,23 +637,6 @@ export async function getTraefikConfig( : {}) } }; - - // Add serversTransport configuration if proxy protocol is enabled - if (resource.proxyProtocol) { - if (!config_output[protocol].serversTransports) { - config_output[protocol].serversTransports = {}; - } - - config_output[protocol].serversTransports[serversTransportName] = { - proxyProtocol: { - version: resource.proxyProtocolVersion || 1 - } - }; - - logger.debug( - `Enabled Proxy Protocol v${resource.proxyProtocolVersion || 1} for ${protocol} resource ${resource.resourceId} (${resource.name})` - ); - } } } return config_output; diff --git a/server/private/lib/traefik/getTraefikConfig.ts b/server/private/lib/traefik/getTraefikConfig.ts index 881e4632..27a980dd 100644 --- a/server/private/lib/traefik/getTraefikConfig.ts +++ b/server/private/lib/traefik/getTraefikConfig.ts @@ -50,7 +50,8 @@ export async function getTraefikConfig( exitNodeId: number, siteTypes: string[], filterOutNamespaceDomains = false, - generateLoginPageRouters = false + generateLoginPageRouters = false, + allowRawResources = true ): Promise { // Define extended target type with site information type TargetWithSite = Target & { @@ -135,7 +136,7 @@ export async function getTraefikConfig( isNull(targetHealthCheck.hcHealth) // Include targets with no health check record ), inArray(sites.type, siteTypes), - config.getRawConfig().traefik.allow_raw_resources + allowRawResources ? isNotNull(resources.http) // ignore the http check if allow_raw_resources is true : eq(resources.http, true) ) @@ -688,6 +689,11 @@ export async function getTraefikConfig( } }); })(), + ...(resource.proxyProtocol && protocol == "tcp" // proxy protocol only works for tcp + ? { + serversTransport: `pp-transport-v${resource.proxyProtocolVersion || 1}` + } + : {}), ...(resource.stickySession ? { sticky: { diff --git a/server/private/routers/hybrid.ts b/server/private/routers/hybrid.ts index df99df92..abfbd02f 100644 --- a/server/private/routers/hybrid.ts +++ b/server/private/routers/hybrid.ts @@ -270,7 +270,8 @@ hybridRouter.get( remoteExitNode.exitNodeId, ["newt", "local", "wireguard"], // Allow them to use all the site types true, // But don't allow domain namespace resources - false // Dont include login pages + false, // Dont include login pages, + true // allow raw resources ); return response(res, { diff --git a/server/routers/traefik/traefikConfigProvider.ts b/server/routers/traefik/traefikConfigProvider.ts index 6c9404e9..9b12ed8a 100644 --- a/server/routers/traefik/traefikConfigProvider.ts +++ b/server/routers/traefik/traefikConfigProvider.ts @@ -21,7 +21,8 @@ export async function traefikConfigProvider( currentExitNodeId, config.getRawConfig().traefik.site_types, build == "oss", // filter out the namespace domains in open source - build != "oss" // generate the login pages on the cloud and hybrid + build != "oss", // generate the login pages on the cloud and and enterprise, + config.getRawConfig().traefik.allow_raw_resources ); if (traefikConfig?.http?.middlewares) {