Skip to content

Instantly share code, notes, and snippets.

@Jensderond
Created July 15, 2020 10:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jensderond/9a98ffb5861a65d7a59b0ae6b42ddfa9 to your computer and use it in GitHub Desktop.
Save Jensderond/9a98ffb5861a65d7a59b0ae6b42ddfa9 to your computer and use it in GitHub Desktop.
Clean up old certificates Traefik - Tested with Traefik 2.2.x
acmefile = acme.json
traefik_dashboard = <TRAEFIK_DASHBOARD_URL>
auth_user = <USERNAME>
auth_password = <PASSWORD>
.SILENT: clean
.PHONY: clean
clean:
curl -s "https://$(auth_user):$(auth_password)@$(traefik_dashboard)/api/http/routers" | jq -r ".[]" | jq ".rule" | sed "s/\"Host(\`//g;s/\`)\"//g" | uniq > existing_frontends;
cat $(acmefile) | jq ".default.Certificates[].domain.main" | sort | uniq | sed "s/\"//g" > existing_certs;
awk 'NR==FNR{a[$$0];next}!($$0 in a)' existing_frontends existing_certs > certs_to_remove;
cp $(acmefile) $(acmefile).new;
cat certs_to_remove | xargs -I'{}' -i sh -c "jq 'del(.default.Certificates[]| select(.domain.main == \"{}\"))' $(acmefile).new > $(acmefile).new2; mv $(acmefile).new2 $(acmefile).new";
chmod 600 $(acmefile).new;
chown traefik:docker $(acmefile).new;
mv $(acmefile) $(acmefile).bak;
mv $(acmefile).new $(acmefile);
rm certs_to_remove existing_certs existing_frontends;
docker-compose restart;
@fuzzykiller
Copy link

A good start. However, there are several issues:

  • It does not support OR rules (Host(`a.example.com`) || Host(`b.example.com`))
  • It does not support HostRegexp rules
  • It does not support SANs in acme.json

OR rule support should be relatively trivial, just split the line or something. Regular expressions could be supported, but that would be very challenging to accurately implement.

@MarkErik
Copy link

Thank you for sharing this!

I am running into a few issues with the first few lines of the script, and I was wondering if things have changed on the traefik side with 2.4 that might impact the script?

The output of the curl api -> existing_frontends is:

"PathPrefix(`/.well-known/acme-challenge/
"PathPrefix(`/api
"PathPrefix(`/
www.url.one
"HostRegexp(`{host:.+}
www.url.two

I was expecting that it would just be a list of the URLs that are running, without the PathPrefix lines.

And on the cat acme.json -> existing certs, I get the following error:
jq: error (at <stdin>:43): Cannot iterate over null (null)

Thank you in advance for any advice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment