diff --git a/docs/rolereference.rst b/docs/rolereference.rst index 722045477660eaeaa4ff8902dae4efb044bf2f59..c29116e11b72fde2554f250fdf5bdf2131e20255 100644 --- a/docs/rolereference.rst +++ b/docs/rolereference.rst @@ -1390,11 +1390,11 @@ Parameters List of TLS protocols the web server should support. Each value specified should be compatible with Nginx configuration option ``ssl_protocols``. -**web_server_tls_ciphers** (string, optional ``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-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:!aNULL:!MD5:!EXPORT``) +**web_server_tls_ciphers** (string, optional, ``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:!aNULL:!MD5:!EXPORT``) TLS ciphers to enable on the web server. This should be an OpenSSL-compatible cipher specification. Value should be compatible with Nginx configuration option ``ssl_ciphers``. Default value allows only TLSv1.2 and strong PFS - ciphers. + ciphers with RSA private keys. Distribution compatibility diff --git a/roles/web_server/defaults/main.yml b/roles/web_server/defaults/main.yml index ea44145714df27aa1d6d9933ea7336d3c8f4e243..e7bd8e9e2cfc6bb09cabf7f5d0ed0cd1c58e7c62 100644 --- a/roles/web_server/defaults/main.yml +++ b/roles/web_server/defaults/main.yml @@ -5,9 +5,14 @@ web_default_title: "Welcome" web_default_message: "You are attempting to access the web server using a wrong name or an IP address. Please check your URL." web_server_tls_protocols: - "TLSv1.2" -web_server_tls_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-SHA256:ECDHE-RSA-AES256-GCM-SHA384:\ -ECDHE-RSA-AES256-SHA384:!aNULL:!MD5:!EXPORT" +web_server_tls_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:\ +!aNULL:!MD5:!EXPORT" # Internal parameters php_fpm_package_name: "php-fpm" diff --git a/roles/web_server/molecule/default/tests/test_mandatory.py b/roles/web_server/molecule/default/tests/test_mandatory.py index 80a5d8d583c7a27f657bc9e1dff4c6d75cd19038..13e0e0d1c17038741e4a42bd266fa25b6efacf63 100644 --- a/roles/web_server/molecule/default/tests/test_mandatory.py +++ b/roles/web_server/molecule/default/tests/test_mandatory.py @@ -1,5 +1,7 @@ import os +import pytest + import testinfra.utils.ansible_runner @@ -21,18 +23,104 @@ def test_tls_version(host): assert old_tls_versions_disabled.rc != 0 -def test_tls_ciphers(host): +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", + "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[: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-mandatory: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-mandatory:443") - assert cipher.rc != 0 - assert "ECDHE-RSA-AES128-SHA" not 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):