Routers only on websecure entrypoint by default

Hey,

I configured traefik with two entrypoints, http (:80) and https (:443). The http entrypoint should only redirect to the https endpoint.

This is my config:

entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true
          priority: 10000
  websecure:
    address: :443
    http:
      # apply default-security headers middleware to each router
      middlewares:
        - default-headers@file
      tls: true

Can I somehow define the websecure endpoint as the default one, so Ingresses and IngressRoutes, which don't explicitely define their entrypoints, will only generate routers for the websecure endpoint?

It's just a smallish imperfection, but it's bothering me, that I now have a lot of unused and unreachable routers for the web entrypoint. I know I could just specify the websecure entrypoint on all of the Ingresses and IngressRoutes, but I wanted to ask if there is an easier solution before doing this.

Thanks in advance!

2 Likes

I couldn't figure out how to do that... My understanding is that for each router you have to explicitly declare an entrypoint, its service, and its rule (i.e. domain). I ended up having to do that for both http and https. Then if you are using HTTPS you have to provide SSL configuration, either by doing all the letsencrypt stuff, or putting the ssl cert info in a config file. Then separately I create a middleware to redirect from the http router to the https router.

Keen to know if anyone thinks this can be done more easily!

# Routing for HTTP
- traefik.http.routers.yourservice-http.service=yourservice
- traefik.http.routers.yourservice-http.entrypoints=web
- traefik.http.routers.yourservice-http.rule=Host(`foo.example.com`)

# Routing for HTTPS
- traefik.http.routers.yourservice-https.service=yourservice
- traefik.http.routers.yourservice-https.entrypoints=websecure
- traefik.http.routers.yourservice-https.rule=Host(`foo.example.com`)
- traefik.http.routers.yourservice-https.tls=true
      
# Http-to-Https redirect Middleware
- traefik.http.middlewares.yourservice-http2https.redirectscheme.scheme=https
- traefik.http.middlewares.yourservice-http2https.redirectscheme.permanent=true
- traefik.http.routers.yourservice-http.middlewares=yourservice-http2https

Hello,

@stuzor something like that:

version: '3.7'

services:

  traefik:
    image: traefik:v2.3.1
    command:
      - --log.level=INFO
      - --api

      - --providers.docker.exposedbydefault=false
      
      - --entrypoints.web.address=:80
      # global redirect to https
      - --entrypoints.web.http.redirections.entryPoint.to=websecure
      - --entrypoints.web.http.redirections.entrypoint.scheme=https

      - --entrypoints.websecure.address=:443
      - --entrypoints.websecure.http.tls=true

    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    labels:
      traefik.enable: 'true'

      # Dashboard
      traefik.http.routers.traefik.rule: Host(`traefik.localhost`)
      traefik.http.routers.traefik.service: api@internal
      traefik.http.routers.traefik.middlewares: auth

      traefik.http.middlewares.auth.basicauth.users: user:$$apr1$$q8eZFHjF$$Fvmkk//V6Btlaf2i/ju5n/ # user/password

  whoami:
    image: traefik/whoami:v1.6.0
    labels:
      traefik.enable: 'true'

      traefik.http.routers.example.rule: Host(`foo.example.com`)

Hey @stuzor,

you definitely don't have to define those for each and every router.

My snippet from above is part of my static configuration. On my ingresses (I use traefik on Kubernetes), I just annotate:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-app
  namespace: my-namespace
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
    - host: my-app.my-domain.com
      http:
        paths:
          - path: /
            backend:
              serviceName: my-service
              servicePort: 8080

This will now create two routers for me connected to the backend service my-service (the service mentioned in the yaml file is a Kubernetes service, not the Traefik one). Both routers are using the default-headers middleware.

I could restrict this to only one router by setting the annotation traefik.ingress.kubernetes.io/router.entrypoints: websecure. But as I have hundreds of ingresses, I'd really like to do something, that just defines websecure as being the default entrypoint, that is used in case none are specified.

And as @Idez pointed out: In a docker environment you only need to define the two annotations traefik.enable: 'true' and traefik.http.routers.example.rule: Host(my-app.my-domain.com) and you'll end up with two routers connected to the default-headers middleware and the appropriate services.

As this comment on Github says, this is a feature, that is will not be implemented again (it was in v1):

With v2, TLS being defined at router level + ability to route at TCP level, the default entrypoint does not make sense as it could break the TCP router, or accidentally mux HTTP/TCP.

There is now the general rule: The default entrypoints in v2 are all "tcp" entrypoints for http/tcp router, there is no default entrypoint for udp.

So I mark this topic as answered.

Best,
razr