new certificate
/usr/bin/certbot --nginx certonly -d yourdomain.com --deploy-hook /usr/local/sbin/push_to_confiared.sh
add new for nginx
ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers         HIGH:!aNULL:!MD5;
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate      /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key  /etc/letsencrypt/live/yourdomain.com/privkey.pem;
renew for apache
/usr/bin/certbot --apache renew --deploy-hook /usr/local/sbin/push_to_confiared.sh --post-hook "/etc/init.d/apache2 reload"
renew for nginx
/usr/bin/certbot --nginx renew --deploy-hook /usr/local/sbin/push_to_confiared.sh
--post-hook "/etc/init.d/nginx reload"
/usr/local/sbin/push_to_confiared.sh to push for IPv4 reverse proxy
#!/bin/bash
#RENEWED_LINEAGE=/etc/letsencrypt/live/site.com
# Pushes a renewed certificate to the Confiared reverse-proxy, so the edges that terminate
# IPv4 stop serving the previous one. Called by certbot as renew_hook/deploy_hook.
# --insecure is deliberate: this can run while the certificate of api.confiared.com itself
# is the one being repaired.

if [ ! -f "${RENEWED_LINEAGE}/cert.pem" ]
then
  echo "${RENEWED_LINEAGE}/cert.pem was not found, abort" > /var/log/last_letsencrypt_confiared_api.log
  echo "${RENEWED_LINEAGE}/cert.pem was not found, abort" >> /var/log/last_letsencrypt_confiared_api.err
  exit 255
fi

# The api answers 400 + a json explaining why when it refuses a certificate. curl exits 0 on
# a 400, so testing $? alone reports success for a certificate that was in fact rejected: that
# is how a stale certificate stayed on the edges until it expired. Test the http code instead.
# Not -f: -f would throw away the json body, which is the only place the reason is written.
#
# The class of the code is what says whether retrying can ever help:
#   200   accepted, nothing more to do
#   4xx   the api understood the request and refused it. The refusal only depends on the three
#         files posted (expired, self signed, private key not matching the certificate...), so
#         posting the same three again can only be refused again. Retrying anyway is what turned
#         a single expired lineage into 100 refusals a day for three months: 06:09 to 22:39 every
#         day, which is exactly 1 push plus 99 sleeps of 600s.
#   other 000 when curl could not reach the api at all, or a 5xx: that one can heal by itself.
push()
{
  local code
  code=$(/usr/bin/curl --insecure --silent --max-time 120 -w '%{http_code}' \
    --data-urlencode "certificate=$(cat ${RENEWED_LINEAGE}/cert.pem)" \
    --data-urlencode "chain=$(cat ${RENEWED_LINEAGE}/chain.pem)" \
    --data-urlencode "privatekey=$(cat ${RENEWED_LINEAGE}/privkey.pem)" \
    https://api.confiared.com/reverse-proxy/upload-certificate \
    -o /var/log/last_letsencrypt_confiared_api.log)
  case "$code" in
    200)
      return 0
      ;;
    4??)
      # said at the first attempt and not 16h later, and the reason is copied here because the
      # .log above is overwritten by the next certificate this host pushes
      echo "`date -Is` ${RENEWED_LINEAGE} refused with http ${code}, nothing to retry: $(head -c 300 /var/log/last_letsencrypt_confiared_api.log | tr '\n' ' ')" >> /var/log/last_letsencrypt_confiared_api.err
      return 2
      ;;
    *)
      return 1
      ;;
  esac
}

push
case $? in
  0) exit 0;;
  2) exit 1;;
esac

# The api did not answer, or answered 5xx. Only that is worth retrying, for ~16h.
for i in {1..99}
do
  sleep 600
  push
  case $? in
    0) exit 0;;
    2) exit 1;;
  esac
done

echo "`date -Is` ${RENEWED_LINEAGE} still not pushed after 99 tries, see /var/log/last_letsencrypt_confiared_api.log" >> /var/log/last_letsencrypt_confiared_api.err
exit 1
cron
0 3 * * * sleep ${RANDOM:0:3}m;[ `ps aux | grep nginx | grep -v -F grep | wc -l` -gt 0 ] && /usr/bin/certbot --nginx renew --deploy-hook /usr/local/sbin/push_to_confiared.sh --post-hook "/etc/init.d/nginx reload" > /var/log/letsencrypt.log 2>&1
0 3 * * * sleep ${RANDOM:0:3}m;[ `ps aux | grep apache2 | grep -v -F grep | wc -l` -gt 0 ] && /usr/bin/certbot --apache renew --deploy-hook /usr/local/sbin/push_to_confiared.sh --post-hook "/etc/init.d/apache2 reload" > /var/log/letsencrypt.log 2>&1