├── README.md └── letsencrypt-watch /README.md: -------------------------------------------------------------------------------- 1 | # letsencrypt-watch 2 | 3 | Independent [certwatch](http://linux.die.net/man/1/certwatch) cron script for [letsencrypt](https://letsencrypt.org) certificates. 4 | 5 | --- 6 | 7 | See also: **[nginx-certwatch](https://github.com/cytopia/nginx-certwatch)** 8 | 9 | --- 10 | 11 | This was mainly built as I am using [nginx](http://nginx.org/) and the normal `/etc/cron.daily/certwatch` script is not picking up the SSL certificates in my vhosts as it relies on [apache](apache.org) and quits if it is not found: 12 | ```shell 13 | test -x /etc/httpd/modules/libmodnss.so || return 0 14 | # and 15 | test -r /etc/httpd/conf/httpd.conf || return 0 16 | ``` 17 | 18 | Add this shell script to your crontab (or copy it to `/etc/cron.daily/`) to be notified via email when your certificates reach expiry. 19 | The default behavior (without arguments) is to notify the root user, once the certificates will expire in 30 days or less. 20 | 21 | 22 | ## Usage 23 | 24 | All command line arguments are optional and if not specified, the default values are used. 25 | 26 | ```shell 27 | $ letsencrypt-watch [--period=30] [--email=user@mail.tld] [--path=/etc/letsencryt] 28 | 29 | --period=XX specify period in days to check for (Default: 30) 30 | --email=root specify email to send notifications if period expires (Default: root) 31 | --path=/etc/path specify letsencrypt base path (Default: /etc/letsencrypt) 32 | 33 | ``` 34 | 35 | ## Cronjob 36 | 37 | Put the following example in your cron daily and replace the email with your own. 38 | 39 | ```shell 40 | @daily /path/to/letsencrypt-watch --email=cytopia@everythingcli.org 41 | ``` 42 | or 43 | ```shell 44 | 0 0 * * * /path/to/letsencrypt-watch --email=cytopia@everythingcli.org 45 | ``` 46 | 47 | ## Note 48 | 49 | * 100% POSIX compatible 50 | * No [bashism](http://mywiki.wooledge.org/Bashism) 51 | -------------------------------------------------------------------------------- /letsencrypt-watch: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ue 2 | 3 | 4 | PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH" 5 | 6 | 7 | 8 | ############################################################ 9 | # Variables that can be overwritten via cmd args 10 | ############################################################ 11 | 12 | # 13 | # Default letsencrypt path. 14 | # Can be overwritten via --path=/path/to/letsencrypt 15 | # 16 | LETSENCRYPT_PATH="/etc/letsencrypt" 17 | 18 | # 19 | # Default max validity in days 20 | # Can be overwritten via --period=10 21 | # 22 | MAX_DAYS="30" 23 | 24 | # 25 | # Default email address when certs are out of validity 26 | # Can be overwritten via --email=user@example.tld 27 | # 28 | EMAIL="root" 29 | 30 | 31 | 32 | 33 | ############################################################ 34 | # Variables that are fix 35 | ############################################################ 36 | 37 | 38 | # 39 | # Default subfolder in letsencrypt 40 | # base folder 41 | # 42 | _DEFAULT_LE_SUBFOLDER="live" 43 | 44 | # 45 | # This is the name of the certificate 46 | # we are looking for. 47 | # 48 | _DEFAULT_CERT_NAME="cert.pem" 49 | 50 | 51 | 52 | 53 | # 54 | # sed is required to extract the command line arguments 55 | # if there are command line arguments. 56 | # 57 | if [ $# -gt 0 ]; then 58 | if ! command -v sed > /dev/null 2>&1 ; then 59 | echo "Binary 'sed' not found but required." 60 | exit 1 61 | fi 62 | fi 63 | 64 | 65 | 66 | ############################################################ 67 | # Command line arguments 68 | ############################################################ 69 | 70 | # 71 | # Get optional command line arguments 72 | # 73 | while [ $# -gt 0 ]; do 74 | 75 | case "$1" in 76 | 77 | --period=*) 78 | MAX_DAYS="$( echo "$1" | sed 's/--period=//g' )" 79 | ;; 80 | 81 | --email=*) 82 | EMAIL="$( echo "$1" | sed 's/--email=//g' )" 83 | ;; 84 | 85 | --path=*) 86 | LETSENCRYPT_PATH="$( echo "$1" | sed 's/--path=//g' )" 87 | ;; 88 | 89 | *) 90 | echo "Invalid argument: '${1}'." 1>&2 91 | echo "Usage: ${0} [--period=30] [--email=user@mail.tld] [--path=/etc/letsencryt]" 1>&2 92 | exit 1 93 | ;; 94 | 95 | esac 96 | shift 97 | done 98 | 99 | 100 | 101 | ############################################################ 102 | # Validate requirements 103 | ############################################################ 104 | 105 | # 106 | # Binaries 107 | # 108 | if ! command -v certwatch > /dev/null 2>&1 ; then 109 | echo "Binary 'certwatch' not found but required." 110 | exit 1 111 | fi 112 | if ! command -v sendmail > /dev/null 2>&1 ; then 113 | echo "Binary 'sendmail' not found but required." 114 | exit 1 115 | fi 116 | if ! command -v find > /dev/null 2>&1 ; then 117 | echo "Binary 'find' not found but required." 118 | exit 1 119 | fi 120 | 121 | # 122 | # Paths 123 | # 124 | if [ ! -d "${LETSENCRYPT_PATH}" ]; then 125 | echo "Letsencrypt path not found in: ${LETSENCRYPT_PATH}" 126 | exit 1 127 | fi 128 | if [ ! -d "${LETSENCRYPT_PATH}/${_DEFAULT_LE_SUBFOLDER}" ]; then 129 | echo "Letsencrypt subfolder path not found in: ${LETSENCRYPT_PATH}/${_DEFAULT_LE_SUBFOLDER}" 130 | exit 1 131 | fi 132 | 133 | # 134 | # Check if there is at least one certificate available 135 | # 136 | CERTIFICATES="$( $(which find) "${LETSENCRYPT_PATH}/${_DEFAULT_LE_SUBFOLDER}" -name "${_DEFAULT_CERT_NAME}" )" 137 | if [ "${CERTIFICATES}" = "" ]; then 138 | echo "No certificates by name '${_DEFAULT_CERT_NAME}' found in Letsencrypt path: ${LETSENCRYPT_PATH}/${_DEFAULT_LE_SUBFOLDER}" 139 | exit 1 140 | fi 141 | 142 | 143 | 144 | ############################################################ 145 | # certwatch function 146 | ############################################################ 147 | 148 | # 149 | # Check certificates 150 | # 151 | watch_letsencrypt_certs() 152 | { 153 | # Build certwatch options 154 | opts="--period ${MAX_DAYS} --address ${EMAIL}" 155 | 156 | # Get full path of binaries 157 | certwatch_bin="$( which certwatch )" 158 | sendmail_bin="$( which sendmail )" 159 | 160 | for c in ${CERTIFICATES}; do 161 | # Check whether a warning message is needed, then issue one if so. 162 | ${certwatch_bin} ${opts} -q "${c}" && 163 | ${certwatch_bin} ${opts} "${c}" | ${sendmail_bin} -oem -oi -t 2>/dev/null 164 | done 165 | } 166 | 167 | watch_letsencrypt_certs 168 | exit 0 --------------------------------------------------------------------------------