Use existing LetsEncrypt certificates in Traefik

强颜欢笑 提交于 2020-01-15 10:22:32

问题


Is it possible to use existing LetsEncrypt certificates (.pem format) in Traefik?

I have Traefik/Docker set up to generate acme.json - can I import my existing certificates for a set of domains?


回答1:


Eventually I found the correct solution - not to use Traefik's ACME integration but instead to simply mount a network volume (EFS) containing certificates as issued by certbot in manual mode.

Why was this my chosen method? Because I'm mounting that certificate-holding NFS volume on two servers (blue and green). These servers are the live & staging servers for the web servers. At any time one will be "live" and the other can be either running a release candidate or otherwise in a "hot standby" role.

For this reason, better to make a separation of concerns and have a third server run as a dedicated "certificate manager". This t2.nano server will basically never be touched and has the sole responsibility of running certbot once a week, writing the certificates into an NFS mount that is shared (in read-only mode) by the two web servers.

In this way, Traefik runs on both blue and green servers to takes care of its primary concern of proxying web traffic, and simply points to the certbot-issued certificate files. For those who found this page and could benefit from the same solution, here is the relevant extract from my traefik.toml file:

defaultEntryPoints = ["https","http"]

[docker]
watch = true
exposedbydefault = false
swarmMode = true

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
  [entryPoints.https.tls]
    [[entryPoints.https.tls.certificates]]
    certFile = "/cert.pem"
    keyFile = "/privkey.pem"

Here is the relevant section from my Docker swarm stack file:

version: '3.2'

volumes:
 composer:

networks:
  traefik:
    external: true

services:
  proxy:
    image: traefik:latest
    command: --docker --web --docker.swarmmode --logLevel=DEBUG
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.toml:/traefik.toml
      - "./certs/live/example.com/fullchain.pem:/cert.pem"
      - "./certs/live/example.com/privkey.pem:/privkey.pem"
    networks:
      - traefik

And finally here is the command that cron runs once a week on the dedicated cert server, configured to use ACME v2 for wildcard certs and Route 53 integration for challenge automation:

sudo docker run -it --rm --name certbot                                      \
            -v `pwd`/certs:/etc/letsencrypt                                  \
            -v `pwd`/lib:/var/lib/letsencrypt                                \
            -v `pwd`/log:/var/log/letsencrypt                                \
            --env-file ./env                                                 \
            certbot/dns-route53                                              \
            certonly --dns-route53                                           \
                     --server https://acme-v02.api.letsencrypt.org/directory \
                     -d example.com                                          \
                     -d example.net                                          \
                     -d *.example.com                                        \
                     -d *.example.net                                        \
                     --non-interactive                                       \
                     -m me@example.org                                       \
                     --agree-tos

The folder certs is the NFS volume shared between the three servers.




回答2:


Despite that presumably anyone wonders why you actually want/need this and anyone will advise you against this, because traefik handles the automatic re-challenge very well, here's what the acme.json looks like:

{
  "Account": {
    "Email": "acme@example.com",
    "Registration": {
      "body": {
        "status": "valid",
        "contact": [
          "mailto:acme@example.com"
        ]
      },
      "uri": "https://acme-v02.api.letsencrypt.org/acme/acct/12345678"
    },
    "PrivateKey": "ABCD...EFG="
  },
  "Certificates": [
    {
      "Domain": {
        "Main": "example.com",
        "SANs": null
      },
      "Certificate": "ABC...DEF=",
      "Key": "ABC...DEF"
    },
    {
      "Domain": {
        "Main": "anotherexample.com",
        "SANs": null
      },
      "Certificate": "ABC...DEF==",
      "Key": "ABC...DEF=="
    }
  ],
  "HTTPChallenges": {}
}

Now it's up to you to write an import script or template parser to loop through your certificates/keys and put the content into the brackets or just generate your own json file in that format.

Notice that it's a slightly different format than classic pem style (i.e without line-breaks).




回答3:


I just want to add that I meanwhile found another approach while I had the need to use HAProxy:

  • run one traefik only for acme at port 81 behind HAProxy
  acl acme path_beg -i /.well-known/acme-challenge/
  use_backend acme if acme
  • have a small webserver providing the acme.json (i.e. shell2http)
  • have a cronjob (i use gitlab ci) which downloads the acme.json and extracts the certs (https://raw.githubusercontent.com/containous/traefik/master/contrib/scripts/dumpcerts.sh)
  • append the certs to a traefik.toml template
  • build a docker image and push to private registry
  • run this private traefik instance as main traefik on 80/443 in read-only mode on any backend-servers behind HAProxy
  • write a file-watcher script which restarts all ro-traefiks when acme.json changes and trigger dumpcert-script


来源:https://stackoverflow.com/questions/50575675/use-existing-letsencrypt-certificates-in-traefik

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!