1

Trying to create a script for automatic SSL renewal with LetsEncrypt.

Daily script begins with checking when SSL expiry is:

response="$(openssl x509 -enddate -noout -in ~/letsencrypt/www.mydomain.com/cert.pem)"

$response is notAfter=May 9 19:27:44 2018 GMT

I would like it to compare with today's date and check whether the time difference is less or equal to 7 days. Pseudocode:

if [$response is less than 7 days away from today] then cd ~/letsencrypt $$ ~/dehydrated/dehydrated --cron --domain www.mydomain.com --out . --challenge http-01

How do I go about doing this?

I tried to convert $response into a more workable format through date -d but got a date: extra operand ‘19:27:44’ error.

2

I will address your actual concern rather than the specific question you asked: dehydrated --cron already does the date checking for you.

Documentation:

--cron (-c) Sign/renew non-existent/changed/expiring certificates.

Code:

# Check expire date of existing certificate
if [[ -e "${cert}" ]]; then
  echo " + Checking expire date of existing cert..."
  valid="$("${OPENSSL}" x509 -enddate -noout -in "${cert}" | cut -d= -f2- )"

  printf " + Valid till %s " "${valid}"
  if "${OPENSSL}" x509 -checkend $((RENEW_DAYS * 86400)) -noout -in "${cert}"; then
    printf "(Longer than %d days). " "${RENEW_DAYS}"
    if [[ "${force_renew}" = "yes" ]]; then
      echo "Ignoring because renew was forced!"
    else
      # Certificate-Names unchanged and cert is still valid
      echo "Skipping renew!"

(https://github.com/lukas2511/dehydrated/blob/master/dehydrated#L1234-L1253)

RENEW_DAYS appears to default to 30, but you can override it using a configuration file; quoting the documentation:

dehydrated is looking for a config file in a few different places, it will use the first one it can find in this order:

  • /etc/dehydrated/config
  • /usr/local/etc/dehydrated/config
  • The current working directory of your shell
  • The directory from which dehydrated was run

The sample config file there contains this line:

# Minimum days before expiration to automatically renew certificate (default: 30)
#RENEW_DAYS="30"

To lower the value from the default 30 to 7 days, for example, you would edit the second line to be:

RENEW_DAYS="7"
  • Awesome! So I just need to run the upgrade command everyday, pretty much. Bonus question - now how do I make an if then statement based on that response - so example, if the certificate does renew then run X command? – DDiran Feb 9 '18 at 16:37
  • @DDiran sounds like a new question! :) – Jeff Schaller Feb 9 '18 at 16:48
  • @JeffSchaller Noted, working on that now... Could you please share more detail on overriding the RENEW_DATES though? :D – DDiran Feb 13 '18 at 9:06
  • @DDiran, see dhag's recent edit. – Jeff Schaller Feb 13 '18 at 16:13
1

Determine the number of seconds sinds 1/1/1970 for the expiry date, for now, and divide the difference by the number of seconds in a day.

$ TZ=GMT date -d "May 9 19:27:44 2018 GMT" '+%s'
1525894064
$ TZ=GMT date '+%s'                             
1518192447
$ expr \( 1525894064 - 1518192447 \) / 86400
89
  • Thanks, it does work, but not when I replace "May 9 19:27:44 2018 GMT" with $response. How come? – DDiran Feb 9 '18 at 16:16
  • You need to drop the "notAfter=". use " ${response/*=/}" – Gerard H. Pille Feb 9 '18 at 16:19
  • yeah, done that, still getting the date: extra operand ‘19:27:44’ error – DDiran Feb 9 '18 at 16:28
  • Can you add your code to the question? – Gerard H. Pille Feb 9 '18 at 16:33
1

The commands below will check the date provided by the openssl command against the date "7 days from now"; if the openssl date (in seconds since the epoch) is less than 7 days from now (in seconds since the epoch), the if command will succeed and you can do what you need to do:

response="$(openssl x509 -enddate -noout -in ~/letsencrypt/www.mydomain.com/cert.pem)"
responsetime=${response##notAfter=}
responsetz={$responsetime##* }
if [ $(date -d "$responsetime" +%s) -lt $(TZ=$responsetz date -d "now + 7 days" +%s) ]
then
   ## do the needful
fi

The first assignment (after getting the $response) strips off the leading "notAfter=" text. The second assignment captures the timezone of the response; this could be simplified if it's always GMT.

The two date commands ask (GNU) date for the time in seconds since the epoch for the openssl date and for "now + 7 days", being careful to set the timezone for the 2nd call to the timezone reported by the openssl command.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.