| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 | 
							- #!/bin/bash
 - #
 - # .---.                  .              .
 - # |                      |              |
 - # |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
 - # |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
 - # '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
 - #
 - #                    Freedom in the Cloud
 - #
 - # Create self-signed or Let's Encrypt certificates on Debian
 - 
 - # License
 - # =======
 - #
 - # Copyright (C) 2015-2016 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}-addcert
 - export TEXTDOMAINDIR="/usr/share/locale"
 - 
 - CONFIGURATION_FILE=$HOME/${PROJECT_NAME}.cfg
 - COMPLETION_FILE=$HOME/${PROJECT_NAME}-completed.txt
 - 
 - UTILS_FILES=/usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-*
 - for f in $UTILS_FILES
 - do
 -   source $f
 - done
 - 
 - # Don't pin certs by default
 - PIN_CERTS=
 - 
 - HOSTNAME=
 - remove_cert=
 - LETSENCRYPT_HOSTNAME=
 - COUNTRY_CODE="US"
 - AREA="Apparent Free Speech Zone"
 - LOCATION="Freedomville"
 - ORGANISATION="Freedombone"
 - UNIT="Freedombone Unit"
 - EXTENSIONS=""
 - NODH=
 - DH_KEYLENGTH=2048
 - INSTALL_DIR=/root/build
 - LETSENCRYPT_SERVER='https://acme-v01.api.letsencrypt.org/directory'
 - MY_EMAIL_ADDRESS=
 - 
 - function show_help {
 -     echo ''
 -     echo $"${PROJECT_NAME}-addcert -h [hostname] -c [country code] -a [area] -l [location]"
 -     echo $'                    -o [organisation] -u [unit] --ca "" --nodh ""'
 -     echo ''
 -     echo $'Creates a self-signed certificate for the given hostname'
 -     echo ''
 -     echo $'     --help                     Show help'
 -     echo $'  -h --hostname [name]          Hostname'
 -     echo $'  -e --letsencrypt [hostname]   Hostname to use with Lets Encrypt'
 -     echo $'  -r --rmletsencrypt [hostname] Remove a Lets Encrypt certificate'
 -     echo $'  -s --server [url]             Lets Encrypt server URL'
 -     echo $'  -c --country [code]           Optional country code (eg. US, GB, etc)'
 -     echo $'  -a --area [description]       Optional area description'
 -     echo $'  -l --location [locn]          Optional location name'
 -     echo $'  -o --organisation [name]      Optional organisation name'
 -     echo $'  -u --unit [name]              Optional unit name'
 -     echo $'     --email [address]          Email address for letsencrypt'
 -     echo $'     --dhkey [bits]             DH key length in bits'
 -     echo $'     --nodh ""                  Do not calculate DH params'
 -     echo $'     --ca ""                    Certificate authority cert'
 -     echo ''
 -     exit 0
 - }
 - 
 - while [[ $# > 1 ]]
 - do
 -     key="$1"
 - 
 -     case $key in
 -         --help)
 -             show_help
 -             ;;
 -         -h|--hostname)
 -             shift
 -             HOSTNAME="$1"
 -             ;;
 -         -e|--letsencrypt)
 -             shift
 -             LETSENCRYPT_HOSTNAME="$1"
 -             ;;
 -         -r|--rmletsencrypt)
 -             shift
 -             LETSENCRYPT_HOSTNAME="$1"
 -             remove_cert=1
 -             ;;
 -         --email)
 -             shift
 -             MY_EMAIL_ADDRESS="$1"
 -             ;;
 -         -s|--server)
 -             shift
 -             LETSENCRYPT_SERVER="$1"
 -             ;;
 -         -c|--country)
 -             shift
 -             COUNTRY_CODE="$1"
 -             ;;
 -         -a|--area)
 -             shift
 -             AREA="$1"
 -             ;;
 -         -l|--location)
 -             shift
 -             LOCATION="$1"
 -             ;;
 -         -o|--organisation)
 -             shift
 -             ORGANISATION="$1"
 -             ;;
 -         -u|--unit)
 -             shift
 -             UNIT="$1"
 -             ;;
 -         --ca)
 -             shift
 -             EXTENSIONS="-extensions v3_ca"
 -             ORGANISATION="Freedombone-CA"
 -             ;;
 -         --nodh)
 -             shift
 -             NODH="true"
 -             ;;
 -         --dhkey)
 -             shift
 -             DH_KEYLENGTH=${1}
 -             ;;
 -         --pin)
 -             shift
 -             PIN_CERTS=${1}
 -             ;;
 -         *)
 -             # unknown option
 -             ;;
 -     esac
 -     shift
 - done
 - 
 - if [ ! $HOSTNAME ]; then
 -     if [ ! $LETSENCRYPT_HOSTNAME ]; then
 -         echo $'No hostname specified'
 -         exit 5748
 -     fi
 - fi
 - 
 - if ! which openssl > /dev/null ;then
 -     echo $"$0: openssl is not installed, exiting" 1>&2
 -     exit 5689
 - fi
 - 
 - if [ ! -d /etc/ssl/mycerts ]; then
 -     mkdir /etc/ssl/mycerts
 - fi
 - 
 - CERTFILE=$HOSTNAME
 - 
 - function remove_cert_letsencrypt {
 -     CERTFILE=$LETSENCRYPT_HOSTNAME
 - 
 -     # disable the site if needed
 -     if [ -f /etc/nginx/sites-available/${LETSENCRYPT_HOSTNAME} ]; then
 -         if grep -q "443" /etc/nginx/sites-available/${LETSENCRYPT_HOSTNAME}; then
 -             nginx_dissite ${LETSENCRYPT_HOSTNAME}
 -         fi
 -     fi
 - 
 -     # remove the cert
 -     rm -rf /etc/letsencrypt/live/${LETSENCRYPT_HOSTNAME}*
 -     rm -rf /etc/letsencrypt/archive/${LETSENCRYPT_HOSTNAME}*
 -     rm /etc/letsencrypt/renewal/${LETSENCRYPT_HOSTNAME}.conf
 - 
 -     # restart the web server
 -     systemctl restart nginx
 - }
 - 
 - function add_cert_letsencrypt {
 -     CERTFILE=$LETSENCRYPT_HOSTNAME
 - 
 -     # obtain the email address for the admin user
 -     if [ ! $MY_EMAIL_ADDRESS ]; then
 -         if [ -f $CONFIGURATION_FILE ]; then
 -             read_config_param MY_EMAIL_ADDRESS
 -         fi
 -     fi
 -     if [ ! $MY_EMAIL_ADDRESS ]; then
 -         if [ -f $COMPLETION_FILE ]; then
 -             if grep -q "Admin user:" $COMPLETION_FILE; then
 -                 function_check get_completion_param
 -                 ADMIN_USER=$(get_completion_param "Admin user")
 -                 if [ ${#ADMIN_USER} -eq 0 ]; then
 -                     exit 463732
 -                 fi
 -                 MY_EMAIL_ADDRESS=$ADMIN_USER@$HOSTNAME
 -             fi
 -         fi
 -     fi
 - 
 -     if [ ! -f /usr/bin/certbot ]; then
 -         apt-get -yq -t stretch-backports install certbot
 -         groupadd ssl-cert
 -         if [ ! -f /usr/bin/certbot ]; then
 -             echo $'LetsEncrypt certbot failed to install'
 -             exit 762830
 -         fi
 -     fi
 - 
 -     # stop the web server
 -     systemctl stop nginx
 - 
 -     chgrp -R root /etc/letsencrypt
 -     chmod -R 777 /etc/letsencrypt
 - 
 -     certbot certonly -n --server $LETSENCRYPT_SERVER --standalone -d $LETSENCRYPT_HOSTNAME --renew-by-default --agree-tos --email $MY_EMAIL_ADDRESS
 -     if [ ! "$?" = "0" ]; then
 -         echo $"Failed to install letsencrypt for domain $LETSENCRYPT_HOSTNAME"
 -         echo $'Also see https://letsencrypt.status.io to check for any service outages'
 -         chgrp -R ssl-cert /etc/letsencrypt
 -         chmod -R 600 /etc/letsencrypt
 -         chmod -R g=rX /etc/letsencrypt
 -         chown -R root:ssl-cert /etc/letsencrypt
 -         systemctl start nginx
 -         exit 63216
 -     fi
 - 
 -     # replace some legacy filenames
 -     if [ -f /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.bundle.crt ]; then
 -         mv /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.bundle.crt /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.pem
 -     fi
 -     if [ -f /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.crt ]; then
 -         mv /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.crt /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.pem
 -     fi
 -     sed -i "s|ssl_certificate /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.bundle.crt|ssl_certificate /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.pem|g" /etc/nginx/sites-available/$LETSENCRYPT_HOSTNAME
 -     sed -i "s|ssl_certificate /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.crt|ssl_certificate /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.pem|g" /etc/nginx/sites-available/$LETSENCRYPT_HOSTNAME
 - 
 -     # link the private key
 -     if [ -f /etc/ssl/private/${LETSENCRYPT_HOSTNAME}.key ]; then
 -         if [ ! -f /etc/ssl/private/${LETSENCRYPT_HOSTNAME}.key.old ]; then
 -             mv /etc/ssl/private/${LETSENCRYPT_HOSTNAME}.key /etc/ssl/private/${LETSENCRYPT_HOSTNAME}.key.old
 -         else
 -             rm -f /etc/ssl/private/${LETSENCRYPT_HOSTNAME}.key
 -         fi
 -     fi
 -     if [ -L /etc/ssl/private/${LETSENCRYPT_HOSTNAME}.key ]; then
 -         rm /etc/ssl/private/${LETSENCRYPT_HOSTNAME}.key
 -     fi
 -     ln -s /etc/letsencrypt/live/${LETSENCRYPT_HOSTNAME}/privkey.pem /etc/ssl/private/${LETSENCRYPT_HOSTNAME}.key
 - 
 -     # link the public key
 -     if [ -f /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.pem ]; then
 -         if [ ! -f /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.pem.old ]; then
 -             mv /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.pem /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.pem.old
 -         else
 -             rm -f /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.pem
 -         fi
 -     fi
 -     if [ -L /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.pem ]; then
 -         rm /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.pem
 -     fi
 -     ln -s /etc/letsencrypt/live/${LETSENCRYPT_HOSTNAME}/fullchain.pem /etc/ssl/certs/${LETSENCRYPT_HOSTNAME}.pem
 - 
 -     cp /etc/letsencrypt/live/${LETSENCRYPT_HOSTNAME}/fullchain.pem /etc/ssl/mycerts/${LETSENCRYPT_HOSTNAME}.pem
 - 
 -     update_default_domain
 - 
 -     # this group can be used to assign read permissions for
 -     # application user accounts
 -     chgrp -R ssl-cert /etc/letsencrypt
 -     chmod -R 600 /etc/letsencrypt
 -     chmod -R g=rX /etc/letsencrypt
 -     chown -R root:ssl-cert /etc/letsencrypt
 - 
 -     nginx_ensite ${LETSENCRYPT_HOSTNAME}
 -     systemctl start nginx
 - 
 -     if [ $PIN_CERTS ]; then
 -         ${PROJECT_NAME}-pin-cert $LETSENCRYPT_HOSTNAME
 -         if [ ! "$?" = "0" ]; then
 -             echo $"Certificate for $LETSENCRYPT_HOSTNAME could not be pinned"
 -             exit 62878
 -         fi
 -     fi
 - }
 - 
 - function add_cert_selfsigned {
 -     if [[ $ORGANISATION == "Freedombone-CA" ]]; then
 -         CERTFILE="ca-$HOSTNAME"
 -     fi
 - 
 -     openssl req -x509 ${EXTENSIONS} -nodes -days 3650 -sha256 \
 -             -subj "/O=$ORGANISATION/OU=$UNIT/C=$COUNTRY_CODE/ST=$AREA/L=$LOCATION/CN=$HOSTNAME" \
 -             -newkey rsa:2048 -keyout /etc/ssl/private/${CERTFILE}.key \
 -             -out /etc/ssl/certs/${CERTFILE}.crt
 -     chmod 400 /etc/ssl/private/${CERTFILE}.key
 -     chmod 640 /etc/ssl/certs/${CERTFILE}.crt
 -     cp /etc/ssl/certs/${CERTFILE}.crt /etc/ssl/mycerts
 - 
 -     if [ $PIN_CERTS ]; then
 -         ${PROJECT_NAME}-pin-cert $CERTFILE
 -         if [ ! "$?" = "0" ]; then
 -             echo $"Certificate for $CERTFILE could not be pinned"
 -             exit 62879
 -         fi
 -     fi
 - }
 - 
 - function generate_dh_params {
 -     if [ ! $NODH ]; then
 -         if [ ! -f /etc/ssl/certs/${CERTFILE}.dhparam ]; then
 -             ${PROJECT_NAME}-dhparam -h ${CERTFILE} --fast yes
 -         fi
 -     fi
 - }
 - 
 - function restart_web_server {
 -     if [ -f /etc/init.d/nginx ]; then
 -         /etc/init.d/nginx reload
 -     fi
 - }
 - 
 - function make_cert_bundle {
 -     # Create a bundle of your certificates
 -     cat /etc/ssl/mycerts/*.crt /etc/ssl/mycerts/*.pem > /etc/ssl/${PROJECT_NAME}-bundle.crt
 -     tar -czvf /etc/ssl/${PROJECT_NAME}-certs.tar.gz /etc/ssl/mycerts/*.crt /etc/ssl/mycerts/*.pem
 - }
 - 
 - function create_cert {
 -     if [ $remove_cert ]; then
 -         remove_cert_letsencrypt
 -         return
 -     fi
 - 
 -     if [ $LETSENCRYPT_HOSTNAME ]; then
 -         add_cert_letsencrypt
 -     else
 -         add_cert_selfsigned
 -     fi
 - }
 - 
 - create_cert
 - generate_dh_params
 - restart_web_server
 - make_cert_bundle
 - 
 - exit 0
 
 
  |