== Traefik == === From certbot to traefik === 1. Get public IP address of server curl ifconfig.me 8.8.8.8 2. Setup a DNS entry that points to that server 2.1. Check DNS name dig @8.8.8.8 test.javilegido.com +short 8.8.8.8 3. Make sure ports TCP 80 and 443 are open **WARNING**: if behind LAN router remember to setup NAT 4. Generate certificate mkdir etc_letsencrypt docker run -it \ --rm \ --name certbot \ -v `pwd`/etc_letsencrypt:/etc/letsencrypt \ -p 80:80 \ certbot/certbot certonly 1 javi@example.com Y N test.javilegido.com Requesting a certificate for test.javilegido.com Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/test.javilegido.com/fullchain.pem Key is saved at: /etc/letsencrypt/live/test.javilegido.com/privkey.pem This certificate expires on 2022-08-24. These files will be updated when the certificate renews. NEXT STEPS: - The certificate will need to be renewed before it expires. Certbot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal-setup for instructions. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - If you like Certbot, please consider supporting our work by: * Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate * Donating to EFF: https://eff.org/donate-le - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5. tree etc_letsencrypt/ ├── accounts │   └── acme-v02.api.letsencrypt.org │   └── directory │   └── 77fcea9a20707993ed3e5d65f5960a8f │   ├── meta.json │   ├── private_key.json │   └── regr.json ├── archive │   └── test.javilegido.com │   ├── cert1.pem │   ├── chain1.pem │   ├── fullchain1.pem │   └── privkey1.pem ├── csr │   └── 0000_csr-certbot.pem ├── keys │   └── 0000_key-certbot.pem ├── live │   ├── README │   └── test.javilegido.com │   ├── cert.pem -> ../../archive/test.javilegido.com/cert1.pem │   ├── chain.pem -> ../../archive/test.javilegido.com/chain1.pem │   ├── fullchain.pem -> ../../archive/test.javilegido.com/fullchain1.pem │   ├── privkey.pem -> ../../archive/test.javilegido.com/privkey1.pem │   └── README ├── renewal │   └── test.javilegido.com.conf └── renewal-hooks ├── deploy ├── post └── pre certbot fullchain.pem => certificate privkey.pem => key chain.pem => CA public certificate acme.json "Certificates": [ { "domain": { "main": "ranura.d.kedu.coop" }, "certificate": "CONTENT_OF_fullchain.pem", "key": "CONTENT_OF_privkey.pem", "Store": "default" }, 6. Deploy traefik with one example https://doc.traefik.io/traefik/user-guides/docker-compose/acme-tls/ 6.1. vim docker-compose.yml Adjust: --certificatesresolvers.myresolver.acme.email traefik.http.routers.whoami.rule **NOTE**: the challenge is listening in port 8080, so don't change it version: "3.3" services: traefik: image: "traefik:v2.7" container_name: "traefik" command: - "--log.level=DEBUG" - "--api.insecure=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.myresolver.acme.tlschallenge=true" #- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" - "--certificatesresolvers.myresolver.acme.email=javi@example.com" - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" ports: - "443:443" - "8080:8080" volumes: - "./letsencrypt:/letsencrypt" - "/var/run/docker.sock:/var/run/docker.sock:ro" whoami: image: "traefik/whoami" container_name: "simple-service" labels: - "traefik.enable=true" - "traefik.http.routers.whoami.rule=Host(`test.javilegido.com`)" - "traefik.http.routers.whoami.entrypoints=websecure" - "traefik.http.routers.whoami.tls.certresolver=myresolver" 6.2. Start docker-compose up -d docker logs -f traefik ... time="2022-06-03T18:15:00Z" level=debug msg="Certificates obtained for domains [test.javilegido.com]" providerName=myresolver.acme routerName=whoami@docker rule="Host(`test.javilegido.com`)" ACME CA="https://acme-v02.api.letsencrypt.org/directory" time="2022-06-03T18:15:00Z" level=debug msg="Configuration received: {\"http\":{},\"tcp\":{},\"udp\":{},\"tls\":{}}" providerName=myresolver.acme ... 6.3. (From another host) wget https://test.javilegido.com 6.4. Stop sudo docker-compose down 6.5. Backup sudo cp letsencrypt/acme.json ./acme.json.bak 7. Replace certs 7.1. Transform certbot certificates in strings sudo chown -R `whoami`:`whoami` etc_letsencrypt* _IN=etc_letsencrypt/live/test.javilegido.com/fullchain.pem _OUT=traefik_certificate cat $_IN | base64 | tr '\n' ' ' | sed --expression='s/\ //g' > $_OUT _IN=etc_letsencrypt/live/test.javilegido.com/privkey.pem _OUT=traefik_key cat $_IN | base64 | tr '\n' ' ' | sed --expression='s/\ //g' > $_OUT 7.2. Edit: sudo vim letsencrypt/acme.json And replace: certificate: Content of file 'traefik_certificate' key: Content of file 'traefik_key' **WARNING**: both files content differ, "letsencrypt/acme.json" and "acme.json.bak" 8. Test 8.1. Take MD5 of acme.json sudo md5sum letsencrypt/acme.json ec151c804d1776d898b62b1b30691aeb letsencrypt/acme.json 8.2. Make file "acme.json" readonly vim docker-compose.yml And leave change only below line: #- "./letsencrypt:/letsencrypt" - "./letsencrypt:/letsencrypt:ro" 8.3. Recreate sudo docker-compose up -d --force-recreate 8.4. Check MD5 of the file: sudo md5sum letsencrypt/acme.json ec151c804d1776d898b62b1b30691aeb letsencrypt/acme.json Should be the same than step 8.1. 8.5. Test wget https://test.javilegido.com