From 2e3af1a245a536075c1d7fbf2f8fbbbd4c8b86bc 2020-09-23 13:25:11 From: Branko Majic Date: 2020-09-23 13:25:11 Subject: [PATCH] MAR-158: Update default TLS ciphers configuration in the ldap_server role: - Updated the default value for parameter ldap_tls_ciphers. - Updated tests, making them explicitly test for enabled and disabled ciphers - Updated role reference documentation. --- diff --git a/docs/rolereference.rst b/docs/rolereference.rst index c29116e11b72fde2554f250fdf5bdf2131e20255..19680e306d9cb0683b0f2c845762e7a00a5b1bcc 100644 --- a/docs/rolereference.rst +++ b/docs/rolereference.rst @@ -742,7 +742,14 @@ Parameters Minimum *Security Strength Factor* to require from all incoming connections. This applies for both remote and local connections. -**ldap_tls_ciphers** (string, optional ``NONE:+VERS-TLS1.2:+CTYPE-X509:+COMP-NULL:+SIGN-RSA-SHA256:+SIGN-RSA-SHA384:+SIGN-RSA-SHA512:+DHE-RSA:+ECDHE-RSA:+SHA256:+SHA384:+AEAD:+AES-128-GCM:+AES-128-CBC:+AES-256-GCM:+AES-256-CBC:+CURVE-ALL``) +**ldap_tls_ciphers** (string, optional ``NONE:+VERS-TLS1.2:+CTYPE-X509:+COMP-NULL:+SIGN-RSA-SHA256:+SIGN-RSA-SHA384:+SIGN-RSA-SHA512:+DHE-RSA:+ECDHE-RSA:+SHA256:+SHA384:+SHA512:+AEAD:+AES-128-GCM:+AES-256-GCM:+CHACHA20-POLY1305:+CURVE-ALL``) + + .. warning:: + Under Debian Stretch, the DHE ciphers are not usable due to a bug + present in OpenLDAP 2.4.44. See + https://bugs.launchpad.net/ubuntu/+source/openldap/+bug/1656979 + for details. + TLS ciphers to enable on the LDAP server. This should be a GnuTLS-compatible cipher specification that should also include what TLS protocol versions should be used. Value should be compatible with OpenLDAP server option diff --git a/roles/ldap_server/defaults/main.yml b/roles/ldap_server/defaults/main.yml index 465ea9fb8fc35da661c87eaa22af6685ca0c58fd..bc5466ba468b2ec8bf3add2e2b6bee44de7b7878 100644 --- a/roles/ldap_server/defaults/main.yml +++ b/roles/ldap_server/defaults/main.yml @@ -31,5 +31,20 @@ ldap_permissions: by users read by * none -ldap_tls_ciphers: "NONE:+VERS-TLS1.2:+CTYPE-X509:+COMP-NULL:+SIGN-RSA-SHA256:+SIGN-RSA-SHA384:\ -+SIGN-RSA-SHA512:+DHE-RSA:+ECDHE-RSA:+SHA256:+SHA384:+AEAD:+AES-128-GCM:+AES-128-CBC:+AES-256-GCM:+AES-256-CBC:+CURVE-ALL" +ldap_tls_ciphers: "NONE:\ ++VERS-TLS1.2:\ ++CTYPE-X509:\ ++COMP-NULL:\ ++SIGN-RSA-SHA256:\ ++SIGN-RSA-SHA384:\ ++SIGN-RSA-SHA512:\ ++DHE-RSA:\ ++ECDHE-RSA:\ ++SHA256:\ ++SHA384:\ ++SHA512:\ ++AEAD:\ ++AES-128-GCM:\ ++AES-256-GCM:\ ++CHACHA20-POLY1305:\ ++CURVE-ALL" diff --git a/roles/ldap_server/molecule/default/tests/test_mandatory.py b/roles/ldap_server/molecule/default/tests/test_mandatory.py index 26d6d7b0b7d9c1c68557ab1b3a2236b34793242d..51efd6cd9cfce0361c962aaebb822b70802ec914 100644 --- a/roles/ldap_server/molecule/default/tests/test_mandatory.py +++ b/roles/ldap_server/molecule/default/tests/test_mandatory.py @@ -1,7 +1,11 @@ import os +import pytest + import testinfra.utils.ansible_runner +from tls_ciphers import ALL_CIPHERS + testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('parameters-mandatory') @@ -68,14 +72,50 @@ def test_tls_configuration(host): assert old_tls_versions_disabled.rc != 0 assert "CONNECTED" in old_tls_versions_disabled.stdout - cipher = host.run("echo 'Q' | openssl s_client -cipher ECDHE-RSA-AES128-SHA256 -connect parameters-mandatory.local:636") - assert cipher.rc == 0 - assert "ECDHE-RSA-AES128-SHA256" in cipher.stdout - cipher = host.run("echo 'Q' | openssl s_client -cipher ECDHE-RSA-AES128-SHA -connect parameters-mandatory.local:636") - assert cipher.rc != 0 - assert "CONNECTED" in cipher.stdout - assert "ECDHE-RSA-AES128-SHA" not in cipher.stdout +# @TODO: Under Debian Stretch, the DHE ciphers are not usable due to a +# bug present in OpenLDAP 2.4.44. See +# https://bugs.launchpad.net/ubuntu/+source/openldap/+bug/1656979 for +# details. It should be possible to fix this problem once switch to +# buster is made. +ENABLED_CIPHERS = [ + # "DHE-RSA-AES128-GCM-SHA256", + # "DHE-RSA-AES256-GCM-SHA384", + # "DHE-RSA-CHACHA20-POLY1305", + "ECDHE-RSA-AES128-GCM-SHA256", + "ECDHE-RSA-AES256-GCM-SHA384", + "ECDHE-RSA-CHACHA20-POLY1305", +] + +DISABLED_CIPHERS = sorted(list(set(ALL_CIPHERS)-set(ENABLED_CIPHERS))) + + +@pytest.mark.parametrize("cipher", ENABLED_CIPHERS) +def test_enabled_tls_ciphers(host, cipher): + """ + Tests available TLS ciphers on the server. + """ + + hostname = host.run('hostname').stdout.strip() + fqdn = hostname + + client = host.run("echo 'Q' | openssl s_client -cipher %s -connect %s:636", cipher, fqdn) + assert client.rc == 0 + assert cipher in client.stdout + + +@pytest.mark.parametrize("cipher", DISABLED_CIPHERS) +def test_disabled_tls_ciphers(host, cipher): + """ + Tests available TLS ciphers on the server. + """ + + hostname = host.run('hostname').stdout.strip() + fqdn = hostname + + client = host.run("echo 'Q' | openssl s_client -cipher %s -connect %s:636", cipher, fqdn) + assert client.rc != 0 + assert cipher not in client.stdout def test_ssf_configuration(host): diff --git a/roles/ldap_server/molecule/default/tests/test_optional.py b/roles/ldap_server/molecule/default/tests/test_optional.py index a5fe69286b8a9f4cc1452c69061c4463bce34a2a..a3d5ae759900d1d26b29794e9b18d35d5dc46c05 100644 --- a/roles/ldap_server/molecule/default/tests/test_optional.py +++ b/roles/ldap_server/molecule/default/tests/test_optional.py @@ -1,9 +1,13 @@ import os +import pytest + import testinfra.utils.ansible_runner from helpers import parse_ldif +from tls_ciphers import ALL_CIPHERS + testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('parameters-optional') @@ -70,13 +74,55 @@ def test_tls_configuration(host): assert old_tls_versions_disabled.rc == 0 assert "CONNECTED" in old_tls_versions_disabled.stdout - cipher = host.run("echo 'Q' | openssl s_client -cipher ECDHE-RSA-AES128-SHA256 -connect parameters-optional:636") - assert cipher.rc == 0 - assert "ECDHE-RSA-AES128-SHA256" in cipher.stdout - cipher = host.run("echo 'Q' | openssl s_client -tls1_1 -cipher ECDHE-RSA-AES128-SHA -connect parameters-optional:636") - assert cipher.rc == 0 - assert "ECDHE-RSA-AES128-SHA" in cipher.stdout +# @TODO: Under Debian Stretch, the DHE ciphers are not usable due to a +# bug present in OpenLDAP 2.4.44. See +# https://bugs.launchpad.net/ubuntu/+source/openldap/+bug/1656979 for +# details. It should be possible to fix this problem once switch to +# buster is made. +ENABLED_CIPHERS = [ + # "DHE-RSA-AES128-GCM-SHA256", + # "DHE-RSA-AES256-GCM-SHA384", + # "DHE-RSA-CHACHA20-POLY1305", + "ECDHE-RSA-AES128-SHA256", + "ECDHE-RSA-AES128-SHA", + "ECDHE-RSA-AES128-GCM-SHA256", + "ECDHE-RSA-AES128-SHA", + "ECDHE-RSA-AES128-SHA256", + "ECDHE-RSA-AES256-GCM-SHA384", + "ECDHE-RSA-AES256-SHA", + "ECDHE-RSA-AES256-SHA384", +] + +DISABLED_CIPHERS = sorted(list(set(ALL_CIPHERS)-set(ENABLED_CIPHERS))) + + +@pytest.mark.parametrize("cipher", ENABLED_CIPHERS) +def test_enabled_tls_ciphers(host, cipher): + """ + Tests available TLS ciphers on the server. + """ + + hostname = host.run('hostname').stdout.strip() + fqdn = hostname + + client = host.run("echo 'Q' | openssl s_client -cipher %s -connect %s:636", cipher, fqdn) + assert client.rc == 0 + assert cipher in client.stdout + + +@pytest.mark.parametrize("cipher", DISABLED_CIPHERS) +def test_disabled_tls_ciphers(host, cipher): + """ + Tests available TLS ciphers on the server. + """ + + hostname = host.run('hostname').stdout.strip() + fqdn = hostname + + client = host.run("echo 'Q' | openssl s_client -cipher %s -connect %s:636", cipher, fqdn) + assert client.rc != 0 + assert cipher not in client.stdout def test_ssf_configuration(host): diff --git a/roles/ldap_server/molecule/default/tests/tls_ciphers.py b/roles/ldap_server/molecule/default/tests/tls_ciphers.py new file mode 100644 index 0000000000000000000000000000000000000000..9a99acdeb943d946eadc058c414580e5f66fb8d5 --- /dev/null +++ b/roles/ldap_server/molecule/default/tests/tls_ciphers.py @@ -0,0 +1,59 @@ +ALL_CIPHERS = [ + "AES128-GCM-SHA256", + "AES128-SHA", + "AES128-SHA256", + "AES256-GCM-SHA384", + "AES256-SHA", + "AES256-SHA256", + "DHE-PSK-AES128-CBC-SHA", + "DHE-PSK-AES128-CBC-SHA256", + "DHE-PSK-AES128-GCM-SHA256", + "DHE-PSK-AES256-CBC-SHA", + "DHE-PSK-AES256-CBC-SHA384", + "DHE-PSK-AES256-GCM-SHA384", + "DHE-PSK-CHACHA20-POLY1305", + "DHE-RSA-AES128-GCM-SHA256", + "DHE-RSA-AES128-SHA", + "DHE-RSA-AES128-SHA256", + "DHE-RSA-AES256-GCM-SHA384", + "DHE-RSA-AES256-SHA", + "DHE-RSA-AES256-SHA256", + "DHE-RSA-CHACHA20-POLY1305", + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-AES128-SHA", + "ECDHE-ECDSA-AES128-SHA256", + "ECDHE-ECDSA-AES256-GCM-SHA384", + "ECDHE-ECDSA-AES256-SHA", + "ECDHE-ECDSA-AES256-SHA384", + "ECDHE-ECDSA-CHACHA20-POLY1305", + "ECDHE-PSK-AES128-CBC-SHA", + "ECDHE-PSK-AES128-CBC-SHA256", + "ECDHE-PSK-AES256-CBC-SHA", + "ECDHE-PSK-AES256-CBC-SHA384", + "ECDHE-PSK-CHACHA20-POLY1305", + "ECDHE-RSA-AES128-GCM-SHA256", + "ECDHE-RSA-AES128-SHA", + "ECDHE-RSA-AES128-SHA256", + "ECDHE-RSA-AES256-GCM-SHA384", + "ECDHE-RSA-AES256-SHA", + "ECDHE-RSA-AES256-SHA384", + "ECDHE-RSA-CHACHA20-POLY1305", + "PSK-AES128-CBC-SHA", + "PSK-AES128-CBC-SHA256", + "PSK-AES128-GCM-SHA256", + "PSK-AES256-CBC-SHA", + "PSK-AES256-CBC-SHA384", + "PSK-AES256-GCM-SHA384", + "PSK-CHACHA20-POLY1305", + "RSA-PSK-AES128-CBC-SHA", + "RSA-PSK-AES128-CBC-SHA256", + "RSA-PSK-AES128-GCM-SHA256", + "RSA-PSK-AES256-CBC-SHA", + "RSA-PSK-AES256-CBC-SHA384", + "RSA-PSK-AES256-GCM-SHA384", + "RSA-PSK-CHACHA20-POLY1305", + "SRP-AES-128-CBC-SHA", + "SRP-AES-256-CBC-SHA", + "SRP-RSA-AES-128-CBC-SHA", + "SRP-RSA-AES-256-CBC-SHA", +]