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