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

[ARM] Fix #20842: az bicep: Fix to use requests environment variables for CA bundle #21807

Merged
merged 1 commit into from
Mar 30, 2022

Conversation

wwmoraes
Copy link
Contributor

@wwmoraes wwmoraes commented Mar 25, 2022

Description

Azure CLI relies on the requests python package, which allows users to set custom CA bundle paths through two environment variables: CURL_CA_BUNDLE and REQUESTS_CA_BUNDLE. https://2.python-requests.org/en/master/user/advanced/#ssl-cert-verification

This is useful for cases where the host is behind a MITM proxy that re-signs all SSL traffic for DPI, or due to a corporate policy that defines which CA roots are to be trusted.

Enforcing a hard-coded bundle, like the one provided by the certifi package, only leads users under similar use cases to modify the Python site packages files, which is meant to be controlled only by the package manager and thus it is not a good practice to configure any Python solution.

The proposed change here leverages Python setdefault mechanism available on dictionaries, which allows to set a default value for a key that is not set. This makes any lookups return the default value instead of their usual result (KeyError exception on an index lookup for a missing key, or None on a get method call).

Setting the CURL_CA_BUNDLE environment variable default value to the certifi bundle path results in the following resolution order:

  • REQUESTS_CA_BUNDLE environment variable is used if set
  • CURL_CA_BUNDLE environment variable is used if set
  • certifi.where() path is used otherwise

fixes #20842.

Testing Guide

A clean environment should use the certifi CA bundle path:

env -i az bicep install

If either REQUESTS_CA_BUNDLE or CURL_CA_BUNDLE is set, then it should be picked up:

env -i REQUESTS_CA_BUNDLE=/path/to/cacert1.pem az bicep install
env -i CURL_CA_BUNDLE=/path/to/cacert1.pem az bicep install

If both REQUESTS_CA_BUNDLE and CURL_CA_BUNDLE are set, then it should use REQUESTS_CA_BUNDLE (this is by definition of the requests package).

History Notes

[ARM] Fix #20842: az bicep: Fix to use requests environment variables for CA bundle


This checklist is used to make sure that common guidelines for a pull request are followed.

@ghost ghost added the customer-reported Issues that are reported by GitHub users external to the Azure organization. label Mar 25, 2022
@ghost
Copy link

ghost commented Mar 25, 2022

Thank you for your contribution wwmoraes! We will review the pull request and get back to you soon.

@ghost ghost requested a review from yonzhan March 25, 2022 15:17
@ghost ghost added the Auto-Assign Auto assign by bot label Mar 25, 2022
@ghost ghost requested a review from wangzelin007 March 25, 2022 15:17
@ghost ghost assigned jiasli Mar 25, 2022
@ghost ghost added this to the Mar 2022 (2022-04-06) milestone Mar 25, 2022
@ghost ghost added the Installation label Mar 25, 2022
@ghost ghost requested a review from jiasli March 25, 2022 15:17
@wwmoraes wwmoraes changed the title [Bicep] fix: use environment CA bundle variables [Bicep] fix: Use environment CA bundle variables Mar 25, 2022
@wwmoraes wwmoraes changed the title [Bicep] fix: Use environment CA bundle variables [Bicep] fix: Use requests environment variables for CA bundle Mar 25, 2022
Azure CLI relies on the requests python package, which
allows users to set custom CA bundle paths through two
environment variables: CURL_CA_BUNDLE and REQUESTS_CA_BUNDLE.

This is useful for cases where the host is behind a MITM proxy
that re-signs all SSL traffic for DPI, or due to a corporate
policy that defines which CA roots are to be trusted.

Enforcing a hard-coded bundle, like the one provided by the certifi
package, only forces users under similar use cases to modify the Python
site packages files, which is meant to be controlled only by the package
manager and thus it is not a good practice to configure the tool.
@yonzhan
Copy link
Collaborator

yonzhan commented Mar 26, 2022

Bicep

@yonzhan yonzhan assigned zhoxing-ms and unassigned jiasli Mar 26, 2022
@yonzhan yonzhan removed customer-reported Issues that are reported by GitHub users external to the Azure organization. Installation Auto-Assign Auto assign by bot labels Mar 26, 2022
@Hurvester
Copy link

Could someone check this, please?

@zhoxing-ms
Copy link
Contributor

@shenglol Could you please help to review this PR?

Copy link
Contributor

@shenglol shenglol left a comment

Choose a reason for hiding this comment

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

:shipit:

@zhoxing-ms zhoxing-ms changed the title [Bicep] fix: Use requests environment variables for CA bundle [ARM] Fix #20842: az bicep: Fix to use requests environment variables for CA bundle Mar 30, 2022
@zhoxing-ms zhoxing-ms merged commit e0bb745 into Azure:dev Mar 30, 2022
@jiasli
Copy link
Member

jiasli commented Mar 30, 2022

Please include PR ID in the commit message of e0bb745.

@inaun
Copy link

inaun commented Apr 29, 2022

Has this fix been released? If so, it does not work, still seeing the same error.

@zhoxing-ms
Copy link
Contributor

zhoxing-ms commented Apr 30, 2022

@inaun This PR has been released in version 2.35.0. If you still have the same issue after using 2.35.0+ version of CLI, please create a new Github issue to describe your issue

Comment on lines +112 to +113
os.environ.setdefault("CURL_CA_BUNDLE", certifi.where())
request = urlopen(_get_bicep_download_url(system, release_tag, target_platform=target_platform))
Copy link
Member

Choose a reason for hiding this comment

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

Copying @emitor's comment from e0bb745#r71858253:

Hi @wwmoraes, urlopen does not use the OS environment CURL_CA_BUNDLE as request does. So if you remove the cafile=ca_file parameter this break the command az bicep if you are behind a proxy using a custom CA.

I'm trying to using this at work behind a corporate proxt and does not work anymore and throws the [SSL: CERTIFICATE_VERIFY_FAILED]. I've manually modified the file locally and is working.

In order to do it properly so urlopen does not throw any warnings, you should change it to something like this:

...
import ssl
...
        context = ssl.create_default_context(cafile=certifi.where())
        request = urlopen(_get_bicep_download_url(system, release_tag, target_platform=target_platform), context=context)
...

Would you be able to fix this back please?

Thanks!

Copy link
Member

Choose a reason for hiding this comment

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

In short, urlopen doesn't support REQUESTS_CA_BUNDLE or CURL_CA_BUNDLE and we shouldn't make urlopen support them either.

Comment on lines +146 to +147
os.environ.setdefault("CURL_CA_BUNDLE", certifi.where())
response = requests.get("https://aka.ms/BicepReleases")
Copy link
Member

@jiasli jiasli Mar 31, 2023

Choose a reason for hiding this comment

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

Per https://requests.readthedocs.io/en/latest/user/advanced/#ssl-cert-verification, there is no need to set certifi.where() to CURL_CA_BUNDLE at all.

requests checks CA bundles in following order:

  1. REQUESTS_CA_BUNDLE
  2. CURL_CA_BUNDLE
  3. certifi.where()

If REQUESTS_CA_BUNDLE or CURL_CA_BUNDLE is not set, request by default uses certifi.where().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SSL: CERTIFICATE_VERIFY_FAILED error on "az bicep install" Resurfaced
7 participants