1
0
Fork 0
mirror of https://github.com/nginx-proxy/nginx-proxy synced 2024-05-12 10:36:08 +02:00
nginx-proxy/test/test_ssl/test_dhparam.py

207 lines
7.8 KiB
Python
Raw Normal View History

2017-03-07 20:04:37 +01:00
import re
2017-03-08 02:37:12 +01:00
import subprocess
import backoff
import docker
import pytest
2017-03-07 20:04:37 +01:00
docker_client = docker.from_env()
2017-03-08 02:37:12 +01:00
###############################################################################
#
# Tests helpers
#
###############################################################################
@backoff.on_exception(backoff.constant, AssertionError, interval=2, max_tries=15, jitter=None)
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
def assert_log_contains(expected_log_line, container_name="nginxproxy"):
2017-03-07 20:04:37 +01:00
"""
2017-03-08 02:37:12 +01:00
Check that the nginx-proxy container log contains a given string.
The backoff decorator will retry the check 15 times with a 2 seconds delay.
:param expected_log_line: string to search for
:return: None
:raises: AssertError if the expected string is not found in the log
2017-03-07 20:04:37 +01:00
"""
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
sut_container = docker_client.containers.get(container_name)
2017-03-08 02:37:12 +01:00
docker_logs = sut_container.logs(stdout=True, stderr=True, stream=False, follow=False)
assert bytes(expected_log_line, encoding="utf8") in docker_logs
2017-03-07 20:04:37 +01:00
2017-03-08 02:37:12 +01:00
def require_openssl(required_version):
"""
This function checks that the required version of OpenSSL is present, and skips the test if not.
Use it as a test function decorator:
2017-03-07 20:04:37 +01:00
2017-03-08 02:37:12 +01:00
@require_openssl("2.3.4")
def test_something():
...
2017-03-07 20:04:37 +01:00
2017-03-08 02:37:12 +01:00
:param required_version: minimal required version as a string: "1.2.3"
"""
def versiontuple(v):
clean_v = re.sub(r"[^\d\.]", "", v)
2017-03-08 02:37:12 +01:00
return tuple(map(int, (clean_v.split("."))))
try:
command_output = subprocess.check_output(["openssl", "version"])
except OSError:
return pytest.mark.skip("openssl command is not available in test environment")
else:
if not command_output:
raise Exception("Could not get openssl version")
openssl_version = str(command_output.split()[1])
2017-03-08 02:37:12 +01:00
return pytest.mark.skipif(
versiontuple(openssl_version) < versiontuple(required_version),
reason=f"openssl v{openssl_version} is less than required version {required_version}")
2017-03-08 02:37:12 +01:00
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
@require_openssl("1.0.2")
def negotiate_cipher(sut_container, additional_params='', grep='Cipher is'):
host = f"{sut_container.attrs['NetworkSettings']['IPAddress']}:443"
try:
# Enforce TLS 1.2 as newer versions don't support custom dhparam or ciphersuite preference.
# The empty `echo` is to provide `openssl` user input, so that the process exits: https://stackoverflow.com/a/28567565
# `shell=True` enables using a single string to execute as a shell command.
# `text=True` prevents the need to compare against byte strings.
# `stderr=subprocess.PIPE` removes the output to stderr being interleaved with test case status (output during exceptions).
return subprocess.check_output(
f"echo '' | openssl s_client -connect {host} -tls1_2 {additional_params} | grep '{grep}'",
shell=True,
text=True,
stderr=subprocess.PIPE,
)
except subprocess.CalledProcessError as e:
# Output a more helpful error, the original exception in this case isn't that helpful.
# `from None` to ignore undesired output from exception chaining.
raise Exception("Failed to process CLI request:\n" + e.stderr) from None
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
def can_negotiate_dhe_ciphersuite(sut_container):
r = negotiate_cipher(sut_container, "-cipher 'EDH'")
assert "New, TLSv1.2, Cipher is DHE-RSA-AES256-GCM-SHA384\n" == r
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
r2 = negotiate_cipher(sut_container, "-cipher 'EDH'", "Server Temp Key")
assert "DH" in r2
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
def cannot_negotiate_dhe_ciphersuite(sut_container):
# Fail to negotiate a DHE cipher suite:
r = negotiate_cipher(sut_container, "-cipher 'EDH'")
assert "New, (NONE), Cipher is (NONE)\n" == r
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
# Correctly establish a connection (TLS 1.2):
r2 = negotiate_cipher(sut_container)
assert "New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384\n" == r2
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
r3 = negotiate_cipher(sut_container, grep="Server Temp Key")
assert "X25519" in r3
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
# Parse array of container ENV, splitting at the `=` and returning the value, otherwise `None`
def get_env(sut_container, var):
env = sut_container.attrs['Config']['Env']
for e in env:
if e.startswith(var):
return e.split('=')[1]
return None
2017-03-08 02:37:12 +01:00
###############################################################################
#
# Tests
#
###############################################################################
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
def test_default_dhparam_is_ffdhe4096(docker_compose):
container_name="dh-default"
sut_container = docker_client.containers.get(container_name)
2017-03-08 02:37:12 +01:00
assert sut_container.status == "running"
2017-03-07 20:04:37 +01:00
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
assert_log_contains("Setting up DH Parameters..", container_name)
2017-03-07 20:04:37 +01:00
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
# Make sure the dhparam file used is the default ffdhe4096.pem:
default_checksum = sut_container.exec_run("md5sum /app/dhparam/ffdhe4096.pem").output.split()
current_checksum = sut_container.exec_run("md5sum /etc/nginx/dhparam/dhparam.pem").output.split()
assert default_checksum[0] == current_checksum[0]
can_negotiate_dhe_ciphersuite(sut_container)
def test_can_change_dhparam_group(docker_compose):
container_name="dh-env"
sut_container = docker_client.containers.get(container_name)
assert sut_container.status == "running"
assert_log_contains("Setting up DH Parameters..", container_name)
# Make sure the dhparam file used is ffdhe2048.pem, not the default (ffdhe4096.pem):
default_checksum = sut_container.exec_run("md5sum /app/dhparam/ffdhe2048.pem").output.split()
current_checksum = sut_container.exec_run("md5sum /etc/nginx/dhparam/dhparam.pem").output.split()
assert default_checksum[0] == current_checksum[0]
can_negotiate_dhe_ciphersuite(sut_container)
def test_fail_if_dhparam_group_not_supported(docker_compose):
container_name="invalid-group-1024"
sut_container = docker_client.containers.get(container_name)
assert sut_container.status == "exited"
DHPARAM_BITS = get_env(sut_container, "DHPARAM_BITS")
assert DHPARAM_BITS == "1024"
assert_log_contains(
f"ERROR: Unsupported DHPARAM_BITS size: {DHPARAM_BITS}. Use: 2048, 3072, or 4096 (default).",
container_name
)
def test_custom_dhparam_is_supported(docker_compose):
container_name="dh-file"
sut_container = docker_client.containers.get(container_name)
assert sut_container.status == "running"
assert_log_contains(
"Warning: A custom dhparam.pem file was provided. Best practice is to use standardized RFC7919 DHE groups instead.",
container_name
)
# Make sure the dhparam file used is not the default (ffdhe4096.pem):
default_checksum = sut_container.exec_run("md5sum /app/dhparam/ffdhe4096.pem").output.split()
current_checksum = sut_container.exec_run("md5sum /etc/nginx/dhparam/dhparam.pem").output.split()
2017-03-07 20:04:37 +01:00
assert default_checksum[0] != current_checksum[0]
tests: Revise dhparams tests - `dhparam_generation` tests are no longer necessary, dropped. Modified the remaining `dhparam` test to use multiple `nginx-proxy` images to verify correct behavior for different configs. Tests now cover: - Default (ffdhe4096) is used. - Alternative via ENV (ffdhe2048) works correctly. - Invalid group via ENV (1024-bit) fails. - Custom DH params provided via file mount works with warning emitted. --- - `assert_log_contains`: added a `container_name` arg with `nginxproxy` as the default value. This allows multiple nginx-proxy containers to utilize this method instead. - Extracted out the `openssl` test (_to `negotiate_cipher()`_) and modified it to be a bit more flexible. It now takes a container with optional extra args to pass to `openssl` command called, as well as the `grep` string to match. This made the original test redundant, so I've dropped it. - Added two methods to use `negotiate_cipher()`, one verifies a DHE cipher suite was negotiated and checks that a DH emphermal key was also mentioned in the output. The other method verifies the expectation of failing to negotiate a valid cipher if DH params have not been set, while verifying that non-DHE cipher suites can be successfully negotiated. - Added a `get_env()` method for extracting attached environments on a container. This is useful for verifying invalid `DHPARAM_BITS` values (eg `1024`-bit). - The original `Server Temp Key` assertion was incorrect, it was expecting a value that is unrelated to DHE cipher suite support (_`X25519` is related to ECDHE_). This is due to TLS 1.3 being negotiated where you cannot use custom DH params, nor influence the negotiated cipher due to this mechanism changing from TLS 1.3. TLS 1.3 does support DH params, but it internally negotiates RFC 7919 group between server and client instead. Thus to verify expectations, the connection via `openssl` is made explicitly with TLS 1.2 instead.
2021-09-28 10:54:22 +02:00
can_negotiate_dhe_ciphersuite(sut_container)
2017-03-08 02:37:12 +01:00
def test_can_skip_dhparam(docker_compose):
container_name="dh-skip"
sut_container = docker_client.containers.get(container_name)
assert sut_container.status == "running"
assert_log_contains("Skipping Diffie-Hellman parameters setup.", container_name)
cannot_negotiate_dhe_ciphersuite(sut_container)
def test_can_skip_dhparam_backward_compatibility(docker_compose):
container_name="dh-skip-backward"
sut_container = docker_client.containers.get(container_name)
assert sut_container.status == "running"
assert_log_contains("Warning: The DHPARAM_GENERATION environment variable is deprecated, please consider using DHPARAM_SKIP set to true instead.", container_name)
assert_log_contains("Skipping Diffie-Hellman parameters setup.", container_name)
cannot_negotiate_dhe_ciphersuite(sut_container)
2017-03-07 20:04:37 +01:00
def test_web5_https_works(docker_compose, nginxproxy):
r = nginxproxy.get("https://web5.nginx-proxy.tld/port", allow_redirects=False)
assert r.status_code == 200
assert "answer from port 85\n" in r.text