Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefer the stdlib SSLContext over urllib3 context #32053

Merged
merged 1 commit into from Oct 24, 2017

Conversation

abadger
Copy link
Contributor

@abadger abadger commented Oct 23, 2017

We do not go through the effort of finding the right PROTOCOL setting if
we have SSLContext in the stdlib. So we do not want to hit the code
that uses PROTOCOL to set the urllib3-provided ssl context when
SSLContext is available. Also, the urllib3 implementation appears to
have a bug in some recent versions. Preferring the stdlib version will
work around that for those with Python-2.7.9+ as well.

Fixes #26235
Fixes #25402
Fixes #31998

@sivel, if you have time, please review this.

ISSUE TYPE
  • Bugfix Pull Request
COMPONENT NAME

lib/ansible/module_utils/urls.py

ANSIBLE VERSION
devel, 2.4, 2.3 (but I don't know if we'lll backport to 2.3.x)

We do not go through the effort of finding the right PROTOCOL setting if
we have SSLContext in the stdlib.  So we do not want to hit the code
that uses PROTOCOL to set the urllib3-provided ssl context when
SSLContext is available.  Also, the urllib3 implementation appears to
have a bug in some recent versions.  Preferring the stdlib version will
work around that for those with Python-2.7.9+ as well.

Fixes ansible#26235
Fixes ansible#25402
Fixes ansible#31998
@sivel sivel self-requested a review October 23, 2017 20:30
@ansibot ansibot added affects_2.5 This issue/PR affects Ansible v2.5 bugfix_pull_request module_utils/urls needs_triage Needs a first human triage before being processed. support:core This issue/PR relates to code supported by the Ansible Engineering Team. labels Oct 23, 2017
@abadger abadger added this to To be cherrypicked (rc only) in 2.4.x Blocker List Oct 23, 2017
@abadger abadger moved this from To be cherrypicked (rc only) to TODO: Next release in 2.4.x Blocker List Oct 23, 2017
@ansibot ansibot added the needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. label Oct 23, 2017
if HAS_URLLIB3_PYOPENSSLCONTEXT:
if HAS_SSLCONTEXT:
context = create_default_context()
elif HAS_URLLIB3_PYOPENSSLCONTEXT:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this. It should have been done this way to start with.

Copy link
Member

@sivel sivel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. The only thing I wonder is whether we could do a try/except around importing tlsv1_2 to use it if available, failing back to v1

@alikins
Copy link
Contributor

alikins commented Oct 23, 2017

There is similar code around the CustomHTTPSConnection (https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/urls.py#L365). Should it be updated as well?

@sivel
Copy link
Member

sivel commented Oct 23, 2017

There is similar code around the CustomHTTPSConnection (https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/urls.py#L365). Should it be updated as well?

That seems to be in the correct order.

@abadger
Copy link
Contributor Author

abadger commented Oct 24, 2017

@sivel I think we could use a try: except in the imports but it would still need the ctypes code in addition. The vanilla stdlib introduces SSLContext in the same version as it introduces PROTOCOL_TLSv1_2 (2.7.9). I know that RHEL7 backported those changes to python-2.7.5 but it backported both changes. So right now the check for if not HAS_SSLCONTEXT is also a hidden (version-based) check for PROTOCOL_TLSv1_2. If we added a try: except to import PROTOCOL_TLSv1_2, it would end up being in addition to the SSLCONTEXT check.

We still end up using ctypes as the next step as that check finds out if the underlying openssl will support TLS-1.1 and TLS-1.2. If it does, then we set the PROTOCOL to ssl.PROTOCOL_SSLv23 which allows the library to negotiate the best version that both the client and server support. If it doesn't, then we leave the protocol setting at ssl.PROTOCOL_TLSv1 which at least prevents ssl2/3 from being used. So a try: except will help us out if there's platforms which have PROTOCOL_TLSv1_2 exposed in the python layer but do not implement SSLContext.

@abadger
Copy link
Contributor Author

abadger commented Oct 24, 2017

@alikins combining the code is not needed because the order is correct in the second instance but it does look tantaliyzingly like duplicate that could be combined. The _make_context() helper is not using self so we could move that out to a toplevel helper function. One is using context.load_verify_locations(to_add_ca_cert_path) while the other is using context.load_cert_chain(self.cert_file, self.key_file) though. I don't know what changing that code would do so I'm loathe to change that in a bugfix. Perhaps that's something someone can research and refactor in devel if they have time.

@abadger abadger merged commit 725ae96 into ansible:devel Oct 24, 2017
@abadger abadger deleted the fix-ssl-context-creation branch October 24, 2017 14:22
@sivel
Copy link
Member

sivel commented Oct 24, 2017

I think that makes sense. We should move forward with this as is.

As for TLS versions, I suppose I speak mostly from experience on Mac. Although SSLContext is available on Mac, PROTOCOL_TLSv1_2 is not, at least not on macOS 10.12 running Python 2.7.10.

@abadger
Copy link
Contributor Author

abadger commented Oct 24, 2017

Interesting. I wonder if that means the underlying openssl on MacOS 10.12 also doesn't support PROTOCOL_TLSv1_2.

@abadger
Copy link
Contributor Author

abadger commented Oct 24, 2017

Merged to devel and cherry-picked to temp-staging-post-2.4.1 This fix will be present in the 2.4.2beta1 release but not in the 2.4.1 release that's due out later this week.

@abadger abadger moved this from TODO: Next release to Done in 2.4.2 in 2.4.x Blocker List Oct 26, 2017
@samdoran samdoran removed the needs_triage Needs a first human triage before being processed. label Oct 26, 2017
sf-project-io pushed a commit to softwarefactory-project/sf-config that referenced this pull request Oct 27, 2017
There is an issue with ansible 2.4.0 to validate certs with
get_url. The validation fails if liburl3 is present on the server
(with pike version, it's functional with newton version)

issue: ansible/ansible#32053

The statement could be remove when ansible 2.4.2 will be available
on centos 7

Change-Id: I25219b24c85a74672a0c56da58f913d53ffb4241
Depends-on: I33a8536f51078d56427b2bef38dc11a9488390d6
mattt416 added a commit to rcbops/rpc-maas that referenced this pull request Dec 12, 2017
In #414 we tried making this include conditional, however this playbook
is still being included when run w/ older versions of ansible (1.9.6
as an example).

Instead, we switch the two `Add influxdata apt-keys` tasks to using
the shell module.  Using ansible's apt_key fails w/ hosts using SNI
(as https://repos.influxdata.com/ appears to be using) because:

1. ansible/ansible#32053 (not backported to
   2.3.2.0)
2. ansible 1.9.6 doesn't seem to support SNI on Trusty (python < 2.7.9)
mattt416 added a commit to rcbops/rpc-maas that referenced this pull request Dec 12, 2017
In #414 we tried making this include conditional, however this playbook
is still being included when run w/ older versions of ansible (1.9.6
as an example).

Instead, we update maas_influxdata_key to have an id and keyserver key.
This allows apt_key to work since it doesn't need to speak to
https://repos.influxdata.com/ directly.  Using ansible's apt_key with
https://repos.influxdata.com/ fails because of SNI and:

1. ansible/ansible#32053 (not backported to
   2.3.2.0)
2. ansible 1.9.6 doesn't seem to support SNI on Trusty (python < 2.7.9)
cloudnull pushed a commit to rcbops/rpc-maas that referenced this pull request Dec 13, 2017
In #414 we tried making this include conditional, however this playbook
is still being included when run w/ older versions of ansible (1.9.6
as an example).

Instead, we update maas_influxdata_key to have an id and keyserver key.
This allows apt_key to work since it doesn't need to speak to
https://repos.influxdata.com/ directly.  Using ansible's apt_key with
https://repos.influxdata.com/ fails because of SNI and:

1. ansible/ansible#32053 (not backported to
   2.3.2.0)
2. ansible 1.9.6 doesn't seem to support SNI on Trusty (python < 2.7.9)
@abadger
Copy link
Contributor Author

abadger commented Feb 23, 2018

Cherry-picked to stable-2.3 for a 2.3.4 release.

@ansibot ansibot added bug This issue/PR relates to a bug. and removed bugfix_pull_request labels Mar 6, 2018
@dagwieers dagwieers added the crypto Crypto community (ACME, openssl, letsencrypt) label Feb 7, 2019
@ansible ansible locked and limited conversation to collaborators Apr 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.5 This issue/PR affects Ansible v2.5 bug This issue/PR relates to a bug. crypto Crypto community (ACME, openssl, letsencrypt) module_utils/urls needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. support:core This issue/PR relates to code supported by the Ansible Engineering Team.
Projects
No open projects
2.4.x Blocker List
Done in 2.4.2
6 participants