Skip to content

Commit 44bd2fa

Browse files
authored
Merge pull request #904 from nginx-proxy/dhparam-rfc7919
Use RFC 7919 DH groups + Remove DH generation
2 parents 57108ba + 9b935a0 commit 44bd2fa

File tree

10 files changed

+87
-53
lines changed

10 files changed

+87
-53
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ It handles the automated creation, renewal and use of SSL certificates for proxi
1515
* Let's Encrypt / ACME domain validation through `http-01` challenge only.
1616
* Automated update and reload of nginx config on certificate creation/renewal.
1717
* Support creation of [Multi-Domain (SAN) Certificates](https://github.com/nginx-proxy/acme-companion/blob/main/docs/Let's-Encrypt-and-ACME.md#multi-domains-certificates).
18-
* Creation of a Strong Diffie-Hellman Group at startup.
18+
* Creation of a strong [RFC7919 Diffie-Hellman Group](https://datatracker.ietf.org/doc/html/rfc7919#appendix-A) at startup.
1919
* Work with all versions of docker.
2020

2121
### Requirements:

app/dhparam/ffdhe2048.pem

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-----BEGIN DH PARAMETERS-----
2+
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
3+
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
4+
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
5+
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
6+
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
7+
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
8+
-----END DH PARAMETERS-----

app/dhparam/ffdhe3072.pem

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-----BEGIN DH PARAMETERS-----
2+
MIIBiAKCAYEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
3+
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
4+
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
5+
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
6+
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
7+
ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3
8+
7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32
9+
nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZsYu
10+
N///////////AgEC
11+
-----END DH PARAMETERS-----
File renamed without changes.

app/entrypoint.sh

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -45,56 +45,63 @@ function check_writable_directory {
4545
}
4646

4747
function check_dh_group {
48-
# Credits to Steve Kamerman for the background Diffie-Hellman creation logic.
49-
# https://github.com/nginx-proxy/nginx-proxy/pull/589
50-
local DHPARAM_BITS="${DHPARAM_BITS:-2048}"
51-
re='^[0-9]*$'
52-
if ! [[ "$DHPARAM_BITS" =~ $re ]] ; then
53-
echo "Error: invalid Diffie-Hellman size of $DHPARAM_BITS !" >&2
54-
exit 1
48+
# DH params will be supplied for acme-companion here:
49+
local DHPARAM_FILE='/etc/nginx/certs/dhparam.pem'
50+
51+
# Should be 2048, 3072, or 4096 (default):
52+
local DHPARAM_BITS="${DHPARAM_BITS:=4096}"
53+
54+
# Skip generation if DHPARAM_SKIP is set to true
55+
if parse_true "${DHPARAM_SKIP:=false}"; then
56+
echo "Info: Skipping Diffie-Hellman group setup."
57+
return 0
5558
fi
5659

57-
# If a dhparam file is not available, use the pre-generated one and generate a new one in the background.
58-
local PREGEN_DHPARAM_FILE="/app/dhparam.pem.default"
59-
local DHPARAM_FILE="/etc/nginx/certs/dhparam.pem"
60-
local GEN_LOCKFILE="/tmp/le_companion_dhparam_generating.lock"
61-
62-
# The hash of the pregenerated dhparam file is used to check if the pregen dhparam is already in use
63-
local PREGEN_HASH; PREGEN_HASH=$(sha256sum "$PREGEN_DHPARAM_FILE" | cut -d ' ' -f1)
64-
if [[ -f "$DHPARAM_FILE" ]]; then
65-
local CURRENT_HASH; CURRENT_HASH=$(sha256sum "$DHPARAM_FILE" | cut -d ' ' -f1)
66-
if [[ "$PREGEN_HASH" != "$CURRENT_HASH" ]]; then
67-
# There is already a dhparam, and it's not the default
68-
set_ownership_and_permissions "$DHPARAM_FILE"
69-
echo "Info: Custom Diffie-Hellman group found, generation skipped."
70-
return 0
71-
fi
60+
# Let's check DHPARAM_BITS is set to a supported value
61+
if [[ ! "$DHPARAM_BITS" =~ ^(2048|3072|4096)$ ]]; then
62+
echo "Error: Unsupported DHPARAM_BITS size: ${DHPARAM_BITS}. Supported values are 2048, 3072, or 4096 (default)." >&2
63+
exit 1
64+
fi
7265

73-
if [[ -f "$GEN_LOCKFILE" ]]; then
74-
# Generation is already in progress
66+
# Use an existing pre-generated DH group from RFC7919 (https://datatracker.ietf.org/doc/html/rfc7919#appendix-A):
67+
local RFC7919_DHPARAM_FILE="/app/dhparam/ffdhe${DHPARAM_BITS}.pem"
68+
local EXPECTED_DHPARAM_HASH; EXPECTED_DHPARAM_HASH=$(sha256sum "$RFC7919_DHPARAM_FILE" | cut -d ' ' -f1)
69+
70+
# DH params may be provided by the user (rarely necessary)
71+
if [[ -f "$DHPARAM_FILE" ]]; then
72+
local USER_PROVIDED_DH
73+
74+
# Check if the DH params file is user provided or comes from acme-companion
75+
local DHPARAM_HASH; DHPARAM_HASH=$(sha256sum "$DHPARAM_FILE" | cut -d ' ' -f1)
76+
77+
for f in /app/dhparam/ffdhe*.pem; do
78+
local FFDHE_HASH; FFDHE_HASH=$(sha256sum "$f" | cut -d ' ' -f1)
79+
if [[ "$DHPARAM_HASH" == "$FFDHE_HASH" ]]; then
80+
# This is an acme-companion created DH params file
81+
USER_PROVIDED_DH='false'
82+
83+
# Check if /etc/nginx/certs/dhparam.pem matches the expected pre-generated DH group
84+
if [[ "$DHPARAM_HASH" == "$EXPECTED_DHPARAM_HASH" ]]; then
85+
set_ownership_and_permissions "$DHPARAM_FILE"
86+
echo "Info: ${DHPARAM_BITS} bits RFC7919 Diffie-Hellman group found, generation skipped."
87+
return 0
88+
fi
89+
fi
90+
done
91+
92+
if parse_true "${USER_PROVIDED_DH:=true}"; then
93+
# This is a user provided DH params file
94+
set_ownership_and_permissions "$DHPARAM_FILE"
95+
echo "Info: A custom dhparam.pem file was provided. Best practice is to use standardized RFC7919 Diffie-Hellman groups instead."
7596
return 0
7697
fi
77-
fi
78-
79-
echo "Info: Creating Diffie-Hellman group in the background."
80-
echo "A pre-generated Diffie-Hellman group will be used for now while the new one is being created."
98+
fi
8199

82-
# Put the default dhparam file in place so we can start immediately
83-
cp "$PREGEN_DHPARAM_FILE" "$DHPARAM_FILE"
100+
# The RFC7919 DH params file either need to be created or replaced
101+
echo "Info: Setting up ${DHPARAM_BITS} bits RFC7919 Diffie-Hellman group..."
102+
cp "$RFC7919_DHPARAM_FILE" "${DHPARAM_FILE}.tmp"
103+
mv "${DHPARAM_FILE}.tmp" "$DHPARAM_FILE"
84104
set_ownership_and_permissions "$DHPARAM_FILE"
85-
touch "$GEN_LOCKFILE"
86-
87-
# Generate a new dhparam in the background in a low priority and reload nginx when finished (grep removes the progress indicator).
88-
(
89-
(
90-
nice -n +5 openssl dhparam -out "${DHPARAM_FILE}.new" "$DHPARAM_BITS" 2>&1 \
91-
&& mv "${DHPARAM_FILE}.new" "$DHPARAM_FILE" \
92-
&& echo "Info: Diffie-Hellman group creation complete, reloading nginx." \
93-
&& set_ownership_and_permissions "$DHPARAM_FILE" \
94-
&& reload_nginx
95-
) | grep -vE '^[\.+]+'
96-
rm "$GEN_LOCKFILE"
97-
) & disown
98105
}
99106

100107
function check_default_cert_key {

app/functions.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,20 @@ if [[ "$DEBUG" == true ]]; then
1010
DEBUG=1 && export DEBUG
1111
fi
1212

13+
function parse_true() {
14+
case "$1" in
15+
16+
true | True | TRUE | 1)
17+
return 0
18+
;;
19+
20+
*)
21+
return 1
22+
;;
23+
24+
esac
25+
}
26+
1327
[[ -z "${VHOST_DIR:-}" ]] && \
1428
declare -r VHOST_DIR=/etc/nginx/vhost.d
1529
[[ -z "${START_HEADER:-}" ]] && \

docs/Advanced-usage.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
**nginx-proxy** can also be run as two separate containers using the [nginx-proxy/**docker-gen**](https://github.com/nginx-proxy/docker-gen) image and the official [**nginx**](https://hub.docker.com/_/nginx/) image. You may want to do this to prevent having the docker socket bound to a publicly exposed container service (ie avoid mounting the docker socket in the nginx exposed container).
44

5-
**NOTE**: The first time this container is launched in a three container setup, it will generates a new 2048 bits Diffie-Hellman parameters file. This process can take up to several minutes to complete on lower end hosts, and certificates creation won't start before that (be patient).
6-
75
Please read and try [basic usage](./Basic-usage.md), and **validate that you have a working two containers setup** before using the three containers setup. In addition to the steps described there, running **nginx-proxy** as two separate containers with **acme-companion** requires the following:
86

97
1) Download and mount the template file [nginx.tmpl](https://github.com/nginx-proxy/nginx-proxy/blob/main/nginx.tmpl) into the **docker-gen** container. You can get the nginx.tmpl file with a command like:

docs/Container-configuration.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ You can also create test certificates per container (see [Test certificates](./L
2222

2323
* `RENEW_PRIVATE_KEYS` - Set it to `false` to make `acme.sh` reuse previously generated private key for each certificate instead of creating a new one on certificate renewal. Reusing private keys can help if you intend to use [HPKP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning), but please note that HPKP has been deprecated by Google's Chrome and that it is therefore strongly discouraged to use it at all.
2424

25-
* `DHPARAM_BITS` - Change the size of the Diffie-Hellman key generated by the container from the default value of 2048 bits. For example `--env DHPARAM_BITS=1024` to support some older clients like Java 6 and 7.
25+
* `DHPARAM_BITS` - Change the key size of the RFC7919 Diffie-Hellman group used by the container from the default value of 4096 bits. Supported values are `2048`, `3072` and `4096`. The DH group file will be located in the container at `/etc/nginx/certs/dhparam.pem`. Mounting a different `dhparam.pem` file at that location will override the RFC7919 group creation by the acme-companion container. **COMPATIBILITY WARNING**: some older clients (like Java 6 and 7) do not support DH keys with over 1024 bits. In order to support these clients, you must provide your own `dhparam.pem`.
26+
27+
* `DHPARAM_SKIP` - Set it to `true` to disable the Diffie-Hellman group creation by the container entirely.
2628

2729
* `CA_BUNDLE` - This is a test only variable [for use with Pebble](https://github.com/letsencrypt/pebble#avoiding-client-https-errors). It changes the trusted root CA used by `acme.sh`, from the default Alpine trust store to the CA bundle file located at the provided path (inside the container). Do **not** use it in production unless you are running your own ACME CA.
2830

docs/Docker-Compose.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ services:
2828
- conf:/etc/nginx/conf.d
2929
- vhost:/etc/nginx/vhost.d
3030
- html:/usr/share/nginx/html
31-
- dhparam:/etc/nginx/dhparam
3231
- certs:/etc/nginx/certs:ro
3332
- /var/run/docker.sock:/tmp/docker.sock:ro
3433
network_mode: bridge
@@ -48,13 +47,10 @@ volumes:
4847
conf:
4948
vhost:
5049
html:
51-
dhparam:
5250
certs:
5351
acme:
5452
```
5553
56-
**Note:** **nginx-proxy** Dockerfile [create a volume for `/etc/nginx/dhparam`](https://github.com/nginx-proxy/nginx-proxy/blob/e80fc0b304bcbcf703d86392394c1a5adb823e3c/Dockerfile#L34), so this compose file include it as a named volume instead of letting it be created anyway as an anonymous volume.
57-
5854
### Three containers example
5955
6056
```yaml

test/tests/test-functions.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ function run_le_container {
3434
return 1
3535
fi
3636

37-
docker cp "${GITHUB_WORKSPACE}/test/setup/dhparam.pem" "$NGINX_CONTAINER_NAME:/etc/nginx/certs/dhparam.pem"
38-
3937
if docker run -d \
4038
--name "$name" \
4139
--volumes-from "$NGINX_CONTAINER_NAME" \

0 commit comments

Comments
 (0)