diff --git a/roles/web_server/molecule/default/tests/test_mandatory.py b/roles/web_server/molecule/default/tests/test_mandatory.py index 13e0e0d1c17038741e4a42bd266fa25b6efacf63..99ad78e21f88437c10f812e3de9f1e1eb26b6ae5 100644 --- a/roles/web_server/molecule/default/tests/test_mandatory.py +++ b/roles/web_server/molecule/default/tests/test_mandatory.py @@ -4,6 +4,8 @@ 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') @@ -23,66 +25,6 @@ def test_tls_version(host): assert old_tls_versions_disabled.rc != 0 -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", -] - ENABLED_CIPHERS = [ "DHE-RSA-AES128-GCM-SHA256", "DHE-RSA-AES256-GCM-SHA384", diff --git a/roles/web_server/molecule/default/tests/test_optional.py b/roles/web_server/molecule/default/tests/test_optional.py index e68113a2112eb8f021a49efc0182ee74ff6c03cc..c71cd59753f5335e0d21d8fe43465176b5c18956 100644 --- a/roles/web_server/molecule/default/tests/test_optional.py +++ b/roles/web_server/molecule/default/tests/test_optional.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-optional') @@ -33,18 +37,47 @@ def test_tls_version(host): assert tls1_2_enabled.rc == 0 -def test_tls_ciphers(host): +ENABLED_CIPHERS = [ + "DHE-RSA-AES128-GCM-SHA256", + "DHE-RSA-AES128-SHA256", + "DHE-RSA-AES256-GCM-SHA384", + "DHE-RSA-AES256-SHA256", + "ECDHE-RSA-AES128-GCM-SHA256", + "ECDHE-RSA-AES128-SHA", + "ECDHE-RSA-AES128-SHA256", + "ECDHE-RSA-AES256-GCM-SHA384", + "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[:hostname.rfind('-')] + + client = host.run("echo 'Q' | openssl s_client -cipher %s -connect %s:443", 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. """ - cipher = host.run("echo 'Q' | openssl s_client -cipher ECDHE-RSA-AES128-SHA256 -connect parameters-optional:443") - assert cipher.rc == 0 - assert "ECDHE-RSA-AES128-SHA256" in cipher.stdout + hostname = host.run('hostname').stdout.strip() + fqdn = hostname[:hostname.rfind('-')] - cipher = host.run("echo 'Q' | openssl s_client -cipher ECDHE-RSA-AES128-SHA -connect parameters-optional:443") - assert cipher.rc == 0 - assert "ECDHE-RSA-AES128-SHA" in cipher.stdout + client = host.run("echo 'Q' | openssl s_client -cipher %s -connect %s:443", cipher, fqdn) + assert client.rc != 0 + assert cipher not in client.stdout def test_https_enforcement(host): diff --git a/roles/web_server/molecule/default/tests/tls_ciphers.py b/roles/web_server/molecule/default/tests/tls_ciphers.py new file mode 100644 index 0000000000000000000000000000000000000000..9a99acdeb943d946eadc058c414580e5f66fb8d5 --- /dev/null +++ b/roles/web_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", +]