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

cmd/go: "go get gopkg.in/yaml.v2" will run into "x509: certificate signed by unknown authority" behind corporate proxy #18519

Closed
iamzhout opened this issue Jan 5, 2017 · 12 comments

Comments

@iamzhout
Copy link

iamzhout commented Jan 5, 2017

What version of Go are you using (go version)?

both tested on:
go version go1.6.4 linux/amd64
go version go1.7.4 linux/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/zhout/paas/k8s_prjroot"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GO15VENDOREXPERIMENT="1"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"

What did you do?

export http_proxy=http://my-corporate-proxy:8080
export https_proxy=http://my-corporate-proxy:8080
go get -v -u gopkg.in/yaml.v2

What did you expect to see?

the repository should be got successfully.

What did you see instead?

Fetching https://gopkg.in/yaml.v2?go-get=1
https fetch failed: Get https://gopkg.in/yaml.v2?go-get=1: x509: certificate signed by unknown authority
package gopkg.in/yaml.v2: unrecognized import path "gopkg.in/yaml.v2" (https fetch: Get https://gopkg.in/yaml.v2?go-get=1: x509: certificate signed by unknown authority)

while if I add -insecure option, it will be ok.

go get -v -u -insecure gopkg.in/yaml.v2
Fetching https://gopkg.in/yaml.v2?go-get=1
https fetch failed: Get https://gopkg.in/yaml.v2?go-get=1: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
Fetching http://gopkg.in/yaml.v2?go-get=1
Parsing meta tags from http://gopkg.in/yaml.v2?go-get=1 (status code 200)
get "gopkg.in/yaml.v2": found meta tag main.metaImport{Prefix:"gopkg.in/yaml.v2", VCS:"git", RepoRoot:"https://gopkg.in/yaml.v2"} at http://gopkg.in/yaml.v2?go-get=1
gopkg.in/yaml.v2 (download)
gopkg.in/yaml.v2

But as to 3rd party tool like glide, there is no global option to add -insecure currently for glide update or glide install command, I think if go get can resolve this X509 issue, it would be of much help!

@iamzhout
Copy link
Author

iamzhout commented Jan 5, 2017

#18508 (comment)

davecheney: @iamzhout it looks like your employer is MITM'ing your SSL communications.
Go get is just a wrapper over git, I recommend git cloning that repository directly.

@davecheney you're right, the https cert will be replaced over company policy, so ... but anyway, I think this should be quite common, maybe.

but the point is that there is no problem if I use git clone directly, if go get is 'just' a wrapper, I would expecte it to work fine also.

git clone -v https://gopkg.in/yaml.v2.git
Cloning into 'yaml.v2'...
POST git-upload-pack (290 bytes)
remote: Counting objects: 921, done.
remote: Total 921 (delta 0), reused 0 (delta 0), pack-reused 921
Receiving objects: 100% (921/921), 1.16 MiB | 0 bytes/s, done.
Resolving deltas: 100% (572/572), done.
Checking connectivity... done.

@iamzhout iamzhout changed the title "go get gopkg.in/yaml.v2" will run into "x509: certificate signed by unknown authority" behind corporate proxy cmd/go: "go get gopkg.in/yaml.v2" will run into "x509: certificate signed by unknown authority" behind corporate proxy Jan 5, 2017
@rsc
Copy link
Contributor

rsc commented Jan 5, 2017

go get is not "just" a wrapper for git. one step is to invoke git but the first step is to fetch https://gopkg.in/yaml.v2.git to learn where that comes from. The certs that 'go get' is finding do not include the company MITM cert. On Linux the cert list is:

// Possible certificate files; stop after finding one.
var certFiles = []string{
        "/etc/ssl/certs/ca-certificates.crt",                // Debian/Ubuntu/Gentoo etc.
        "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
        "/etc/pki/tls/certs/ca-bundle.crt",                  // Fedora/RHEL 6
        "/etc/ssl/ca-bundle.pem",                            // OpenSUSE
        "/etc/pki/tls/cacert.pem",                           // OpenELEC
}

It sounds like whichever of those files is on your system does not include the company CA. If it did, go get would succeed at the https fetch.

@rsc
Copy link
Contributor

rsc commented Jan 5, 2017

Actually, I see your $https_proxy above now. I don't know why go get would not be using that.

@bradfitz
Copy link
Contributor

bradfitz commented Jan 5, 2017

@rsc, cmd/go/http.go doesn't set ProxyFromEnvironment:

// impatientInsecureHTTPClient is used in -insecure mode,                                                                                    
// when we're connecting to https servers that might not be there                                                                            
// or might be using self-signed certificates.                                                                                               
var impatientInsecureHTTPClient = &http.Client{
        Timeout: 5 * time.Second,
        Transport: &http.Transport{
                TLSClientConfig: &tls.Config{
                        InsecureSkipVerify: true,
                },
        },
}       

@bradfitz
Copy link
Contributor

bradfitz commented Jan 5, 2017

That is, we have different proxy behavior in --insecure mode. I'll send a CL.

@gopherbot
Copy link

CL https://golang.org/cl/34818 mentions this issue.

gopherbot pushed a commit that referenced this issue Jan 5, 2017
Be consistent on whether the http proxy environment variables are
respected regardless of whether -insecure is used.

Updates #18519

Change-Id: Ib157eaacfd342dd3bfcd03e64da18c98c609cae3
Reviewed-on: https://go-review.googlesource.com/34818
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
@iamzhout
Copy link
Author

iamzhout commented Jan 6, 2017

Thanks @bradfitz for your quick fix.

While seems this fix only takes effect when -insecure flag provided? Doesn't this already work fine as I mentioned earlier that if giving -insecure option, the go get is ok?

I also have tested using the latest nightly build(?),

➜ /usr/local >go get -u -v -insecure gopkg.in/yaml.v2
Fetching https://gopkg.in/yaml.v2?go-get=1
https fetch failed: Get https://gopkg.in/yaml.v2?go-get=1: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
Fetching http://gopkg.in/yaml.v2?go-get=1
Parsing meta tags from http://gopkg.in/yaml.v2?go-get=1 (status code 200)
get "gopkg.in/yaml.v2": found meta tag main.metaImport{Prefix:"gopkg.in/yaml.v2", VCS:"git", RepoRoot:"https://gopkg.in/yaml.v2"} at http://gopkg.in/yaml.v2?go-get=1
gopkg.in/yaml.v2 (download)
gopkg.in/yaml.v2
➜ /usr/local >go get -u -v gopkg.in/yaml.v2
Fetching https://gopkg.in/yaml.v2?go-get=1
https fetch failed: Get https://gopkg.in/yaml.v2?go-get=1: x509: certificate signed by unknown authority
gopkg.in/yaml.v2 (download)
➜ /usr/local >go version
go version 1.7rc1-nightly-a1110c39301b21471c27dad0e50cdbe499587fc8 linux/amd64

Does above log means go get -u -v gopkg.in/yaml.v2 is successful?

@iamzhout
Copy link
Author

iamzhout commented Jan 6, 2017

@rsc

It sounds like whichever of those files is on your system does not include the company CA. If it did, go get would succeed at the https fetch.

Actually I have already imported related certs into /etc/ssl/certs/ca-certificates.crt before submitting this issue, and unfortunately without luck. Below is the steps what I do:

  1. open firefox, and use the same proxy above: http://my-corporate-proxy:8080
  2. navigate to "https://gopkg.in/yaml.v2", click upper left lock icon, and open "View Certificate"
  3. export the cert to /usr/local/share/ca-certificates
  4. run update-ca-certificates, and double check that /etc/ssl/certs/ca-certificates.crt does include this new cert

So seems go get doesn't recognise local certs? and still reports "certificate signed by unknown authority".

@bradfitz
Copy link
Contributor

bradfitz commented Jan 6, 2017

@iamzhout, I don't think your nightly build was new enough. The bug fix was that -insecure mode previously did not respect your $HTTP_PROXY (etc) environment variables. Now it does.

@iamzhout
Copy link
Author

iamzhout commented Jan 10, 2017

@bradfitz I have built and tested latest golang code on master branch. As the fix says it will only take effect when using -insecure option with go get, which doesn't resolve my problem :(

@rsc I just digged a little bit deeper to find out the root cause. It seems that the original gopkg site cert will be replaced by a dynamically generated cert which, instead of a constant one, will be different every single minute in validation start/end time fields, as shown in below picture.

20170110-gopkg-in-cert

So it turns out that the problem is not in golang's X509 verification algorithm which will do byte comparison using bytes.Equal, but the cert itslef.

I will try to contact IT guys in company to see if the troublesome dynamic cert policy could be changed, though most probably not.

Thanks for your help.

@bradfitz
Copy link
Contributor

Okay, closing.

@iamzhout
Copy link
Author

Just to update that I missed to understand https cert quite well, and added leaf cert previously, not company cert which @rsc already pointed out . After I added the root company cert, problem got resolved perfectly.

@golang golang locked and limited conversation to collaborators Jan 11, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants