Can't set catchall rule for unencrypted traffic to port 443

I have Traefik set up running in Docker with 2 endpoints: 80 which redirects to 443 and 443 which is encrypted. I also have a catchall rule to not respond to any connections that aren't specifically made to one of the configured hostname (done via docker labels).

That all works. Connections to my hostnames go to my services and connections to http:/ipaddress and https://ipaddress redirect to my catchall "unavailable" service.

The problem I'm running into is if someone connects to http:/ipaddress:443, it returns a 404. Basically the catchall rule never triggers. I'm guessing this is because the endpoint for port 443 is set up for encrypted traffic.

As far as I can tell there is no way to set up separate routers rules for unencrypted connections to port 443 and encrypted connections to port 443 as only one port 443 entry point can be defined.

I've tried removing the specified endpoint from the dynamic router rule but that doesn't do anything.

How can I get connections to http:/ipaddress:443 to go to the "unavailable" service.

traefik.yml

entryPoints:
  http:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: https
          scheme: https
  https:
    address: ":443"
    http:
      tls:
        certresolver: "cloudflare"
        domains:
          main: "mydomain.com"
          sans: "*.mydomain.com"

dynamic.yml

http:
  routers:
    catchall:
      entryPoints:
        - "https"
      tls: {}
      # catchall rule
      rule: "PathPrefix(`/`)"
      service: unavailable
      # lowest possible priority
      # evaluated when no other router is matched
      priority: 1

  services:
    unavailable:
      loadBalancer:
        servers:
          # unused private ip address to force a 504
          - url: "https://10.10.10.10:111/"

If you really want to support http on port 443, you can just move TLS to the router, not declare it on the entrypoint.

That way you can have one router without TLS on port 443. But you will have to add TLS to every other router. Not sure if it is worth the effort.

I want to redirect http to https, but not allow unencrypted over port 443. What I found that worked was creating a tcp router that just blackholes any unencrypted traffic. I'm not sure how I'm getting unencrypted traffic, but this works.

tcp:
  routers:
    catchall_unencrypted:
      rule: "HostSNI(`*`)"
      service: unavailable
      # lowest possible priority
      # evaluated when no other router is matched
      priority: 1
  services:
    unavailable:
      loadBalancer:
        servers:
          - address: "10.10.10.10:111"

As for why I'm doing this. I don't want my server responding to requests. I actually found it was responding to unencrypted traffic over port 443 when I noticed stuff in the access logs that shouldn't have been there meaning someone was probing the server. I don't want a 404 or anything else coming back. I want it to completely ignore the traffic and the closest thing I found to that was to redirect the traffic to a non-existent ip address.

I tried removing the TLS from the entry point which worked, but then https://ipaddress returned a 404, so that's not really a solution.

My prior solution isn't exactly great either as an empty response is returned.

I had an idea though and instead of redirecting to an invalid ip address, I redirected back to the server on port 80 where it should be in the first place. Then that gets redirected back to port 443 encrypted. At that point the https TLS catchall works. Not the most elegant solution, but it works.

tcp:
  routers:
    catchall_unencrypted:
      rule: "HostSNI(`*`)"
      service: http
      # lowest possible priority
      # evaluated when no other router is matched
      priority: 1
  services:
    # Service that will always answer a 503 Service Unavailable response
    http:
      loadBalancer:
        servers:
          # redirect unencrypted traffic to port 80
          - address: "127.0.0.1:80"

Just on a side note, receiving an unencrypted connection on port 443 probably should return a 400 as that's not really valid. Unfortunately because Traefik can't have different rules for unencrypted vs encrypted on the same port, there's no real easy way to do that.

That seems like a lof of effort for returning a 503 instead of 404 status code. Not sure if anyone scanning the Internet really cares about the different code.

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.