# 内网goproxy服务搭建配置

# goproxy是什么

goproxy是go模块代理服务,主要用来加速获取go模块。官方默认的proxy为:https://proxy.golang.org (opens new window), 国内主要使用的proxy是由七牛云提供的https://goproxy.cn/ (opens new window)

# 为什么要在内网搭建goproxy服务

  • 内网自建的goproxy不仅可以访问公网的模块,还可以访问内网的 git server
  • 缓存业务用到的公网第三方模块,防止公网仓库变更或者消失,导致线上编译失败或者紧急回退失败
  • 防止公司内部开发人员配置不当造成 import path 泄露
  • cache热点依赖,提升代码编译速度等

# 搭建流程(我们以ubuntu系统为例进行安装。primary为goproxy机器,huge-elk为研发机器)

# golang安装

通过国内go资源网站studygolang下载安装:https://studygolang.com/dl (opens new window)

## 下载对应系统的golang
root@primary:~# wget https://studygolang.com/dl/golang/go1.19.2.linux-amd64.tar.gz

## 解压到指定目录
root@primary:~# tar zxvf go1.19.2.linux-amd64.tar.gz -C /usr/local

## 将go命令添加到/usr/bin
root@primary:/usr/bin# ln /usr/local/go/bin/go -s /usr/bin/go

## 查看go命令是否安装成功
root@primary:~# go version
go version go1.19.2 linux/amd64

# git安装

ubuntu默认已经安装git。如未安装,请通过官网下载安装:https://git-scm.com/downloads (opens new window)

# 通过 git version命令来查看是否安装成功
root@primary:~# git version
git version 2.34.1

# goproxy安装

## 拉取goproxy代码
root@primary:~# git clone https://github.com/goproxyio/goproxy.git
Cloning into 'goproxy'...
remote: Enumerating objects: 530, done.
remote: Counting objects: 100% (27/27), done.
remote: Compressing objects: 100% (21/21), done.
remote: Total 530 (delta 10), reused 13 (delta 6), pack-reused 503
Receiving objects: 100% (530/530), 139.72 KiB | 266.00 KiB/s, done.
Resolving deltas: 100% (225/225), done.

## 安装make
root@primary:~/goproxy# apt install make -y

## make安装goproxy
root@primary:~# cd goproxy
root@primary:~/goproxy# make

go: downloading github.com/prometheus/client_golang v1.9.0
go: downloading golang.org/x/mod v0.4.0
go: downloading github.com/goproxyio/windows v0.0.0-20191126033816-f4a809841617
go: downloading github.com/prometheus/client_model v0.2.0
go: downloading github.com/prometheus/common v0.15.0
go: downloading golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
go: downloading github.com/beorn7/perks v1.0.1
go: downloading github.com/cespare/xxhash/v2 v2.1.1
go: downloading github.com/golang/protobuf v1.4.3
go: downloading github.com/prometheus/procfs v0.2.0
go: downloading golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e
go: downloading github.com/matttproud/golang_protobuf_extensions v1.0.1
go: downloading google.golang.org/protobuf v1.23.0
go: downloading github.com/google/go-cmp v0.4.0

## 将goproxy二进制文件移动到指定目录
## 安装完成后goproxy下会多出bin目录,将bin目录移动到/usr/local/goproxy
root@primary:~/goproxy# mkdir /usr/local/goproxy
root@primary:~/goproxy# mv ./bin /usr/local/goproxy/
root@primary:~/goproxy# cd /usr/local/goproxy/bin/
root@primary:/usr/local/goproxy/bin# ll
total 8464
drwxrwxr-x 2 root root    4096 Oct 31 15:15 ./
drwxr-xr-x 3 root   root      4096 Oct 31 15:18 ../
-rwxrwxr-x 1 root root 8658944 Oct 31 15:15 goproxy*

## 将goproxy命令添加到/usr/bin
root@primary:/usr/bin# ln /usr/local/goproxy/bin/goproxy -s /usr/bin/goproxy

## 查看goproxy命令是否安装成功
root@primary:/usr/local/goproxy/bin# goproxy -h
Usage of goproxy:
  -cacheDir string
    	Go Modules cache dir, default is $GOPATH/pkg/mod/cache/download
  -cacheExpire duration
    	Go Modules cache expiration (min), default is 5 min (default 5m0s)
  -exclude string
    	exclude host pattern, you can exclude internal Git services
  -listen string
    	service listen address (default "0.0.0.0:8081")
  -proxy string
    	next hop proxy for Go Modules, recommend use https://gopropxy.io

# goproxy命令

## 执行goproxy -h命令查看goproxy命令帮助
root@primary:/usr/local/goproxy/bin# goproxy -h
Usage of goproxy:
  -cacheDir string
    	Go Modules cache dir, default is $GOPATH/pkg/mod/cache/download
  -cacheExpire duration
    	Go Modules cache expiration (min), default is 5 min (default 5m0s)
  -exclude string
    	exclude host pattern, you can exclude internal Git services
  -listen string
    	service listen address (default "0.0.0.0:8081")
  -proxy string
    	next hop proxy for Go Modules, recommend use https://gopropxy.io

  • -cacheDir go module缓存目录,默认$GOPATH/pkg/mod/cache/download
  • -cacheExpire go module缓存时长(分钟), 默认5分钟
  • -exclude 排除指定host模式,你可以排除内部git server host
  • -listen 监听host和端口, 默认0.0.0.0:8081
  • -proxy go module上游代理, 推荐使用 https://gopropxy.io

# 启动goproxy服务

## 新建cache dir
root@primary:~# mkdir /usr/local/goproxy/cache

## 使用nohup命令,在后台启动goproxy进程
root@primary:~# nohup goproxy -cacheDir=/usr/local/goproxy/cache -exclude=gitea.example.com -listen=0.0.0.0:80 -proxy=https://goproxy.cn > /tmp/goproxy.log 2>&1 &
[1] 23261
root@primary:~# ps aux | grep gop
root@primary:/usr/local/goproxy# ps aux | grep gop
root        3441  0.0  0.7 1154944 7376 pts/0    Sl   19:24   0:00 goproxy -cacheDir=/usr/local/goproxy/cache -exclude=gitea.example.com -listen=0.0.0.0:80 -proxy=https://goproxy.cn
root        3449  0.0  0.2   7004  2064 pts/0    S+   19:25   0:00 grep --color=auto gop

## 查看goproxy服务机器IP地址 如果已经将域名解析到goproxy服务机器,可以直接使用域名。
root@primary:~# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp0s2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether ca:3b:cc:0e:10:69 brd ff:ff:ff:ff:ff:ff
    inet 192.168.64.3/24 metric 100 brd 192.168.64.255 scope global dynamic enp0s2
       valid_lft 74713sec preferred_lft 74713sec
    inet6 fd4a:5ec3:8409:4846:c83b:ccff:fe0e:1069/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 2591984sec preferred_lft 604784sec
    inet6 fe80::c83b:ccff:fe0e:1069/64 scope link
       valid_lft forever preferred_lft forever

## 到这里我们基本的内网goproxy服务就启动了,goproxy服务的地址为:http://192.168.64.3

# 研发机配置goproxy

在开发机器上配置GOPROXY

## 研发机器继续使用ubuntu
## 查看go环境变量
root@huge-elk:~# go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/root/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go-1.18"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go-1.18/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.18.1"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2599397427=/tmp/go-build -gno-record-gcc-switches"

## 设置GO111MODULE=on, 使用mod模式开发
root@huge-elk:~# go env -w GO111MODULE=on

## 将GOPROXY设置为我们配置的内网host
root@huge-elk:~# go env -w GOPROXY=http://192.168.64.3,direct

## 查看修改是否生效
root@huge-elk:~# go env GO111MODULE GOPROXY
on
http://192.168.64.3,direct

## 拉取公网go模块 
root@huge-elk:~# go install github.com/fbbyqsyea/wechat@latest
go: downloading github.com/fbbyqsyea/wechat v0.0.4
package github.com/fbbyqsyea/wechat is not a main package

# 拉取内网gitea go模块

## 要拉取gitea代码,goproxy机器必须配置对应仓库的访问权限

## 生成SSH密钥
## 1. 进入 ~/.ssh目录
root@primary:~# cd ~/.ssh
## 2. 使用ssh-keygen命令生成rsa公私钥 id_rsa_git为秘钥名称,不要设置密码,直接按几次回车键,完成密钥创建
root@primary:~/.ssh# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): id_rsa_git
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa_git
Your public key has been saved in id_rsa_git.pub
The key fingerprint is:
SHA256:URSu2NTjQomvYIyRF3U+A0XCkHT7V7AHz/1RazPCil0 root@primary
The key's randomart image is:
+---[RSA 3072]----+
|   .+==o+.*.    .|
|   ..o.B = *..  o|
|  o . o O = =E.* |
|   =   B *o+o o.+|
|  . + . S.oo    .|
|   . . . o       |
|      .          |
|                 |
|                 |
+----[SHA256]-----+
root@primary:~/.ssh# ll
total 20
drwx------ 2 root root 4096 Oct 31 19:39 ./
drwx------ 8 root root 4096 Oct 31 19:37 ../
-rw------- 1 root root  562 Oct 31 19:08 authorized_keys
-rw------- 1 root root 2602 Oct 31 19:39 id_rsa_git
-rw-r--r-- 1 root root  566 Oct 31 19:39 id_rsa_git.pub

## 配置gitea公钥
## 1.获取公钥内容
root@primary:~/.ssh# cat id_rsa_git.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCi+BCfnmWmI+6LsIfB42op5Y5a7MuxPw3PQb4uy5p/OEjDTN+XfCg763V7/0ZR0jL1Brer6zgOczm5FaVbIgbdwc7KXBE4fhqDJMdlDmWWaP71jaVbzdQnLkGE88xXqKG0gZT+n+JwJbC+ZymAkwZsOJvWa0TWIcL9MVgspyN19R8ZuvUJ6iws+rhx//6EPDa3FPkkzAD7LLkDRqb6rd+Ml8jhmN21x2aPU6R6WIXJbHqN3r5Rs9d58oHS/60e+Z2uYiHYr9oxs4Vun6YZCY2x1c5rfJOlHlOtZI9T5n2GScRykVBbNCp4OEv69Ga8xN6q2k6oQKYylF7+7J99S9nOUvX95E0sVGcNAHBupAZ4xst/y/XL8QQxNwn1+cEwuOHJp0er8qHp83kPqAn/8pQwzT+6UTfKfcj+eP9w742an9eIwtcjD1FBYvKqUkh0739vvshFBJOHSF/LQMRo8ARU8AfAxfhkTqc4O98xADwDTxKCZ3HHZNkK7SB/1XMiXiU= root@primary

## 2.使用有权限的账号登录gitea并且配置公钥,配置路径:Gitea “用户设置 -> SSH/GPG秘钥 -> 管理 SSH 密钥 ->增加秘钥

## 配置本地私钥
## 1.打开~/.ssh/config,添加如下内容
root@primary:~# vim ~/.ssh/config
root@primary:~# cat ~/.ssh/config
 Host *
 HostkeyAlgorithms +ssh-rsa
 PubkeyAcceptedKeyTypes +ssh-rsa

 Host gitea.example.com
 HostName gitea.example.com
 Port 22
 User git
 IdentityFile ~/.ssh/id_rsa_git

## 2. 给config文件可执行权限
root@primary:~# chmod a+x ~/.ssh/config

## 修改git clone方式
root@primary:~/.ssh# git config --global url."ssh://git@gitea.example.com".insteadOf "https://gitea.example.com"

## 由于gitea https证书已过期,所以设置GOINSECURE变量,忽略gitea.example.com https校验
root@primary:~/.ssh# go env -w GOINSECURE=gitea.example.com
root@primary:~/.ssh# go env GOINSECURE
gitea.example.com

## 测试安装内网gitea项目 (研发机器)
root@huge-elk:~# go install gitea.example.com/goweb/gin-framework-layout@latest
go: downloading gitea.example.com/goweb/gin-framework-layout v0.0.0-20221028094355-547f7a489c3b
go: gitea.example.com/goweb/gin-framework-layout@latest: gitea.example.com/goweb/gin-framework-layout@v0.0.0-20221028094355-547f7a489c3b: verifying module: gitea.example.com/goweb/gin-framework-layout@v0.0.0-20221028094355-547f7a489c3b: reading http://192.168.64.3/sumdb/sum.golang.org/lookup/gitea.example.com/goweb/gin-framework-layout@v0.0.0-20221028094355-547f7a489c3b: 404 Not Found
	server response: not found: gitea.example.com/goweb/gin-framework-layout@v0.0.0-20221028094355-547f7a489c3b: unrecognized import path "gitea.example.com/goweb/gin-framework-layout": https fetch: Get "https://gitea.example.com/goweb/gin-framework-layout?go-get=1": dial tcp: lookup gitea.example.com on 8.8.8.8:53: no such host

## 目前gin-framework-layout模块安装成功,但是sum校验失败,设置内部项目忽略校验 (研发机器)
root@huge-elk:~# go env -w GONOSUMDB=gitea.example.com

## 重新安装
root@huge-elk:~# go clean -modcache
root@huge-elk:~# go env -w GONOSUMDB=gitea.example.com
root@huge-elk:~# go install gitea.example.com/goweb/gin-framework-layout@latest
go: downloading gitea.example.com/goweb/gin-framework-layout v0.0.0-20221028094355-547f7a489c3b
go: downloading gitea.example.com/goweb/gin-framework-core v0.0.1
go: downloading github.com/gin-gonic/gin v1.8.1
go: downloading github.com/go-redis/redis v6.15.9+incompatible
go: downloading github.com/go-sql-driver/mysql v1.6.0
go: downloading github.com/jmoiron/sqlx v1.3.5
go: downloading github.com/spf13/viper v1.13.0
go: downloading go.uber.org/zap v1.23.0
go: downloading gopkg.in/natefinch/lumberjack.v2 v2.0.0
go: downloading github.com/Masterminds/squirrel v1.5.3
go: downloading github.com/mcuadros/go-defaults v1.2.0
go: downloading github.com/gin-contrib/sse v0.1.0
go: downloading github.com/mattn/go-isatty v0.0.14
go: downloading golang.org/x/net v0.1.0
go: downloading github.com/fsnotify/fsnotify v1.5.4
go: downloading github.com/mitchellh/mapstructure v1.5.0
go: downloading github.com/spf13/afero v1.8.2
go: downloading github.com/spf13/cast v1.5.0
go: downloading github.com/spf13/jwalterweatherman v1.1.0
go: downloading github.com/spf13/pflag v1.0.5
go: downloading go.uber.org/atomic v1.7.0
go: downloading go.uber.org/multierr v1.6.0
go: downloading gitea.example.com/goweb/go-utils v0.0.0-20221028065316-8abebfd58706
go: downloading github.com/dgrijalva/jwt-go v3.2.0+incompatible
go: downloading github.com/lann/builder v0.0.0-20180802200727-47ae307949d0
go: downloading github.com/go-playground/validator/v10 v10.10.0
go: downloading github.com/pelletier/go-toml/v2 v2.0.5
go: downloading github.com/pelletier/go-toml v1.9.5
go: downloading github.com/ugorji/go/codec v1.2.7
go: downloading google.golang.org/protobuf v1.28.0
go: downloading gopkg.in/yaml.v2 v2.4.0
go: downloading golang.org/x/sys v0.1.0
go: downloading golang.org/x/text v0.4.0
go: downloading github.com/subosito/gotenv v1.4.1
go: downloading github.com/hashicorp/hcl v1.0.0
go: downloading gopkg.in/ini.v1 v1.67.0
go: downloading github.com/magiconair/properties v1.8.6
go: downloading gopkg.in/yaml.v3 v3.0.1
go: downloading github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0
go: downloading github.com/go-playground/universal-translator v0.18.0
go: downloading github.com/leodido/go-urn v1.2.1
go: downloading golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
go: downloading github.com/go-playground/locales v0.14.0



# gitea.example.com/goweb/gin-framework-layout
go/pkg/mod/gitea.example.com/goweb/gin-framework-layout@v0.0.0-20221028094355-547f7a489c3b/main.go:9:7: undefined: core.New
note: module requires Go 1.19


到这里我们内网goproxy服务搭建配置成功