Changeset - 36cc127035aa
[Not reviewed]
0 3 0
Branko Majic (branko) - 4 years ago 2020-09-22 14:12:07
branko@majic.rs
MAR-158: Update default TLS cipher configuration in the web_server role:

- Updated the default value for parameter web_server_tls_ciphers.
- Updated tests, making them explicitly test for enabled and disabled
ciphers.
- Updated role reference documentation.
3 files changed with 105 insertions and 12 deletions:
0 comments (0 inline, 0 general)
docs/rolereference.rst
Show inline comments
 
@@ -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
roles/web_server/defaults/main.yml
Show inline comments
 
@@ -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"
roles/web_server/molecule/default/tests/test_mandatory.py
Show inline comments
 
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):
0 comments (0 inline, 0 general)