rust-lang / cargo

The Rust package manager
https://doc.rust-lang.org/cargo
Apache License 2.0
12.26k stars 2.31k forks source link

Cargo doesn't respect git's http.sslverify #1180

Open alexcrichton opened 9 years ago

alexcrichton commented 9 years ago

This used to be supported in libgit2, but it was removed. We should probably add back in explicit support somewhere.

cc #636, this has come up once or twice there.

alexcrichton commented 9 years ago

This will likely be done by binding the certificate_check callback in remote_callbacks.rs of git2-rs and then using that in Cargo itself

yug commented 8 years ago

It seems a little bit complicated.

We are behind the R&D proxy, the company classifies the connection zones, we are unfortunately in a zone we can git clone the outside code, no write access to outside.

Cargo should get work by hacked locally, however, the process is that it firstly download a pre-built binary, that init binary couldn't work, so, all things blocked. I am not sure Cargo support cross-compile, if it does not we had to find a linux 64bit box without proxy access problem, build a hacked cargo, substitute the pre-built with that hacked, then get whole things work.

BTW, there should be configuration item to tell cargo to ignore the SSL_certificate_check, rather than people to hack an ad-hoc version

The problem is not solved, I will try it and update feedback here

the-shank commented 8 years ago

@yug any updates on this one? I am behind a http proxy and am unable to use cargo

thebitllc commented 8 years ago

I hardcoded the hostnames on my windows box and it worked with tinyproxy/proxifier:

c:\windows\system32\drivers\etc\hosts

174.129.244.175 www.crates.io crates.io s3-us-west-1-r-w.amazonaws.com

alexcrichton commented 8 years ago

@thebitllc hm that's interesting, if you don't have that hardcoding, does crates.io resolve to a different IP than it normally does?

chrisxue815 commented 8 years ago

I managed to bypass this problem by setting up a crates.io proxy and a local index repo. See detailed description in chrisxue815/crates.io-proxy.

guillon commented 8 years ago

Related issue on my side, actually my company has a HTTP/HTTPS proxy service which fakes SSL certificates for doing HTTPS session monitoring (i.e. decrypts https on the fly). To achieve this the proxy provider fakes https certificates by returning its own certificate to the client. This is quite unfortunate and forces us to always do HTTPS fetches with no server certificate checks.

Hence it would be great to have a cargo option similar to the --no-check-certificate flag of wget (or --insecure flag of curl, or as mentionned, sslVerify=false configuration of git) when downloading from crates.io. Whatever the implementation in the background, I guess it would be better to have the flag honored independently of the actual git config as the problem is not specific to git fetches, but also to bare downloads.

alexcrichton commented 8 years ago

One question here is how Cargo may want to export this. It'd undeniably pretty questionable security practice to ignore certificate checks, but the use cases brought up here are indeed legitimate. We may want to do something beyond http.sslVerify or the GIT_SSL_NO_VERIFY environment variable (e.g. also require cargo build --insecure), but if git itself has this sort of configuration then we arguably should just go ahead and respect it as well

the-shank commented 8 years ago

My case is the exact same as @guillon ... Behind a company wide proxy which fakes SSL certificates and am unable to use (and to ask others to use) cargo. Will give the crates.io-proxy thing a go but still, it would be so much better if this is resolved.

guillon commented 8 years ago

@alexcrichton, I guess that if one provides a --insecure (or --no-check-certificate) flag, it would be natural for the user to expect that cargo will force the skip of certificate check for all transport connection initiated (git, curl or whatever application level client used by cargo to get artifacts from the network). Hence I guess that if this flag is provided it should force this setting for file download and git fetches initiated as part of the cargo command. Thus, actually overriding the defauly git setting if any or download client setting if any.

If, independently of this flag, cargo uses a git client which honors the git configuration, no issue with this, i.e. the user may expect that if he sets a git configuration a git client may honor it. It is not cargo responsibility in this case. Same for instance if cargo would explicitly mention that the download client is curl (I don't know actually), in this case the ~/.curlrc configuration could be also used by the user.

In summary, it would be good if cargo uses git/download libraries that honor "standard" git/download configurations. But in any case it seems to me that providing a flag and thus forcing the behavior in anycase is a must have and more maintainable solution (i.e. it becomes a feature of cargo itself and thus gives a guarantee of reliability).

aldanor commented 8 years ago

@the-shank @guillon Ditto, same case here, our company-wide proxy fakes SSL certificates, so we are basically forced to use wget --no-check-certificate, curl --insecure, etc, and sslVerify = false for git. And then of course it's a major PITA when a library/package/build systen doesn't comply with the configuration of standard tools like git.

I would, too, expect cargo to use whatever's listed in git configuration by default (if the user configured it in some specific way, that's the ground truth?), but maybe also provide a way to manually override this setting (--insecure) explicitly.

alexcrichton commented 8 years ago

I've pushed this up as https://github.com/rust-lang/cargo/pull/2408

guillon commented 8 years ago

Great. Note though, that this does not solve the file download transport as mentionned above, only the git transport.

This issue was initially related to the git config only thus the proposed fix seems sufficient for this issue, should we create another issue for the file download case?

For instance with the revision from pull request #2408, on a network with faked certificates: $ cargo --version cargo 0.9.0 (879766a 2016-02-23) $ cargo build --verbose Downloading bitflags v0.3.3 unable to get packages from source

Caused by: failed to download package bitflags v0.3.3 from https://crates.io/api/v1/crates/bitflags/0.3.3/download

Caused by: Peer certificate cannot be authenticated with given CA certificates

alexcrichton commented 8 years ago

@guillon indeed! Out of curiosity, do you know if there's standard environment variable/config file configuration for curl to ignore certificates? I know there's a flag, but I'd hope to avoid a flag for now...

guillon commented 8 years ago

@alexcrichton I do not now for env vars. Though, you have a ~/.curlrc file with the insecure option set as in: $ cat $HOME/.curlrc insecure

The curl command line will read it. Note though that while the command line curl honors it, I'm not sure whether libcurl does it also.

aldanor commented 8 years ago

Yea, the best you can do is probably see if ~/.curlrc has an insecure line in it. I don't think curl picks up any environment variables.

alexcrichton commented 8 years ago

Those who are running into this problem, one question that came up when @wycats and I were talking about this was why can't a local CA root be added? This is so blatantly a bad security practice it seems like the "standard way" of doing this would be for companies to install some trusted root CA which Cargo should then used to verify connections.

guillon commented 8 years ago

Yes. Actually the two cases are

In the second case, indeed, one should install the root CA to solve the issue or the company IT should do it. Still, it remains more complicated when trying to set up containers or VMs, i.e. need a specific case for providing the root CA and installing it in the container, etc... Thus we tend to go the easier way, indeed, and deactivate certs checks when possible for non production work. => the absurd idea of replacing real certs by actually making man-in-the-middle "the security guarant" lead us to absurdities also...

alexcrichton commented 8 years ago

It was also pointed out that we could also make it easier to use a custom store of certificates through standard mechanisms if modifying the "root store" is too hard:

aligature commented 8 years ago

I'm new to rust, but I'm coming from the perspective of just trying to experiment / introduce it in our corporate environment. We have the same HTTPS proxy substituting certificates issue that's presented above.

The strategy of adding the private CA into the right spots in the OS makes sense in general, but isn't always practical in a corporate environment. This is true for policy reasons, not just technical. In our case, we don't have root access to our machines and trying to convince teams of people to make certificate changes for a "language experiment" is definitely an uphill battle. In the end, lack of an alternative solution just increases the barrier to entry for trying rust out.

From my point of view, either allowing me to force disable the certificate check or side load and point at our private CA certificate file would be workable solutions.

aldanor commented 8 years ago

I'm in exactly the same spot, was trying to introduce Rust to the team at work until we've hit this issue -- without root access (as is quite often the case) it's too much of a hassle to fix in a corporate environment and in some cases it's just plain implausible. This is pretty much the only reason we had to give up on Rust for now, at least until there's a solution that works (and doesn't require root rights).

lilianmoraru commented 8 years ago

I am also in a corporate environment. On Linux it works through the proxy but on Windows it doesn't. On Windows we use "wpad.dat"(Web Proxy Autodiscovery), even git clone doesn't work on Windows(with http_proxy and https_proxy setup)... Web browsers work all ok. Tried to call cargo(from MSYS2) with http_proxy=[the proxy] https_proxy=[the proxy] cargo build and it doesn't work.

the-shank commented 8 years ago

@alexcrichton I understand that support for using cargo behind company wide proxy that fakes SSL Certificates isn't going to land into cargo as it is insecure practice. However, we (as in me) could fork cargo and modify that fork to support working behind company wide proxies. This would atleast enable folks like me (and @guillon, @aldanor, @aligature etc.) to work with rust and introduce it at our work places.

The issue is that I am not very familiar with cargo. Could you give some pointers as to how to go about this.

We can even name this fork "cargo-insecure" :wink:

apaprocki commented 8 years ago

@alexcrichton What are the next steps for adding support for alternative cert stores as mentioned in https://github.com/rust-lang/cargo/issues/1180#issuecomment-200605114 ?

alexcrichton commented 8 years ago

@apaprocki Cargo should already respect platform-specific conventions like the environment variables SSL_CERT_FILE and SSL_CERT_DIR, so it may just be a matter of configuring those. Otherwise for a more cross-platform solution it'll likely involve binding libcurl's certificate information and then adding Cargo-specific configuration to inform libcurl of the various possible certificate stores.

DemiMarie commented 8 years ago

Using a company-wide proxy is not necessarily insecure, provided that the proxy checks TLS certificates AND the proxy's certificate is on the client machines.

In the relevant cases here, the proxy's certificate is known, so there should be a way to tell Cargo to use it.

alexcrichton commented 8 years ago

@DemiMarie yeah I think that's definitely the next step to take on this issue, ensuring that you can configure the certificates that Cargo uses and it then communicates that to all of its components. It's also be great to read this configuration from a standard location if it's already there as well.

worker2345234 commented 7 years ago

Very said that it is so complicated to use cargo behind our company wide proxy. I set up a localhost cntlm proxy for authentification. git works fine together with the cntlm, but still I need "sslVerify=false" in the git config.

I guess rust will have a serious problem to get used in company environements. Should be possible to give rust a quick try without struggeling around with proxys and certificates. By the way I don't understand why cargo shall be more secure than git...

alexcrichton commented 7 years ago

Ok, I've opened a PR (https://github.com/rust-lang/cargo/pull/2917) for adding http.cainfo config which should allow configuring Cargo to use a specific CA bundle for HTTP connections. If Cargo is then configured with an HTTP proxy, then all traffic should be routed with that cainfo information.

If you're on Linux you can also do that today by setting the SSL_CERT_FILE environment variable pointing at your cainfo file, but that won't work on OSX and Windows as OpenSSL isn't used there.

alexcrichton commented 7 years ago

Now that https://github.com/rust-lang/cargo/pull/2917 is merged, if anyone runs into this issue, you can try to add:

[http]
cainfo = "path/to/cert.pem"

to your .cargo/config file (probably next to http.proxy. I've tested this on OSX/Linux, but I suspect Windows will work as well!

yoava333 commented 7 years ago

@alexcrichton unfortunately Windows doesn't work with the new cainfo option. Looking at the source it seems that CURLOPT_CAINFO is not supported with winssl. I've tried to install the certificate (tested with chrome) but cargo is still unable to download crates. I've tested this on windows 10 (10586.494) with cargo 0.13.0-nightly (c205132 2016-08-09).

alexcrichton commented 7 years ago

Ah yeah I've since learned that unfortunately Windows handles certificate trust in a very different fashion so this operation is a nop in curl on Windows.

On Sunday, August 14, 2016, yoava333 notifications@github.com wrote:

@alexcrichton https://github.com/alexcrichton unfortunately Windows doesn't work with the new cainfo option. Looking at the source it seems that CURLOPT_CAINFO is not supported with winssl. I've tried to install the certificate (tested with chrome) but cargo is still unable to download crates. I've tested this on windows 10 (10586.494) with cargo 0.13.0-nightly ( c205132 https://github.com/rust-lang/cargo/commit/c205132c6ff66babd0eb741e08363f1d79d77eba 2016-08-09).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rust-lang/cargo/issues/1180#issuecomment-239668595, or mute the thread https://github.com/notifications/unsubscribe-auth/AAD95BTiEvq0yY0T8EfP7OPzeFiN0it5ks5qfvskgaJpZM4DTdrr .

petrochenkov commented 7 years ago

So, http.cainfo wants a Certificate Authority bundle to point to. In case you are wondering "what on earth is a 'Certificate Authority bundle' and where do I take one?", the working answer may be* the curl's site (cacert.pem).

* At least if you are on a server with sufficiently old version of some enterprise Linux, in this case the proxy may be a red herring. (I spent too much time on this today.)

dwijnand commented 5 years ago

With the "git the cli" config option (I forget what it is exactly) available as an alternative, do we still care to resolve this anyways?

alexcrichton commented 5 years ago

I think we'll still want to consider this yeah for all of Cargo's other interactions, as there's often https issues with crates.io as well

lihz6 commented 4 years ago

If git is working, then open ~/.cargo/config and write:

[net]
git-fetch-with-cli = true

https://doc.rust-lang.org/cargo/reference/config.html