Hi All,
I've encountered an issue with Traefik where it does not properly capture and route requests that have mismatched protocols and ports. This problem arises when using combinations like HTTP on port 443 or HTTPS on port 80. Despite having rules configured to capture these scenarios, Traefik fails to handle them correctly, resulting in 404 errors.
Issue Overview
When sending requests with mismatched protocol and port combinations, Traefik does not route them as expected. Examples of such requests include:
- HTTP requests sent to port 443 (http:// <load_balancer_ip> :443/) or
- HTTP requests sent to port 443 (http:// example .com:443/) and
- HTTPS requests sent to port 80 (https://<load_balancer_ip>:80/) or
- HTTPS requests sent to port 80 (https:// example .com:80/)
These requests result in:
- 404 Not Found errors for HTTPS requests sent to port 80 and
- 404 Not Found errors for HTTP requests sent to port 443
The primary concern is ensuring correct routing and being able to catch and blackhole these requests.
Current Configuration
Here are the highest priority rules to prevent IP v4/v6 requests (I’ve retained document hierarchy elements for ease of readability of config, these all fall under a single config file):
http: routers: # Blackhole direct IP v4/v6 address requests for HTTP web-block-ip-router: rule: "HostRegexp(`^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(:[0-9]+)?$|^\\[[0-9a-fA-F:]+\\](:[0-9]+)?$|^[0-9a-fA-F:]+(:[0-9]+)?$`)" entryPoints: ["web"] service: blackhole-service priority: 99999 # Blackhole direct IP v4/v6 address requests for HTTPS websecure-block-ip-router: rule: "HostRegexp(`^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(:[0-9]+)?$|^\\[[0-9a-fA-F:]+\\](:[0-9]+)?$|^[0-9a-fA-F:]+(:[0-9]+)?$`)" entryPoints: ["websecure"] service: blackhole-service tls: {} priority: 99999 services: blackhole-service: loadBalancer: servers: - url: "http:// 10.255.255.1 " # Non-routable IP
Followed by any requests that are not captured by the higher priority rules first:
http: routers: # Default path rule for HTTP web-block-default: rule: "PathPrefix(`/`)" entryPoints: ["web"] service: blackhole-service priority: 1 # Default path rule for HTTPS websecure-block-default: rule: "PathPrefix(`/`)" entryPoints: ["websecure"] service: blackhole-service tls: {} priority: 1 # Catch-all rule for HTTP web-catch-all: rule: "HostRegexp(`.*`)" entryPoints: ["web"] service: blackhole-service priority: 0 # Catch-all rule for HTTPS websecure-catch-all: rule: "HostRegexp(`.*`)" entryPoints: ["websecure"] service: blackhole-service tls: {} priority: 0 services: blackhole-service: loadBalancer: servers: - url: "http:// 10.255.255.1 " # Non-routable IP
Symptoms
In my setup, the following requests result in unexpected 404 errors:
- curl -v -k "https://<load_balancer_ip>:80" # Handled by web entrypoint
- curl -v "http://<load_balancer_ip>:443" # Handled by websecure entrypoint
The Traefik logs show the following entries:
- For https://<load_balancer_ip>:80 /:
2024-06-15T08:43:06+10:00 DBG github. com/traefik/traefik/v3/pkg/tls/tlsmanager.go:228 > Serving default certificate for request: ""
{"ClientAddr":"<private_ip>:53488","ClientHost":"<private_ip>","ClientPort":"53488","DownstreamStatus":404,"Duration":202631,"OriginStatus":0,"RequestAddr":"<load_balancer_ip>:80","RequestCount":6,"RequestHost":"<load_balancer_ip>","RequestMethod":"GET","RequestPath":"/","RequestPort":"80","RequestProtocol":"HTTP/1.1","RequestScheme":"https","RetryAttempts":0,"StartLocal":"2024-06-15T08:43:06.962840543+10:00","entryPointName":"web","level":"info","msg":"","request_User-Agent":"curl/7.68.0"}
- Summary: Enters via the web entrypoint, loads certificate and does not measure against the load balancer weighted round robin
- For http://<load_balancer_ip>:443 /:
{"ClientAddr":"<private_ip>:53454","ClientHost":"<private_ip>","ClientPort":"53454","DownstreamStatus":404,"Duration":119671,"OriginStatus":0,"RequestAddr":"<load_balancer_ip>:443","RequestCount":13,"RequestHost":"<load_balancer_ip>","RequestMethod":"GET","RequestPath":"/","RequestPort":"443","RequestProtocol":"HTTP/1.1","RequestScheme":"http","RetryAttempts":0,"StartLocal":"2024-06-15T08:58:37.535011194+10:00","entryPointName":"websecure","level":"info","msg":"","request_User-Agent":"curl/7.68.0"}
- Summary: Enters via the websecure entrypoint, does not load certificate and does not measure against the load balancer weighted round robin
Note: I wonder if the WeightedRoundRobin load balancer handles mismatches - I do not understand Golang, so I cannot read through the codebase to analyze and determine if there is a possible non-condition which could be the issue.
I've attempted various configurations, including higher-priority rules to handle mismatched scenarios, but they do not seem to resolve the issue. Here is an example attempt:
http: routers: # Blackhole mismatched entry and request web-portweb-webentry-mismatch: entryPoints: ["web"] rule: "HostRegexp(`^(http:\\/\\/|https:\\/\\/)?[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(:80|:443)?$|^(http:\\/\\/|https:\\/\\/)?\\[[0-9a-fA-F:]+\\](:80|:443)?$|^(http:\\/\\/|https:\\/\\/)?[0-9a-fA-F:]+(:80|:443)?$`)" service: blackhole-service priority: 99998 # Blackhole mismatched entry and request web-portweb-websecureentry-mismatch: entryPoints: ["websecure"] rule: "HostRegexp(`^(http:\\/\\/|https:\\/\\/)?[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(:80|:443)?$|^(http:\\/\\/|https:\\/\\/)?\\[[0-9a-fA-F:]+\\](:80|:443)?$|^(http:\\/\\/|https:\\/\\/)?[0-9a-fA-F:]+(:80|:443)?$`)" service: blackhole-service tls: {} priority: 99998 services: blackhole-service: loadBalancer: servers: - url: "http:// 10.255.255.1 " # Non-routable IP
Regex Testing
Find the above pattern testing verifying these requests should be matching for both IP v4/v6.
Conclusion
It appears that Traefik has a fundamental issue with capturing and routing requests that have mismatched protocols and ports correctly based on my testing as per the provided configurations in other variations also in attempts to capture these mismatch requests. If there is no known solution or a correct way to set this up, I'll raise this as an issue on GitHub.
Questions
- Has anyone successfully managed to route mismatched protocol and port requests in Traefik?
- Are there any additional configurations or middleware that could handle this scenario better?
Any insights or suggestions would be greatly appreciated!
Thanks,
Eldin