URL: https://github.com/freeipa/freeipa/pull/3350
Author: tiran
 Title: #3350: Use only TLS 1.2 by default
Action: opened

PR body:
"""
TLS 1.3 is causing some trouble with client cert authentication.
Conditional client cert authentication requires post-handshake
authentication extension on TLS 1.3. The new feature is not fully
implemented yet.

TLS 1.0 and 1.1 are no longer state of the art and now disabled by
default.

TLS 1.2 works everywhere and supports PFS.

Related: pagure.io/freeipa/issue/7667
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/3350/head:pr3350
git checkout pr3350
From b25467810114423f22a26efaa61ed65653b196af Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Thu, 23 May 2019 10:45:26 -0400
Subject: [PATCH 1/2] For Fedora and RHEL use system-wide crypto policy for
 mod_ssl

Drop the SSLProtocol directive for Fedora and RHEL systems. mod_ssl
will use crypto policies for the set of protocols.

For Debian systems configure a similar set of protocols for what
was previously configured, but do it in a different way. Rather than
iterating the allowed protocols just include the ones not allowed.

Fixes: https://pagure.io/freeipa/issue/7667

Signed-off-by: Rob Crittenden <rcrit...@redhat.com>
---
 ipaplatform/base/tasks.py         | 4 ++++
 ipaplatform/debian/tasks.py       | 7 +++++++
 ipaplatform/redhat/tasks.py       | 6 ++++++
 ipaserver/install/httpinstance.py | 6 ++----
 4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/ipaplatform/base/tasks.py b/ipaplatform/base/tasks.py
index 94f1de1f5c..8aa9c5cd05 100644
--- a/ipaplatform/base/tasks.py
+++ b/ipaplatform/base/tasks.py
@@ -246,6 +246,10 @@ def configure_httpd_wsgi_conf(self):
         """Configure WSGI for correct Python version"""
         raise NotImplementedError()
 
+    def configure_httpd_protocol(self):
+        """Configure TLS protocols in Apache"""
+        raise NotImplementedError()
+
     def is_fips_enabled(self):
         return False
 
diff --git a/ipaplatform/debian/tasks.py b/ipaplatform/debian/tasks.py
index 4a2b81d8e8..b378c5954b 100644
--- a/ipaplatform/debian/tasks.py
+++ b/ipaplatform/debian/tasks.py
@@ -10,7 +10,9 @@
 
 from ipaplatform.base.tasks import BaseTaskNamespace
 from ipaplatform.redhat.tasks import RedHatTaskNamespace
+from ipaplatform.paths import paths
 
+from ipapython import directivesetter
 from ipapython import ipautil
 
 class DebianTaskNamespace(RedHatTaskNamespace):
@@ -69,6 +71,11 @@ def configure_httpd_wsgi_conf(self):
         # Debian doesn't require special mod_wsgi configuration
         pass
 
+    def configure_httpd_protocol(self):
+        directivesetter.set_directive(paths.HTTPD_SSL_CONF,
+                                      'SSLProtocol',
+                                      'all -SSLv3', False)
+
     def setup_httpd_logging(self):
         # Debian handles httpd logging differently
         pass
diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
index e4b76d3d2d..3b6156849e 100644
--- a/ipaplatform/redhat/tasks.py
+++ b/ipaplatform/redhat/tasks.py
@@ -589,6 +589,12 @@ def remove_httpd_service_ipa_conf(self):
 
         self.systemd_daemon_reload()
 
+    def configure_httpd_protocol(self):
+        """Drop SSLProtocol directive and let crypto policy handle it"""
+        directivesetter.set_directive(paths.HTTPD_SSL_CONF,
+                                      'SSLProtocol',
+                                      None, False)
+
     def set_hostname(self, hostname):
         ipautil.run([paths.BIN_HOSTNAMECTL, 'set-hostname', hostname])
 
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index 4436b56017..63d3021255 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -123,7 +123,7 @@ def create_instance(self, realm, fqdn, domain_name, dm_password=None,
         self.step("disabling nss.conf", self.disable_nss_conf)
         self.step("configuring mod_ssl certificate paths",
                   self.configure_mod_ssl_certs)
-        self.step("setting mod_ssl protocol list to TLSv1.0 - TLSv1.2",
+        self.step("setting mod_ssl protocol list",
                   self.set_mod_ssl_protocol)
         self.step("configuring mod_ssl log directory",
                   self.set_mod_ssl_logdir)
@@ -244,9 +244,7 @@ def disable_nss_conf(self):
         open(paths.HTTPD_NSS_CONF, 'w').close()
 
     def set_mod_ssl_protocol(self):
-        directivesetter.set_directive(paths.HTTPD_SSL_CONF,
-                                   'SSLProtocol',
-                                   '+TLSv1 +TLSv1.1 +TLSv1.2', False)
+        tasks.configure_httpd_protocol()
 
     def set_mod_ssl_logdir(self):
         tasks.setup_httpd_logging()

From 7e962e2c133924947aa4be2cf6b571ee5d4bc278 Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Mon, 1 Jul 2019 10:41:23 +0200
Subject: [PATCH 2/2] Use only TLS 1.2 by default

TLS 1.3 is causing some trouble with client cert authentication.
Conditional client cert authentication requires post-handshake
authentication extension on TLS 1.3. The new feature is not fully
implemented yet.

TLS 1.0 and 1.1 are no longer state of the art and now disabled by
default.

TLS 1.2 works everywhere and supports PFS.

Related: https://pagure.io/freeipa/issue/7667

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 ipalib/config.py            |  6 +++---
 ipalib/constants.py         | 33 ++++++++++++++++++++-------------
 ipalib/util.py              | 10 +++++-----
 ipaplatform/debian/tasks.py |  3 ++-
 ipaplatform/redhat/tasks.py |  4 ++--
 5 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/ipalib/config.py b/ipalib/config.py
index 6f45317455..b051f25438 100644
--- a/ipalib/config.py
+++ b/ipalib/config.py
@@ -44,7 +44,7 @@
 from ipalib.constants import (
     CONFIG_SECTION,
     OVERRIDE_ERROR, SET_ERROR, DEL_ERROR,
-    TLS_VERSIONS
+    TLS_VERSIONS, TLS_VERSION_DEFAULT_MIN, TLS_VERSION_DEFAULT_MAX,
 )
 from ipalib import errors
 
@@ -632,14 +632,14 @@ def _finalize_core(self, **defaults):
 
         # set the best known TLS version if min/max versions are not set
         if 'tls_version_min' not in self:
-            self.tls_version_min = TLS_VERSIONS[-1]
+            self.tls_version_min = TLS_VERSION_DEFAULT_MIN
         elif self.tls_version_min not in TLS_VERSIONS:
             raise errors.EnvironmentError(
                 "Unknown TLS version '{ver}' set in tls_version_min."
                 .format(ver=self.tls_version_min))
 
         if 'tls_version_max' not in self:
-            self.tls_version_max = TLS_VERSIONS[-1]
+            self.tls_version_max = TLS_VERSION_DEFAULT_MAX
         elif self.tls_version_max not in TLS_VERSIONS:
             raise errors.EnvironmentError(
                 "Unknown TLS version '{ver}' set in tls_version_max."
diff --git a/ipalib/constants.py b/ipalib/constants.py
index f35a125c36..d4577d668f 100644
--- a/ipalib/constants.py
+++ b/ipalib/constants.py
@@ -35,6 +35,24 @@
     except Exception:
         FQDN = None
 
+# TLS related constants
+# * SSL2 and SSL3 are broken.
+# * TLS1.0 and TLS1.1 are no longer state of the art.
+# * TLS1.3 support is not yet stable, e.g. issues with PHA.
+# Therefore only TLS 1.2 is enabled by default.
+
+TLS_VERSIONS = [
+    "ssl2",
+    "ssl3",
+    "tls1.0",
+    "tls1.1",
+    "tls1.2",
+    "tls1.3",
+]
+TLS_VERSION_MINIMAL = "tls1.0"
+TLS_VERSION_DEFAULT_MIN = "tls1.2"
+TLS_VERSION_DEFAULT_MAX = "tls1.2"
+
 # regular expression NameSpace member names must match:
 NAME_REGEX = r'^[a-z][_a-z0-9]*[a-z0-9]$|^[a-z]$'
 
@@ -144,8 +162,8 @@
     ('rpc_protocol', 'jsonrpc'),
 
     # Define an inclusive range of SSL/TLS version support
-    ('tls_version_min', 'tls1.0'),
-    ('tls_version_max', 'tls1.2'),
+    ('tls_version_min', TLS_VERSION_DEFAULT_MIN),
+    ('tls_version_max', TLS_VERSION_DEFAULT_MAX),
 
     # Time to wait for a service to start, in seconds.
     # Note that systemd has a DefaultTimeoutStartSec of 90 seconds. Higher
@@ -306,17 +324,6 @@
 IPAAPI_USER = 'ipaapi'
 IPAAPI_GROUP = 'ipaapi'
 
-# TLS related constants
-TLS_VERSIONS = [
-    "ssl2",
-    "ssl3",
-    "tls1.0",
-    "tls1.1",
-    "tls1.2"
-]
-TLS_VERSION_MINIMAL = "tls1.0"
-
-
 # Use cache path
 USER_CACHE_PATH = (
     os.environ.get('XDG_CACHE_HOME') or
diff --git a/ipalib/util.py b/ipalib/util.py
index 35f445d84c..367368afb0 100644
--- a/ipalib/util.py
+++ b/ipalib/util.py
@@ -57,7 +57,8 @@
 from ipalib import errors, messages
 from ipalib.constants import (
     DOMAIN_LEVEL_0,
-    TLS_VERSIONS, TLS_VERSION_MINIMAL
+    TLS_VERSIONS, TLS_VERSION_MINIMAL, TLS_VERSION_DEFAULT_MIN,
+    TLS_VERSION_DEFAULT_MAX,
 )
 from ipalib.text import _
 from ipaplatform.constants import constants
@@ -282,8 +283,8 @@ def create_https_connection(
     cafile=None,
     client_certfile=None, client_keyfile=None,
     keyfile_passwd=None,
-    tls_version_min="tls1.1",
-    tls_version_max="tls1.2",
+    tls_version_min=TLS_VERSION_DEFAULT_MIN,
+    tls_version_max=TLS_VERSION_DEFAULT_MAX,
     **kwargs
 ):
     """
@@ -308,11 +309,10 @@ def create_https_connection(
     """
     # pylint: disable=no-member
     tls_cutoff_map = {
-        "ssl2": ssl.OP_NO_SSLv2,
-        "ssl3": ssl.OP_NO_SSLv3,
         "tls1.0": ssl.OP_NO_TLSv1,
         "tls1.1": ssl.OP_NO_TLSv1_1,
         "tls1.2": ssl.OP_NO_TLSv1_2,
+        "tls1.3": getattr(ssl, "OP_NO_TLSv1_3", 0),
     }
     # pylint: enable=no-member
 
diff --git a/ipaplatform/debian/tasks.py b/ipaplatform/debian/tasks.py
index b378c5954b..31982a0ee9 100644
--- a/ipaplatform/debian/tasks.py
+++ b/ipaplatform/debian/tasks.py
@@ -72,9 +72,10 @@ def configure_httpd_wsgi_conf(self):
         pass
 
     def configure_httpd_protocol(self):
+        # TLS 1.3 is not yet supported
         directivesetter.set_directive(paths.HTTPD_SSL_CONF,
                                       'SSLProtocol',
-                                      'all -SSLv3', False)
+                                      'TLSv1.2', False)
 
     def setup_httpd_logging(self):
         # Debian handles httpd logging differently
diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
index 3b6156849e..e3c316c61b 100644
--- a/ipaplatform/redhat/tasks.py
+++ b/ipaplatform/redhat/tasks.py
@@ -590,10 +590,10 @@ def remove_httpd_service_ipa_conf(self):
         self.systemd_daemon_reload()
 
     def configure_httpd_protocol(self):
-        """Drop SSLProtocol directive and let crypto policy handle it"""
+        # TLS 1.3 is not yet supported
         directivesetter.set_directive(paths.HTTPD_SSL_CONF,
                                       'SSLProtocol',
-                                      None, False)
+                                      'TLSv1.2', False)
 
     def set_hostname(self, hostname):
         ipautil.run([paths.BIN_HOSTNAMECTL, 'set-hostname', hostname])
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org

Reply via email to