diff --git a/Dockerfile b/Dockerfile index 228254f..786db25 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,9 +9,8 @@ RUN apt-get update \ && apt-get clean \ && rm -r /var/lib/apt/lists/* -# Generate dhparam.pem, configure nginx -RUN openssl dhparam -out /etc/nginx/dhparam.pem 2048 \ - && echo "daemon off;" >> /etc/nginx/nginx.conf +# Configure nginx +RUN echo "daemon off;" >> /etc/nginx/nginx.conf # Install Forego ADD https://github.com/jwilder/forego/releases/download/v0.16.1/forego /usr/local/bin/forego @@ -28,7 +27,7 @@ WORKDIR /app/ ENV DOCKER_HOST unix:///tmp/docker.sock -VOLUME ["/etc/nginx/certs"] +VOLUME ["/etc/nginx/certs", "/etc/nginx/dhparam"] ENTRYPOINT ["/app/docker-entrypoint.sh"] CMD ["forego", "start", "-r"] diff --git a/dhparam.pem.default b/dhparam.pem.default new file mode 100644 index 0000000..8548c34 --- /dev/null +++ b/dhparam.pem.default @@ -0,0 +1,8 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEAzB2nIGzpVq7afJnKBm1X0d64avwOlP2oneiKwxRHdDI/5+6TpH1P +F8ipodGuZBUMmupoB3D34pu2Qq5boNW983sm18ww9LMz2i/pxhSdB+mYAew+A6h6 +ltQ5pNtyn4NaKw1SDFkqvde3GNPhaWoPDbZDJhpHGblR3w1b/ag+lTLZUvVwcD8L +jYS9f9YWAC6T7WxAxh4zvu1Z0I1EKde8KYBxrreZNheXpXHqMNyJYZCaY2Hb/4oI +EL65qZq1GCWezpWMjhk6pOnV5gbvqfhoazCv/4OdRv6RoWOIYBNs9BmGho4AtXqV +FYLdYDhOvN4aVs9Ir+G8ouwiRnix24+UewIBAg== +-----END DH PARAMETERS----- diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 6353314..f43a127 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -2,7 +2,7 @@ set -e # Warn if the DOCKER_HOST socket does not exist -if [[ $DOCKER_HOST == unix://* ]]; then +if [[ $DOCKER_HOST = unix://* ]]; then socket_file=${DOCKER_HOST#unix://} if ! [ -S $socket_file ]; then cat >&2 <<-EOT @@ -14,6 +14,9 @@ if [[ $DOCKER_HOST == unix://* ]]; then fi fi +# Generate dhparam file if required +/app/generate-dhparam.sh + # If the user has run the default command and the socket doesn't exist, fail if [ "$socketMissing" = 1 -a "$1" = forego -a "$2" = start -a "$3" = '-r' ]; then exit 1 diff --git a/generate-dhparam.sh b/generate-dhparam.sh new file mode 100755 index 0000000..ed010b7 --- /dev/null +++ b/generate-dhparam.sh @@ -0,0 +1,42 @@ +#!/bin/bash -e + +# If a dhparam file is not available, use the pre-generated one and generate a new one in the background. +# Note that /etc/nginx/dhparam is a volume, so this dhparam will persist restarts. +PREGEN_DHPARAM_FILE="/app/dhparam.pem.default" +DHPARAM_FILE="/etc/nginx/dhparam/dhparam.pem" +DHPARAM_BITS="2048" +GEN_LOCKFILE="/tmp/dhparam_generating.lock" + +# The hash of the pregenerated dhparam file is used to check if the pregen dhparam is already in use +PREGEN_HASH=$(md5sum $PREGEN_DHPARAM_FILE | cut -d" " -f1) +if [[ -f $DHPARAM_FILE ]]; then + CURRENT_HASH=$(md5sum $DHPARAM_FILE | cut -d" " -f1) + if [[ $PREGEN_HASH != $CURRENT_HASH ]]; then + # There is already a dhparam, and it's not the default + exit 0 + fi + + if [[ -f $GEN_LOCKFILE ]]; then + # Generation is already in progress + exit 0 + fi +fi + +cat >&2 <<-EOT +WARNING: $DHPARAM_FILE was not found. A pregenerated dhparam.pem will be used for now while a new one +is being generated in the background. Once the new dhparam.pem is in place, nginx will be reloaded. +EOT + +# Put the default dhparam file in place so we can start immediately +cp $PREGEN_DHPARAM_FILE $DHPARAM_FILE +touch $GEN_LOCKFILE + +# Generate a new dhparam in the background in a low priority and reload nginx when finished (grep removes the progress indicator). +( + ( + nice -n +5 openssl dhparam -out $DHPARAM_FILE $DHPARAM_BITS 2>&1 \ + && echo "dhparam generation complete, reloading nginx" \ + && nginx -s reload + ) | grep -vE '^[\.+]+' + rm $GEN_LOCKFILE +) & diff --git a/nginx.tmpl b/nginx.tmpl index b99fa23..4f39ab2 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -42,7 +42,7 @@ map $http_upgrade $proxy_connection { server_names_hash_bucket_size 128; # Default dhparam -ssl_dhparam /etc/nginx/dhparam.pem; +ssl_dhparam /etc/nginx/dhparam/dhparam.pem; # Set appropriate X-Forwarded-Ssl header map $scheme $proxy_x_forwarded_ssl {