Parsing Certbot Output

I’m trying to wrap certbot in a wrapper script that keeps my own records of when certs get updated, what their new expiration dates are, and things like that.

  1. I hope someone can tell me there is a super-secret “output in xml” flag for certbot to make it’s output super easy to parse?

  2. I didn’t think so. So can you guys post the output from sudo certbot certificates here? Particularly people with multiple certificates and many many SAN names inside each certificate. If you want to replace your domain names with ‘example1.com’, `example2.com’ and so-on, that’s fine. But try not to change the text formatting in anyway besides that. I really want to see every possible output option so I can parse it accordingly.

Hi @l008com

I think this is the wrong way.

Certbot is to used as a command line tool. Not like an API.

And the output may change, so you have to change your parser, that's terrible.

Create a connection, then you should have the certificate informations. So you can use these informations.

So you can use different programming languages to do the same.

Certbot does have an API though: API Documentation — Certbot 2.7.0.dev0 documentation

Apart from the documentation linked above, there's not really good documentation about how to use it..

2 Likes

I agree it's not ideal but I want to get each cert's expiration date and list of domains contained within, and this does seem like the easiest way to get that. I may have to update the script periodically but it should be pretty easy to make those updates. And my script will notify me as soon as that needs to be done.

Create a connection, then you should have the certificate informations.

Can you elaborate on this?

Seems promising but… missing how is no exaggeration. What even are these commands? How/where do you run them?

Thanks, good to know.

I had the same question creating https://check-your-website.server-daten.de/

In .NET, it's easy to create a connection and define a handler to check the certificate.

The handler is called with the certificate informations. So if the certificate is invalide, but the handler returns true, the connection loads the url, has the correct http status, can read the http headers ...

And the handler can read all certificate informations, so it's possible to show, if the certificate is valide, the SAN-list, if the certificate is revoked etc.

Same functions should exist in most programming languages which support https requests.

So you can write a tool to check your online certificates directly.

Well that was easier than I thought it would be. The article is about getting the expiration date but the same array has all the info including the list of SAN domains. Weirdly encoded but easily extracted.

I see your last post covers other methods.
I was going to suggest using OpenSSL to output the expiration date and SAN.

Certbot is written in Python. Look like python commands to me. Certbots own main.py uses a line with import certbot. It would surprise me if you could write a Python script, import certbot there and use the commands from the API documentation.

My php connection returns the expiration time in seconds. Is that time going to be in my own time zone? Or do I have to convert it to my own time zone?

Perhaps that's the UNIX timestamp - DateAdd(seconds, yourValue, '1970-01-01') to get the expiration date.

You have the cert.pem files:
See if you can work with::
openssl x509 -in cert.pem -noout -dates | grep After
openssl x509 -in cert.pem -noout -text | grep DNS:

Outputs:
notAfter=Mar 14 18:46:26 2019 GMT

DNS:cert.int-x1.letsencrypt.org, DNS:cert.int-x2.letsencrypt.org, DNS:cert.int-x3.letsencrypt.org, DNS:cert.int-x4.letsencrypt.org, DNS:cert.root-x1.letsencrypt.org, DNS:cert.staging-x1.letsencrypt.org, DNS:cert.stg-int-x1.letsencrypt.org, DNS:cert.stg-root-x1.letsencrypt.org, DNS:cp.letsencrypt.org, DNS:cp.root-x1.letsencrypt.org, DNS:cps.letsencrypt.org, DNS:cps.root-x1.letsencrypt.org, DNS:crl.root-x1.letsencrypt.org, DNS:letsencrypt.org, DNS:origin.letsencrypt.org, DNS:origin2.letsencrypt.org, DNS:status.letsencrypt.org, DNS:www.letsencrypt.org

The LetsEncrypt.org site cert expires in 26 days, 6 hours…
Oh no!
That’s less than 30 days!
Sound the alarms!
Email everyone!
[or do whatever your job would do in such a case]

1 Like

I’m finishing up my script that does the following:

  • Renews all Certs
  • Loops through my list of certs (via SQL) and for each cert:
  • Gets cert info via PHP over TCP. If the expiration date is different then what I have in my database, I update my database, load some other info, copy certs to my backup drive, and restart apache

But this won’t work will it? Because I won’t be getting info on the new cert UNTIL I restart apache, correct? Or will apache start serving the new cert immediately, without needing a restart?

I could just always restart apache every time, but restarting apache twice a day (plus a third for my log rotation) seems… excessive.

Depending on how you renew. When using the apache installer plugin, it will reload itself automatically, without downtime. Without using an installer plugin, you'll need to reload Apache "manually", but this can be automated through a certbot hook, such as the --deploy-hook.

The documentation isn’t clear on this one fine detail:

does --deploy-hook get run for each certificate that gets renewed (say I have two that expire at the same time because I made them at the same time), or will it only run once after all old certs have been renewed?

This would be during a single run of certbot renew.

From the same documentation:

Command to be run in a shell once for each successfully issued certificate.

As I interpret this line, it will run for every separate renew.

Ahh gotcha. I was looking further up in the docs where it is vague. If I wanted to reissue a cert to offset the expiration dates, I can just run my creation command again and it will give me a new cert, right? This would be a one time thing I’d do once I have my certs for all my domains loaded, just to spread out the expiration dates.

I also agree that it reads clear enough to understand that for each certbot run:
Certbot will iterate through the list of certs (one by one) and, if needed, it will renew them (one by one) and it will call --deploy-hook once after each cert is successfully renewed [and immediately following each renewal - not just once after all certs have been processed].

Otherwise, the updated shell variables would get overwritten and could only be correctly used for the last cert renewed.