Skip to content
Christian edited this page Feb 13, 2018 · 8 revisions

Prerequisites:

  • A working domain name
    • Unfortunately you cannot create a cert using Let's Encrypt for a IP address only: here's why
  • A working Let's Encrypt setup. With certificate generation/renewals provided elsewhere.

Read up on how certificate renewal works and about the pree/post-hooks here: renewing-certificates

Configure sys-API / Dropwizard

First, we'll edit our configuration.yml to add HTTPS and only allow connections to the admin interface over localhost. The <password> here is a generated long password.

Then we need to edit our configuration file to enable HTTPS

server:
  applicationContextPath: /v1
  applicationConnectors:
    - type: http
      port: 8080
    - type: https
      port: 8443
      keyStorePath: ./cert/keystorewww.jks
      keyStorePassword: <password>
      validateCerts: false
      validatePeers: false
  adminConnectors:
    - type: http
      port: 8081
      bindHost: 127.0.0.1

Add certbot deploy hook

Deploy hooks are run only after a full successful renewal process, unlike post hooks who are ran after each and every certificates renewal in the current session.

Create a bash file in /etc/letsencrypt/renewal-hooks/deploy named renewal_post_hook.sh.
as root user:
$ touch /etc/letsencrypt/renewal-hooks/deploy/renewal_post_hook.sh
$ nano /etc/letsencrypt/renewal-hooks/deploy/renewal_post_hook.sh

paste the content below and edit the four variables sys_api_dir, lets_encrypt_cert_dir, password and admin_port according to your environment.

#!/bin/bash
#set -x
# don't use ~ in this file as certbot is most likely ran as root
# if you think there are problems: remove last backslash on line 23 and 33 and the whole lines 34 and 24
# if you want to see what it's doing. Uncomment line 2
# don't put trailing slash in the variables

#i.e sys_api_dir='/home/<user>/sys-api'
sys_api_dir=''
# i.e lets_encrypt_cert='/etc/letsencrypt/live/<mydomain.com>'
lets_encrypt_cert_dir=''
# generated strong password (same as keyStorePassword in configuration.yml)
password=''
# admin port from configuration.yml
admin_port='8081'

rm -fr "$sys_api_dir"/cert/temp
mkdir -p "$sys_api_dir"/cert/temp

openssl pkcs12 -export \
-in "$lets_encrypt_cert_dir"/fullchain.pem \
-inkey "$lets_encrypt_cert_dir"/privkey.pem \
-out "$sys_api_dir"/cert/temp/pkcswww.p12 \
-name cert \
-password pass:"$password" \
2>/dev/null

keytool -deststorepass "$password" \
-importkeystore \
-destkeypass "$password" \
-destkeystore "$sys_api_dir"/cert/temp/keystorewww.jks.new \
-srckeystore "$sys_api_dir"/cert/temp/pkcswww.p12 \
-srcstoretype PKCS12 \
-srcstorepass "$password" \
-alias cert \
2>/dev/null

mv "$sys_api_dir"/cert/temp/keystorewww.jks.new "$sys_api_dir"/cert/keystorewww.jks
rm -r "$sys_api_dir"/cert/temp

CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST http://127.0.0.1:"$admin_port"/tasks/reload-ssl)

if [[ "${CODE}" != "200" ]]; then
  echo "On no did not renew cert!"
fi

Now try to run the script and see if it runs successfully. It should not print any output if it does.

Add cron job

Next we can add a cron job that renews all certs every monday at 02:30 (am).

as super user
$ crontab -e
Then add a new line and paste this:
30 2 * * 1 certbot renew -nq --deploy-hook /etc/letsencrypt/renewal-hooks/deploy/renewal_post_hook.sh

n option means that it will not ask for user input and q means quite everything that's not an error.

All done! You should now be able to use sys-API over HTTPS on port 8443

Most of this guide is based on nbsoftsolutions: Dropwizard 1.1 and lets encrypt with no downtime