Golang Default GOPROXY Hidden Networking Requirements

Nick Gibbon
Pareture
Published in
3 min readMay 16, 2022

--

Brief overview of Golang GOPROXY defaults and some not well known domain allowlist requirements.

Background

I have very little experience with Golang. I need to read it occasionally to work out where things are going weird because I operate a lot of CNCF and HashiCorp products.

I was recently running some of the Kubernetes performance tooling (some of which depend on Go) and ran in to an issue that doesn’t affect many use-cases and therefor is not well-known.

GOPROXY

By default Golang modules are downloaded via a proxy — for all the benefits of a proxy.

GOPROXY=https://proxy.golang.org,direct

This means that when downloading modules Go should use the proxy and if the module is not found then go direct to the source.

The default proxy is a closed-source system ran by the Go Team / Google.

You are able to use other proxies and there are other flags to ensure that you can download public and private modules from specific proxies or directly as you require.

Problem

Given this is how things work then you might assume you only need to network with the proxy.

Nope!

It turns out that the proxy sometimes returns 302 redirects to Google Cloud Storage for module archives.

Which means Networking Errors if you can not connect to GCS.

Example: No Redirect

curl --include 'https://proxy.golang.org/github.com/google/go-querystring/@v/v1.0.0.zip'HTTP/2 200

Example: With Redirect

curl --include 'https://proxy.golang.org/google.golang.org/api/@v/v0.4.0.zip'HTTP/2 302access-control-allow-origin: *location: https://storage.googleapis.com/proxy-golang-org-prod/3a4011dc517dc6d3-google.golang.org:api-v0.4.0.zip?Expires=1652615465&GoogleAccessId=gcs-urlsigner-prod%40golang-modproxy.iam.gserviceaccount.com&Signature=qX7%2FNYXKrHJXdwJ8tR7WyMZdHPqw%2FAMvaTPAIVkkizqJ5K2mRXS1cFUmyIYhO%2FF%2Fn4XesbnV7Xk5pPtKvrIWS4%2FNiN1akqKz2UA0EHgimGcANaWEbtSX3mBXnpXG4QPGSh56VphsNzkt3pZnqqgkzPE6chE27XlKABMSTV1vrWwz2OU9mhr3Gs6mTRzS2M0h6aJN1ZOrfNL5%2BfRM7HhM0Nkbif5fUM5PaAX%2FpsinSEY%2Byf04yH4UjFQ0x2cuy3FQsTLR%2FxrQJa3%2BD%2FjO7F3AD1tY%2FoK%2B7%2BJtOXDtzX1dAogkGv6PylDWpLS2HVJtAx%2F4SS047tbOsSAxQpRFu41X9Q%3D%3D

See: https://storage.googleapis.com/proxy-golang-org-prod/* .

Resolution

This may not matter to many users but it is knowledge that’s needed if you are in an environment which utilises domain allowlisting.

# Domain Allowlist## Go Proxy
proxy.golang.org
sum.golang.org
index.golang.org
### Go Proxy Storage
storage.googleapis.com

Request

This problem seems to have caught the Go Team themselves off-guard at one time but there is very little other mention of it around:

This issue is no biggie. But having looked around the documentation I can not find any reference to the proxy working like this. Given that this is a technical tooling system and not a general consumer service I think the dependency on the external service should be made explicit somewhere.

--

--

Nick Gibbon
Pareture

Software engineer & manager in cloud infrastructure, platforms & tools.