Package management is a feature that Go has been criticized for doing poorly. Before 1.11, go get lacked support for package versioning and reproducible builds. At the time, many useful tools were born in the Go community, such as glide, dep, etc. After 1.11, Go introduced the Go Module, and there was no longer a GOPATH restriction, so you could write projects in any path you wanted, but support for private repositories was not very good at that time. After version 1.13, Go has optimized Go Module again and supports the GOPRIVATE environment variable, which allows you to specify the address of a private repository, making it very easy to use. In the process of using it, you may encounter some problems, so I will summarize the problems I encountered below.

go get

If you run go get your.gitlab.com/pkg/example directly without any setup, you will probably encounter the following error.

1
2
3
4
go get: module your.gitlab.com/pkg/example: git ls-remote -q origin in /go/pkg/mod/cache/vcs/a39fc2dbfb0a9645950d24df5d7e922bb7a6a877aecfe2b20f74b96385a83109: exit status 128:
    fatal: could not read Username for 'https://your.gitlab.com': terminal prompts disabled
Confirm the import path was entered correctly.
If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.

In fact, the error message has already given us the solution, we just need to click https://golang.org/doc/faq#git_https to check it out.

Here is the original article.

Why does “go get” use HTTPS when cloning a repository?

Companies often permit outgoing traffic only on the standard TCP ports 80 (HTTP) and 443 (HTTPS), blocking outgoing traffic on other ports, including TCP port 9418 (git) and TCP port 22 (SSH). When using HTTPS instead of HTTP, git enforces certificate validation by default, providing protection against man-in-the-middle, eavesdropping and tampering attacks. The go get command therefore uses HTTPS for safety.

Git can be configured to authenticate over HTTPS or to use SSH in place of HTTPS. To authenticate over HTTPS, you can add a line to the $HOME/.netrc file that git consults:

1
machine github.com login USERNAME password APIKEY

For GitHub accounts, the password can be a personal access token. Git can also be configured to use SSH in place of HTTPS for URLs matching a given prefix. For example, to use SSH for all GitHub access, add these lines to your ~/.gitconfig:

1
2
[url "ssh://git@github.com/"]
      insteadOf = https://github.com/

Presumably this means that HTTPS is more secure, so the go get command uses HTTPS.

If you want to use HTTPS, then you need to configure the HTTPS username and password.

1
machine github.com login USERNAME password APIKEY

Of course you can also use ssh, which requires modifying your git configuration.

Modify the current user’s ~/.gitconfig and add the following.

1
2
[url "ssh://git@your.gitlab.com/"]
      insteadOf = https://your.gitlab.com/

The same effect can be achieved by executing the following command.

1
git config --global url."git@your.gitlab.com/".insteadof "https://your.gitlab.com/"

After the operation, we can use go get and use go get -v to display the execution log.

GONOPROXY

As we all know, most domestic users set up proxies. If we set up proxies using the GOPROXY environment variable and use private repositories before Go 1.12, we are likely to encounter the following error.

1
2
go get your.gitlab.com/pkg/example: module your.gitlab.com/pkg/example: 
reading https://goproxy.cn/your.gitlab.com/pkg/example/@v/list: 404 Not Found

This is because it is impossible for the proxy service to access our private code repository, so it reports an error 404, and it does not work even with the ssh authentication mentioned above.

After Go 1.13, you can set the environment variable GONOPROXY to specify a domain name without a proxy, with comma-separated values.

GONOSUMDB

go mod needs to checksum the downloaded dependencies, which is fine if your git repository is open, but not if it is a private repository that is not accessible, even on your company’s intranet. It is likely that the checksum will fail with the following error.

1
2
get "your.gitlab.com/pkg/example": found meta tag get.metaImport{Prefix:"your.gitlab.com/pkg/example", VCS:"git", RepoRoot:"https://your.gitlab.com/pkg/example.git"} at //your.gitlab.com/pkg/example?go-get=1
  verifying your.gitlab.com/pkg/example@v0.0.0: your.gitlab.com/pkg/example@v0.0.0: reading https://sum.golang.org/lookup/your.gitlab.com/pkg/example@v0.0.0: 410 Gone

As with proxies, our private repository is not visible to sum.golang.org, so there is certainly no way to perform a security check.

Likewise in Go 1.13 onwards, you can set the GONOSUMDB environment variable to specify the domain name to skip checksums, with support for comma-separated multiple values.

GOPRIVATE

Finally, Go 1.13 also introduced the GOPRIVATE environment variable, which can be set once and for all to automatically skip the proxy server and checksum checks, and the value of this variable also supports comma separation, so you can fill in multiple values, e.g.

1
GOPRIVATE=*.corp.example.com,your.gitlab.com

Of course, after setting GOPRIVATE, you can also control it separately with GONOPROXY and GONOSUMDB.

But we need to pay attention to the problem of GOPRIVATE failure.

For example, if a company has a private repository: your.corp.com, if you set it up like this.

1
2
3
GOPRIVATE=your.corp.com
GOPROXY=https://goproxy.cn 
GONOPROXY=none   

Since the value of GONOPROXY is none, the user will still download all private and shared repositories from the address of GOPROXY, which may still report an error. The same goes for GONOSUMDB, so be aware of this.