Просмотр исходного кода

Implemented background dhparam generation

Steve Kamerman 8 лет назад
Родитель
Сommit
dfdd67f5a4
5 измененных файлов с 58 добавлено и 6 удалено
  1. 3 4
      Dockerfile
  2. 8 0
      dhparam.pem.default
  3. 4 1
      docker-entrypoint.sh
  4. 42 0
      generate-dhparam.sh
  5. 1 1
      nginx.tmpl

+ 3 - 4
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"]

+ 8 - 0
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-----

+ 4 - 1
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

+ 42 - 0
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
+) &

+ 1 - 1
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 {