Getting TCP routers to work with Traefik

I'm trying to set up a TCP router to forward requests via an SNI to an apache server.

  labels:
    - traefik.enable=true

    - traefik.http.routers.insecure.rule=Host(`i.trajano.net`)
    - traefik.http.routers.insecure.entryPoints=http
    - traefik.http.routers.insecure.middlewares=default

    - traefik.tcp.routers.intranet.rule=HostSNI(`i.trajano.net`)
    - traefik.tcp.routers.intranet.entryPoints=https
    - traefik.tcp.routers.intranet.tls.certresolver=default
    - traefik.tcp.routers.intranet.tls=true
    - traefik.tcp.routers.intranet.service=intranet

    - traefik.tcp.services.intranet.loadbalancer.server.port=443

However, in the logs it says:

edge_traefik.0.jb62zdmsnnha@docker-desktop | time="2019-09-08T20:47:06Z" level=error msg="port is missing" providerName=docker container=intranet_web-sfw8i1stmkokltqu2v17xdwyq

which does not make sense as I had that port specified in the last line.

The port it's asking for is on the http router. You'll need to define a service, such as:

    - traefik.http.routers.insecure.service=insecure
    - traefik.http.services.insecure.loadbalancer.server.port=80

I'm guessing port 80 for the insecure route

I don't expect there to be a service in for the insecure port since I have a default chain (forgot to put that earlier)

    - traefik.http.middlewares.default.chain.middlewares=https-only,compress-all
    - traefik.http.middlewares.https-only.redirectscheme.scheme=https
    - traefik.http.middlewares.https-only.redirectscheme.permanent=true
    - traefik.http.middlewares.compress-all.compress=true

What if you use port 443 with the above example? You could also remove the http router completely to see if the TCP router works.

  labels:
    - traefik.enable=true

    - traefik.http.routers.insecure.rule=Host(`i.trajano.net`)
    - traefik.http.routers.insecure.entryPoints=http
    - traefik.http.routers.insecure.middlewares=default
    - traefik.http.routers.insecure.service=insecure
    - traefik.http.services.insecure.loadbalancer.server.port=443

    - traefik.tcp.routers.intranet.rule=HostSNI(`i.trajano.net`)
    - traefik.tcp.routers.intranet.entryPoints=https
    - traefik.tcp.routers.intranet.tls.certresolver=default
    - traefik.tcp.routers.intranet.tls=true
    - traefik.tcp.routers.intranet.service=intranet
    - traefik.tcp.services.intranet.loadbalancer.server.port=443

or

  labels:
    - traefik.enable=true

    - traefik.tcp.routers.intranet.rule=HostSNI(`i.trajano.net`)
    - traefik.tcp.routers.intranet.entryPoints=https
    - traefik.tcp.routers.intranet.tls.certresolver=default
    - traefik.tcp.routers.intranet.tls=true
    - traefik.tcp.routers.intranet.service=intranet
    - traefik.tcp.services.intranet.loadbalancer.server.port=443

I have an entrypoint defined as mariadb-port, and have a TCP route set up with:

      - traefik.tcp.routers.mariadb.entrypoints=mariadb-port
      - traefik.tcp.routers.mariadb.tls=true
      - traefik.tcp.routers.mariadb.rule=HostSNI(`*`)
      - traefik.tcp.routers.mariadb.service=mariadb
      - traefik.tcp.services.mariadb.loadbalancer.server.port=3306

It's not the same type of SNI rule, but i think those rules should work as you expect.

1 Like

Thanks that got rid of one problem "the port is missing" issue.

Unfortunately my overall objective is still not working which is to route i.trajano.net to an Apache server using Client Certificates.

I am presuming at the moment because of LetsEncrypt JSON file is not being stored my certificate will obviously fail, but I should at least see something in the logs regarding some failure, instead I am just getting no response.

This is what I have at the moment

  labels:
    - traefik.enable=true

    - traefik.tcp.routers.intranet.rule=HostSNI(`i.trajano.net`)
    - traefik.tcp.routers.intranet.entryPoints=https
    - traefik.tcp.routers.intranet.tls.certresolver=default
    - traefik.tcp.routers.intranet.tls.passthrough=true
    # - traefik.tcp.routers.intranet.tls=true
    - traefik.tcp.routers.intranet.service=intranet

    - traefik.tcp.services.intranet.loadbalancer.server.port=443

Note I am shifting the position of the comment around. Still no luck though. My Apache server is running on a self-signed certificate with client side validation (because unlike my previous setup the LetsEncrypt certificate is not available to me anymore)

I think you should try to resolve your certificate issue first, and then turn on debug logging and see if that helps identify what the issue is. I'm assuming you can get the http router to work already?

1 Like

yup HTTP routers work with the certificates failing because of rate limits due to the restarts. But I'll have to do that when I get home.

You should should turn on the staging server while you're troubleshooting to avoid rate limits:

--certificatesResolvers.default.acme.caServer="https://acme-staging-v02.api.letsencrypt.org/directory"

and I bet you're hitting the rate limit because you're trying to pull a new certificate each time you restart traefik

Yes I had it at one point, it worked so I switched. What I didn't realize what after that it kept on redoing the request but I have not changed it since.

It would be much easier for you to save the cert locally than to try try and save it in a docker volume. The cert needs to have the correct permissions and perhaps when it is generated in the docker volume the permissions don't allow it to persist for some reason? Saving it locally also lets you check the status (if cert was pulled and which server it was pulled from) and allows you to delete it if you need to. I would at least start there.

1 Like