123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- #!/bin/bash
- # _____ _ _
- # | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
- # | __| _| -_| -_| . | . | | . | . | | -_|
- # |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
- #
- # Freedom in the Cloud
- #
- # A script for renewing SSL/TLS certificates
- #
- # License
- # =======
- #
- # Copyright (C) 2015-2018 Bob Mottram <bob@freedombone.net>
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU Affero General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU Affero General Public License for more details.
- #
- # You should have received a copy of the GNU Affero General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- PROJECT_NAME='freedombone'
-
- export TEXTDOMAIN=${PROJECT_NAME}-renew-cert
- export TEXTDOMAINDIR="/usr/share/locale"
-
- HOSTNAME=
- PROVIDER='startssl'
- DH_KEYLENGTH=2048
- LETSENCRYPT_SERVER='https://acme-v01.api.letsencrypt.org/directory'
- INSTALL_DIR=/root/build
-
- function show_help {
- echo ''
- echo $"${PROJECT_NAME}-renew-cert -h [hostname] -p [provider]"
- echo ''
- echo $'Makes it easier to renew a ssl/tls certificate for a website'
- echo ''
- echo $' --help Show help'
- echo $' -h --hostname [name] Hostname'
- echo $' -p --provider [name] eg. startssl/letsencrypt'
- echo ''
- exit 0
- }
-
- function renew_letsencrypt {
- if [ ! -f /etc/letsencrypt/live/${HOSTNAME}/fullchain.pem ]; then
- echo $"Adding Let's Encrypt certificate"
- else
- echo $"Renewing Let's Encrypt certificate"
- fi
-
- if ! ${PROJECT_NAME}-addcert -e $HOSTNAME -s $LETSENCRYPT_SERVER --dhkey $DH_KEYLENGTH; then
- echo $"Unable to add Let's encrypt certificate"
- exit 6328
- fi
-
- # Ensure that links are in place
- ln -s /etc/letsencrypt/live/${HOSTNAME}/privkey.pem /etc/ssl/private/${HOSTNAME}.key
- ln -s /etc/letsencrypt/live/${HOSTNAME}/fullchain.pem /etc/ssl/certs/${HOSTNAME}.pem
-
- ${PROJECT_NAME}-pin-cert $HOSTNAME remove
- }
-
- function renew_startssl {
- echo $'Renewing StartSSL certificate'
- if [ -s /etc/ssl/certs/$HOSTNAME.new.crt ]; then
- if ! grep -q "-BEGIN CERTIFICATE-" /etc/ssl/certs/$HOSTNAME.new.crt; then
- echo $'/etc/ssl/certs/$HOSTNAME.new.crt does not contain a public key'
- return
- fi
-
- cp /etc/ssl/certs/$HOSTNAME.new.crt /etc/ssl/certs/$HOSTNAME.crt
-
- if [ ! -d /etc/ssl/roots ]; then
- mkdir /etc/ssl/roots
- fi
- if [ ! -d /etc/ssl/chains ]; then
- mkdir /etc/ssl/chains
- fi
-
- # download intermediate certs
- wget "http://www.startssl.com/certs/ca.pem" --output-document="/etc/ssl/roots/startssl-root.ca"
- wget "http://www.startssl.com/certs/sub.class1.server.ca.pem" --output-document="/etc/ssl/chains/startssl-sub.class1.server.ca.pem"
- wget "http://www.startssl.com/certs/sub.class2.server.ca.pem" --output-document="/etc/ssl/chains/startssl-sub.class2.server.ca.pem"
- wget "http://www.startssl.com/certs/sub.class3.server.ca.pem" --output-document="/etc/ssl/chains/startssl-sub.class3.server.ca.pem"
- ln -s "/etc/ssl/roots/startssl-root.ca" "/etc/ssl/roots/$HOSTNAME-root.ca"
- ln -s "/etc/ssl/chains/startssl-sub.class1.server.ca.pem" "/etc/ssl/chains/$HOSTNAME.ca"
- cp "/etc/ssl/certs/$HOSTNAME.crt" "/etc/ssl/certs/$HOSTNAME.crt+chain+root"
- test -e "/etc/ssl/chains/$HOSTNAME.ca" && cat "/etc/ssl/chains/$HOSTNAME.ca" >> "/etc/ssl/certs/$HOSTNAME.crt+chain+root"
- test -e "/etc/ssl/roots/$HOSTNAME-root.ca" && cat "/etc/ssl/roots/$HOSTNAME-root.ca" >> "/etc/ssl/certs/$HOSTNAME.crt+chain+root"
-
- # remove the password from the private cert
- openssl rsa -in /etc/ssl/private/$HOSTNAME.key -out /etc/ssl/private/$HOSTNAME.new.key
- cp /etc/ssl/private/$HOSTNAME.new.key /etc/ssl/private/$HOSTNAME.key
- shred -zu /etc/ssl/private/$HOSTNAME.new.key
-
- # bundle the cert
- cat /etc/ssl/certs/$HOSTNAME.crt /etc/ssl/chains/startssl-sub.class1.server.ca.pem > /etc/ssl/certs/$HOSTNAME.bundle.crt
-
- # add it to mycerts
- cp /etc/ssl/certs/$HOSTNAME.bundle.crt /etc/ssl/mycerts
- cat /etc/ssl/mycerts/*.crt > /etc/ssl/${PROJECT_NAME}-bundle.crt
- tar -czvf /etc/ssl/${PROJECT_NAME}-certs.tar.gz /etc/ssl/mycerts/*.crt
-
- # create backups
- if [ ! -d /etc/ssl/backups ]; then
- mkdir /etc/ssl/backups
- fi
- if [ ! -d /etc/ssl/backups/certs ]; then
- mkdir /etc/ssl/backups/certs
- fi
- if [ ! -d /etc/ssl/backups/private ]; then
- mkdir /etc/ssl/backups/private
- fi
- cp /etc/ssl/certs/$HOSTNAME* /etc/ssl/backups/certs/
- cp /etc/ssl/private/$HOSTNAME* /etc/ssl/backups/private/
- chmod -R 400 /etc/ssl/backups/certs/*
- chmod -R 400 /etc/ssl/backups/private/*
-
- rm /etc/ssl/certs/$HOSTNAME.new.crt
- rm /etc/ssl/requests/$HOSTNAME.csr
-
- # update your site to include the bundle
- sed -i "s|$HOSTNAME.crt|$HOSTNAME.bundle.crt|g" /etc/nginx/sites-available/$HOSTNAME
-
- echo $'Certificate installed'
- systemctl restart nginx
- return
- fi
-
- if [ -f /etc/ssl/requests/$HOSTNAME.csr ]; then
- echo $'Certificate request already created:'
- echo ''
- cat /etc/ssl/requests/$HOSTNAME.csr
- echo ''
- echo $"Save the requested public key to /etc/ssl/certs/$HOSTNAME.new.crt"
- echo $'then run this command again.'
- echo ''
- return
- fi
- openssl genrsa -out /etc/ssl/private/$HOSTNAME.new.key 2048
- chown root:ssl-cert /etc/ssl/private/$HOSTNAME.new.key
- chmod 440 /etc/ssl/private/$HOSTNAME.new.key
- if [ ! -d /etc/ssl/requests ]; then
- mkdir /etc/ssl/requests
- fi
- openssl req -new -sha256 -key /etc/ssl/private/$HOSTNAME.new.key -out /etc/ssl/requests/$HOSTNAME.csr
- echo ''
- cat /etc/ssl/requests/$HOSTNAME.csr
- echo ''
- echo $'On the StartSSL site select Certificates Wizard then'
- echo $'Web server SSL/TLS Certificate. You can then click on "skip"'
- echo $'and then copy and paste the above certificate request into the text'
- echo $'entry box. You may now need to wait a few hours for a confirmation'
- echo $'email indicating that the new certificate was created.'
- echo ''
- echo $'Once you have retrieved the new public certificate paste it to:'
- echo $"/etc/ssl/certs/$HOSTNAME.new.crt then run this command again."
- echo ''
-
- ${PROJECT_NAME}-pin-cert $HOSTNAME remove
- }
-
- while [ $# -gt 1 ]
- do
- key="$1"
-
- case $key in
- --help)
- show_help
- ;;
- -h|--hostname)
- shift
- HOSTNAME="$1"
- ;;
- -p|--provider)
- shift
- PROVIDER="$1"
- ;;
- *)
- # unknown option
- ;;
- esac
- shift
- done
-
- if [ ! "$HOSTNAME" ]; then
- echo $'No hostname specified'
- exit 5748
- fi
-
- if ! which openssl > /dev/null ;then
- echo $"$0: openssl is not installed, exiting" 1>&2
- exit 5689
- fi
-
- # check that the web site exists
- if [ ! -f "/etc/nginx/sites-available/$HOSTNAME" ]; then
- echo $"/etc/nginx/sites-available/$HOSTNAME does not exist"
- exit 7598
- fi
-
- if [[ $PROVIDER == 'startssl' || $PROVIDER == 'StartSSL' ]]; then
- renew_startssl
- else
- if [[ $PROVIDER == 'letsencrypt' ]]; then
- renew_letsencrypt
- else
- echo $"$PROVIDER is not currently supported"
- fi
- fi
-
- exit 0
|