diff --git a/docker/tls.py b/docker/tls.py index 6488bbcc..8fdf3596 100644 --- a/docker/tls.py +++ b/docker/tls.py @@ -37,13 +37,40 @@ class TLSConfig(object): self.assert_hostname = assert_hostname self.assert_fingerprint = assert_fingerprint - # TLS v1.0 seems to be the safest default; SSLv23 fails in mysterious - # ways: https://github.com/docker/docker-py/issues/963 + # TODO(dperny): according to the python docs, PROTOCOL_TLSvWhatever is + # depcreated, and it's recommended to use OPT_NO_TLSvWhatever instead + # to exclude versions. But I think that might require a bigger + # architectural change, so I've opted not to pursue it at this time - self.ssl_version = ssl_version or ssl.PROTOCOL_TLSv1 + # If the user provides an SSL version, we should use their preference + if ssl_version: + self.ssl_version = ssl_version + else: + # If the user provides no ssl version, we should default to + # TLSv1_2. This option is the most secure, and will work for the + # majority of users with reasonably up-to-date software. However, + # before doing so, detect openssl version to ensure we can support + # it. - # "tls" and "tls_verify" must have both or neither cert/key files - # In either case, Alert the user when both are expected, but any are + # ssl.OPENSSL_VERSION_INFO returns a tuple of 5 integers + # representing version info. We want any OpenSSL version greater + # than 1.0.1. Python compares tuples lexigraphically, which means + # this comparison will work. + if ssl.OPENSSL_VERSION_INFO > (1, 0, 1, 0, 0): + # If this version is high enough to support TLSv1_2, then we + # should use it. + self.ssl_version = ssl.PROTOCOL_TLSv1_2 + else: + # If we can't, use a differnent default. Before the commit + # introducing this version detection, the comment read: + # >>> TLS v1.0 seems to be the safest default; SSLv23 fails in + # >>> mysterious ways: + # >>> https://github.com/docker/docker-py/issues/963 + # Which is why we choose PROTOCOL_TLSv1 + self.ssl_version = ssl.PROTOCOL_TLSv1 + + # "tls" and "tls_verify" must have both or neither cert/key files In + # either case, Alert the user when both are expected, but any are # missing. if client_cert: