Fetching Go Modules via `goproxy` Inside VPN
Posted on Oct 15 2024
I think I finally setup the holy grail of universally being able to fetch-by-proxy go modules through a firewall using https://github.com/goproxy/goproxy
On your internal host (such as your work machine), run the following:
GOPRIVATE=git.company.com GOMODCACHE=~/go goproxy server --address localhost:9981
On your external host (such as a network isolated Linux VM):
ssh -L 9981:localhost:9981 $INTERNALHOST &
GOPROXY=http://localhost:9981,direct go mod tidy
Of course, the tunneling is optional and you can use a non-localhost
--address
when running goproxy server
, but then of course you are dealing
with this proxy being open on the LAN, which may upset security in some cases.
And bam! Now you can fetch go modules as if you’re on the VPN even if you’re not on the VPN.
You can use something like go env -w GOPROXY=http://localhost:9981,direct
to
avoid prefixing all your go
commands with the environment variable. Obviously,
this can cause things to break weirdly if/when the goproxy server
dies or the
tunnel is disconnected. Tread lightly!
One last possible step is that when the proxy machine clones the repo it may try
to do so over HTTPS when you almost certainly want it to use SSH. To avoid this,
you can do something like this in ~/.gitconfig
or ~/.config/git/config
to
force git to use SSH instead of HTTPS:
[url "git@git.example.com:"]
insteadOf = "https://git.example.com"
My full invocation looks something like this:
go install github.com/goproxy/goproxy/cmd/goproxy@latest
# put this cute background job somewhere or `disown`
GOPRIVATE=git.example.com GOMODCACHE=~/go goproxy server --address localhost:58320 &
And then on the client:
# put this cute background job somewhere or `disown`
ssh -L 58320:localhost:58320 $PROXYHOST &
go env -w GOPROXY=http://localhost:58320,direct
go mod tidy