Use consul to configure your certificates with Traefik v2 and Swarm

Hi
We are trying to migrate to Traefik 2.1. We use three providers: file, docker and consul. The goal is to use consul to modify the configuration of traefik. We don't use letsencrypt and generate our own certificates. We are not able to add our certificates in consul so that they are automatically used by Traefik depending on the site accessed.
Only the default certificate is used (we specified it in a .toml file)

This is our stack swarm

version: "3.3"
services:
  traefik:
    image: traefik:v2.1.1
    depends_on:
      - consul-cluster
    command:
      - --providers.docker.swarmMode=true
      - --providers.docker.network=NET_OVE_TRAEFIK_PUBLIC
      - --providers.docker.constraints=Label(`traefik.enable`,`true`)
      - --providers.docker.endpoint=unix:///var/run/docker.sock
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --api
      - --providers.consulcatalog.stale=true
      - --providers.consulcatalog.endpoint.address=consul-cluster:8500
      - --providers.file.directory=/etc/traefik/
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - VOL_NFS_CERTIF_RO:/etc/coolcorp:ro
      - VOL_NFS_CNF_TRAEFIK_RO:/etc/traefik/
    networks:
      - NET_OVE_CONSUL_INTERNAL
      - NET_OVE_TRAEFIK_PUBLIC
    ports:
      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host
      - target: 8080
        published: 8080
        mode: host
    deploy:
      replicas: 3
      placement:
        constraints:
          - node.role == manager
        #  - node.labels.name == swaman01 
        preferences:
          - spread: node.id
      labels:
          - traefik.enable=true
          - "traefik.http.routers.traefik.rule=Host(`traefik.inf.prd.dck.coolcorp.priv`)"
          - "traefik.http.routers.traefik.service=api@internal"
          - "traefik.http.routers.traefik.entrypoints=websecure"
          - traefik.http.routers.traefik.tls=true
          - "traefik.http.services.dummyService.loadbalancer.server.port=1337"
          - "traefik.http.routers.traefik.middlewares=authtraefik"
          - "traefik.http.middlewares.authtraefik.basicauth.users=user:$$apr1$$q8eZFHjF$$Fvmkk//V6Btlaf2i/ju5n/"
            # middleware redirect
          - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"  
            # global redirect to https
          - "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
          - "traefik.http.routers.redirs.entrypoints=web"
          - "traefik.http.routers.redirs.middlewares=redirect-to-https"
    secrets:
        - SEC_NOP_TRAEFIK_CONSUL_AUTH
  consul-cluster:
    image: consul:1.6.2
    hostname: "{{.Node.Hostname}}"
    command: [ "agent", "-server", "-bootstrap-expect=3", "-retry-max=3", "-retry-interval=10s", "-datacenter=prd", "-join=consul-cluster", "-retry-join=consul-cluster", "-bind={{ GetInterfaceIP \"eth0\" }}", "-client=0.0.0.0", "-ui"]
    volumes:
      - type: bind
        source: /mnt/cnf/prd/traefik_consul
        target: /consul/data
    networks:
      - NET_OVE_CONSUL_INTERNAL
      - NET_OVE_TRAEFIK_PUBLIC
    secrets:
      - SEC_NOP_TRAEFIK_CONSUL_AUTH
    deploy:
      labels:
        - traefik.enable=true
        - traefik.http.routers.consul.entrypoints=websecure
        - traefik.http.routers.consul.tls=true
        - traefik.http.routers.consul.rule=Host(`consul.inf.prd.dck.coolcorp.priv`)
        - traefik.http.services.consul.loadbalancer.server.port=8500
        - "traefik.http.routers.consul.middlewares=authconsul"
        - "traefik.http.middlewares.authconsul.basicauth.users=user:$$apr1$$q8eZFHjF$$Fvmkk//V6Btlaf2i/ju5n/"
      mode: global
      placement:
        constraints:
          - node.role == manager        
networks:
  NET_OVE_TRAEFIK_PUBLIC:
    external: true
  NET_OVE_CONSUL_INTERNAL:
    driver: overlay
volumes:
  VOL_NFS_CERTIF_RO:
    external: true
  VOL_NFS_CNF_TRAEFIK_RO:
    external: true
 #    driver_opts:
 #     type: "nfs"
 #     o: "addr=storage.coolcorp.priv,ro,nfsvers=3,nolock,soft"
 #     device: ":/volume1/docker/cnf/prd/traefik_consul"
secrets:
 SEC_NOP_TRAEFIK_CONSUL_AUTH:
   external: true

Here's our configuration file.

[tls]

  [tls.stores]
    [tls.stores.default]
      [tls.stores.default.defaultCertificate]
        certFile = "/etc/coolcorp/prd/inf/prd_inf.cer"
        keyFile = "/etc/coolcorp/prd/inf/prd_inf.key"

  [[tls.certificates]]
    certFile = "/etc/coolcorp/prd/inf/prd_inf.cer"
    keyFile = "/etc/coolcorp/prd/inf/prd_inf.key"

In consul, we have created the following tree structure

traefik/tls/certificates/1/certfile=/etc/coolcorp/prd/inf/tstext_inf.cer
traefik/tls/certificates/1/keyFile=/etc/coolcorp/prd/inf/tstext_inf.key

This is our test stack

version: "3.3"
services:
  webtest:
    image: containous/whoami:v1.3.0
    networks:
        - NET_OVE_TRAEFIK_PUBLIC
    deploy:
      replicas: 3
      placement:
        constraints:
          - node.role == manager
        preferences:
          - spread: node.id
      labels:
        - traefik.enable=true
        - traefik.http.routers.webtest.entrypoints=websecure
        - traefik.http.routers.webtest.tls=true
        - traefik.http.routers.webtest.rule=Host(`test.coolcorp.fr`)
        - traefik.http.services.webtest.loadbalancer.server.port=80
        - "traefik.http.routers.webtest.middlewares=authwebtest"
        - "traefik.http.middlewares.authwebtest.basicauth.users=user:$$apr1$$q8eZFHjF$$Fvmkk//V6Btlaf2i/ju5n/"   
networks:
  NET_OVE_TRAEFIK_PUBLIC:
    external: true              

When accessing the test site, the certificate specified in consul is not used.

Do you have any idea?

1 Like

Hello,

the Consul Catalog provider is not the Consul KV provider.

The Consul KV provider will come in the next version (v2.2)
https://docs.traefik.io/master/providers/consul/

3 Likes

HI,
Thank you for your help ! I will wait 2.2 version.

1 Like

I'm glad to know that consul kv will be back on traefik v2.2.

You can create a docker-compose.yml with an example.

Hi,
Thanks

I tried that version with Kubernetes, but I have another problem.