5
\$\begingroup\$

This script updates a settings in ssl config file for Nginx. I generate DHEC key and then update the Nginx SSL file to that location. I also give an option for the user through arguments if they want to change the bit size of the key and if they want more conservative or hardened SSL cipher suites.

I don't know how to deal with the long wait on a large key because the user might think the program froze because it takes a long time generate. Its dependent on the environment of course how long you wait. How would you deal with this, through a percentage output? I'm using a spinner at the moment which does the same thing as the 'openssl' command does. So I will probably not use it if I can't find something uses a line or two at most instead of continuous outputting and pushing everything off screen.

#!/bin/bash

source /etc/global.conf # load global vars
source setup/functions.sh #functions

apt_install openssl

nginx_ssl_conf=/etc/nginx/nginx-ssl.conf
DEFAULT_BIT_SIZE=2048 
isHardened="false"
hardened_ciphers="'ECDH+AESGCM256:DH+AESGCM256:ECDH+AES256:SH+AES256:RSA+AESGCM256:RSA+AES256:!aNULL:!MD5:!kEDH';"
hardened_protocol="TLSv1.2;"

DHEC_path=$STORAGE_ROOT/ssl/dhparam.pem

# Functions
update_config() 
{
    lineNUM=$(grep -n "$2" $1 | tail -n1 | sed 's/:.*//')
    [ "$lineNUM" ] || lineNUM="$"
    sed -i -r "$lineNUM s|#?(.*)|#\1\n$4\n$2 $3|" "$1"
} 

ok() 
{ 
    echo -e '\e[32m'$1'\e[m'; 
}

spinner()
{
    local pid=$1
    local delay=0.75
    local spinstr='|/-\'
    while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
        local temp=${spinstr#?}
        printf " [%c]  " "$spinstr"
        local spinstr=$temp${spinstr%"$temp"}
        sleep $delay
        printf "\b\b\b\b\b\b"
    done
    printf "    \b\b\b\b"
}

# Usage info
usage()
{
    cat << EOF
    Usage: ${0##*/} [-h] [-p DIR_DHEC_KEY] [-b BIT_SIZE]  [-c DIR_NGINX_SSL]...
    This script generates and enables DHEC for Nginx.  Defaulted to 2048 key.
    Hardened mode will generate 4096 key and the following cipher suites:
    'ECDH+AESGCM256:DH+AESGCM256:ECDH+AES256:SH+AES256:RSA+AESGCM256:RSA+AES256:!aNULL:!MD5:!kEDH'

    -h          Enable hardened ciphers and 4096 bit key.
    -p          Specify dir to generate the DHEC key.
    -c          Specify dir nginx ssl conf is. 
    -b          Specify the bit size to generate which will override any other default.
EOF
    exit 1
}  

while getopts "hb:c:p:" opt ; do
    case "${opt}" in
        b)
            BIT_SIZE=${OPTARG}
            if [ -z "${OPTARG}" ]; then
               usage
            fi
            ;;
        h)
            isHardened=true
            BIT_SIZE=4096 
            ;;
    p)
            DHEC_path=${OPTARG}
        if [ -z "${OPTARG}" ]; then
               usage
            fi
            ;;
        c)
            nginx_ssl_conf=${OPTARG}
            if [ -z "${OPTARG}" ]; then
               usage
            fi
            ;;
        *)
            usage
            ;;
    esac
done
shift $((OPTIND-1))

if [ -z "${BIT_SIZE}" -a "true" == ${isHardened} ]; then
    BIT_SIZE=4096
elif [ -z "${BIT_SIZE}" ]; then
    BIT_SIZE=$DEFAULT_BIT_SIZE
fi

ok "â¯â¯â¯ Generating DH elliptic curve key.  It might take a while, grab a coffee!"
ok "Seriously, $BIT_SIZE takes forever!"

if [ ! -f $DHEC_path ]; then
  # Generate a 4096 bit random parameter for DH elliptic curves.
  # Generated by OpenSSL with the following command:
  #   openssl dhparam -outform pem -out dhparam.pem 2048
  #   openssl dhparam -outform pem -out dhparam.pem 4096
   ( openssl dhparam -outform pem -out $DHEC_path $BIT_SIZE) &
    spinner $!
fi
        update_config $nginx_ssl_conf ssl_dhparam $DHEC_path';' "#Path to DHEC key"      

if [ $isHardened == "true" ]; then
    update_config $nginx_ssl_conf ssl_ciphers $hardened_ciphers "#Hardened SSL Ciphers DHEC" 
        update_config $nginx_ssl_conf ssl_protocols $hardened_protocol "#Hardened SSL Protocol"  
fi

service nginx reload
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

How would you deal with this, through a percentage output?

I don't know a better way. It seems fine the way you did it, using a spinner.

Quoting

The quoting is unnecessary here:

isHardened="false"

You can safely write this simply as:

isHardened=false

Here, on the other hand, you should quote $1:

lineNUM=$(grep -n "$2" $1 | tail -n1 | sed 's/:.*//')

And you could use sed to include what tail does:

lineNUM=$(grep -n "$2" "$1" | sed -ne '$s/:.*//p')

Prefer [[ ... ]] instead of [ ... ]

[ "$lineNUM" ] || lineNUM="$"

[ ... ] is obsoleted, unless you require POSIX compatibility. Using [[ ... ]] is recommended, and it let's you simplify the quoting:

[[ $lineNUM ]] || lineNUM="$"

Don't use echo for non-trivial things

Avoid using echo with any of it's flags, like -e, because it's not portable. You also don't need the trailing ; here:

echo -e '\e[32m'$1'\e[m'; 

It's better to rewrite using printf:

printf '\e[32m%s\e[m\n' $1

Simplify logic

You evaluate -z "${BIT_SIZE}" twice, unnecessarily:

if [ -z "${BIT_SIZE}" -a "true" == ${isHardened} ]; then
    BIT_SIZE=4096
elif [ -z "${BIT_SIZE}" ]; then
    BIT_SIZE=$DEFAULT_BIT_SIZE
fi

You can simplify the logic, and using [[ ... ]] also helps:

if [[ ! $BIT_SIZE ]]; then
    if [[ $isHardened = true ]]; then
        BIT_SIZE=4096
    else
        BIT_SIZE=$DEFAULT_BIT_SIZE
    fi
fi

Formatting

The formatting is strange here, and it makes your script harder to read:

if [ ! -f $DHEC_path ]; then
  # Generate a 4096 bit random parameter for DH elliptic curves.
  # Generated by OpenSSL with the following command:
  #   openssl dhparam -outform pem -out dhparam.pem 2048
  #   openssl dhparam -outform pem -out dhparam.pem 4096
   ( openssl dhparam -outform pem -out $DHEC_path $BIT_SIZE) &
    spinner $!
fi
        update_config $nginx_ssl_conf ssl_dhparam $DHEC_path';' "#Path to DHEC key"

Write like this instead:

if [[ ! -f $DHEC_path ]]; then
    # Generate a 4096 bit random parameter for DH elliptic curves.
    # Generated by OpenSSL with the following command:
    #   openssl dhparam -outform pem -out dhparam.pem 2048
    #   openssl dhparam -outform pem -out dhparam.pem 4096
    (openssl dhparam -outform pem -out $DHEC_path $BIT_SIZE) &
    spinner $!
fi
update_config $nginx_ssl_conf ssl_dhparam $DHEC_path';' "#Path to DHEC key"      
\$\endgroup\$
1
  • \$\begingroup\$ Thank you for you help. I will look into these recommendations and get back to you shortly. \$\endgroup\$ Commented Sep 24, 2014 at 11:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.