How to automatically renew certificates?

I only installed letsencrypt the other day, so, no it isn’t outdated. I actually forgot that the --help all option exists even though I saw it before. Sorry, my bad - thanks for pointing it out!

On ubuntu-server and apache.
How do I put LE in cron when it requires sudo to work?

I don’t know if there’s something wrong with my setup, but I can’t run LE as pure root. It fails every time. Says something about some module _struct is missing. It runs perfectly fine as a regular user with sudo. Put lots of stuff in the cli.ini, so it runs completely without interaction, after sudo authorisation.

depending on your sudoers file you can put everything into a script (like the one from @mikeskril) and add the following line to your cron (e.g. /etc/cron.d/local)

0 0 1 * * <youruser> /usr/bin/sudo <your-script>

What I highly suggest, is that you don’t use the generated certificate directly. What I do is to copy the generated certificate to something like mycert.pem. and then create a symlink to the current certificate and then point my nginx config to that symlink. In case something is wrong with the certificate I can roll-back to a valid one (as I renew my certificates every 30 days).

Also you should always monitor the state of your certificates. I created a little program that does that and shows you a simple webpage: https://github.com/drtoful/certinel You put this on your local machine and let it run there and check on the page from time to time, as it checks every 5 minutes and updates the page automatically. There’s also a command line utility https://github.com/srvrco/checkssl that does the same, but a.f.a.i.k. it’s a one-shot test.

2 Likes

Hmm, that seems to have failed.

Dec 8 10:15:01 user sudo: pam_unix(sudo:auth): conversation failed
Dec 8 10:15:01 user sudo: pam_unix(sudo:auth): auth could not identify password for [user]

My username replaced with “user”.

@NoSubstitute, keep in mind that file /etc/sudoers should be configured to allow your user to run that command with sudo (and to run that command unattended it should be configured to not require password).

To do that, edit sudoers file, as root you should run this command visudo and put a line like this into that file (change youruser and the path to the command):
youruser ALL=(root) NOPASSWD:/path/to/the/command

Cheers,
sahsanu

1 Like

or maybe create an extra user that cannot login normally so security gets less compromise.

1 Like

@My1, how do I create such a user? One that can’t login.

if you have luck (depending on distro and stuff) you can lock a user with passwd -l
depending on whether your systems still stores passwords in the passwd or in the shadow it’s a little bit different, but fist you need to create a “normal” user as usual and then there’s the main point. go into the pass or shadow file and replace the password hash with somehing that cant be a hash (for example put an ! before it (that’s what the command above does according to a website) so any password matching fails.

BUT!

the account can still be accessed by means that dont need a password, for example going into it by using su from root or using public key auth if that is configured.

Or use certain shells: https://unix.stackexchange.com/questions/10852/whats-the-difference-between-sbin-nologin-and-bin-false

I wrote a blog post about my setup using the webroot method for renewals: https://www.bytopia.dk/blog/2015/11/09/automatic-renewal-of-lets-encrypt-issued-certificates/

Basically I use the following script to renew all letsencrypt certificates when they are about to expire in 4 weeks:

#!/bin/bash
if [ ! -d /etc/letsencrypt/live ]; then
  exit 1
fi
function issueCert {
  /root/.local/share/letsencrypt/bin/letsencrypt certonly --renew-by-default --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory --authenticator webroot --webroot-path /var/www/acme $1
}
exitcode=1
while IFS= read -r -d '' cert; do
  if ! openssl x509 -noout -checkend $((4*7*86400)) -in "${cert}"; then
    subject="$(openssl x509 -noout -subject -in "${cert}" | grep -o -E 'CN=[^ ,]+' | tr -d 'CN=')"
    subjectaltnames="$(openssl x509 -noout -text -in "${cert}" | sed -n '/X509v3 Subject Alternative Name/{n;p}' | sed 's/\s//g' | tr -d 'DNS:' | sed 's/,/ /g')"
    domains="-d ${subject}"
    for name in ${subjectaltnames}; do
      if [ "${name}" != "${subject}" ]; then
        domains="${domains} -d ${name}"
      fi
    done
    issueCert "${domains}"
    exitcode=0
  fi
done < <(find /etc/letsencrypt/live -name cert.pem -print0)
exit ${exitcode}
2 Likes

Ah, so that path/to/the/command would be directly to the LE script?

Thank you, @My1
I'm going to have to try that, because I still can't run LE as root.

anyone has a script for ubuntu trusty + nginx? get it here not working :disappointed_relieved:

Do try with https://gethttpsforfree.com too.

If your user is foo and you have the letsencrypt-auto command for example in /home/foo/letsencrypt/letsencrypt-auto you should put in sudoers the path to letsencrypt (not letsencrypt-auto) command that should be located here /home/foo/.local/share/letsencrypt/bin/letsencrypt

So the line in sudoers file should be something like this:
foo ALL=(root) NOPASSWD:/home/foo/.local/share/letsencrypt/bin/letsencrypt

Now, as your foo user you can execute letsencrypt-auto command and it will take care to call to letsencrypt with sudo or you can directly execute sudo letsencrypt command.

Cheers,
sahsanu

1 Like

after 4 beers …i got it

Ubuntu Trusty & Nginx
make a cli.ini under /etc/letsencrypt/cli.ini
fill with
authenticator = webroot
webroot-path = /var/www/example/
server = https://acme-v01.api.letsencrypt.org/directory
email = your@mail.com
text = True
agree-tos = True
renew-by-default = True

now command line: crontab -e
@monthly /root/letsencrypt/letsencrypt-auto --config /etc/letsencrypt/cli.ini -d example.com -d www.example.com -d somestuff.example.com certonly && service nginx reload
save for && nginx reload i use /pathto/pathto/nginx/sbin/nginx -s reload -c /pathto/pathto/nginx/conf/nginx.conf
pathto=find your path use only if nginx is not a service

these steps are helping me! hope you too…thanks to the folks here!
IMPORTANT NOTES:

  • Congratulations! Your certificate and chain have been saved at
    /etc/letsencrypt/live/example/fullchain.pem. Your cert will
    expire on 2016-03-07. To obtain a new version of the certificate in
    the future, simply run Let’s Encrypt again.

sorry for my english

1 Like

I can’t run LE in any account but the one I commonly use! Can’t run as root, and can’t run as newly created le-user. Python fails with

ImportError: No module named _struct

So I can’t, so far, use this idea of a sudo user not needing a password to run LE.

You might want to take a look a the script I have created for updating my certificates.( Please note: probably very alpha)

The script should implement the following features:

  1. works with nginx, but can easily altered to work with any other web server,
  2. works with multiple certificates,
  3. treats each certificate individually,
  4. can be run daily without taking any action without cause,
  5. restarts the web server only once even if multiple certificate shave been updated,
  6. suitable for unattended usage as often as you like,
  7. should request new certificate when expiry of the present one comes closer than an configurable amount of days,
  8. expiry date is read from the certificate,
  9. if request fails for some reason, the next run retries.

I did upload it on github: https://github.com/myprs/lenc-update

There is also some rudimentary documentation.

1 Like

Please excuse the dumb question - I’m a beginner with these things:

Would it make sense to setup a LE cronjob with a non root shared hosting? That is not possible, right? How I understand it, the cronjob takes care about the cert renewal process. But it would require the LE client on the server (?)

As I generate my certs locally (I have to, bc no root access with my hosting plan), I can’t use cronjobs (although, I’m free to setup one cronjob with my hosting plan) to automatically renew them - correct?

More or less correct. You don’t have to be root if you use one of the third-party clients. If you can add files to the web root and replace the certificate information with the user that the cronjob uses, then you have all the access you need.

If you have to use a control panel interface to update/add the certificate information, a fully automated solution isn’t really feasible at this time without a bunch of special coding on your remove system.

1 Like

Appreciate your work!
Have one issue with running letsencrypt with renew argument. Seems letsencrypt doesn’t know how to deal with “renew” argument provided. Any ideas?