Go-Get Proxy搭建

Go-Get 原理

不论是否开启Go Module功能,go get从版本控制系统VCS中取包的基础过程是类似的。假设依赖包github.com/liujianping/foo不在本地,需要通过go get获取。发起以下命令:

go get github.com/liujianping/foo

正则匹配出依赖包的查询路径

go get可以指定具体包的import路径或者通过其自行分析代码中的import得出需要获取包的路径。但是import路径,并不直接就是该包的查询路径。在go get的源码实现中,包的查询路径是通过一组正则匹配出来的。也就是说,import路径是必须匹配这组正则表达式的,如果不匹配的话,代码是肯定无法编译的。

// Github
    {
        prefix: "github.com/",
        re:     `^(?Pgithub\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[\p{L}0-9_.\-]+)*$`,
        vcs:    "git",
        repo:   "https://{root}",
        check:  noVCSSuffix,
    },
    //省略其它VCS...

以包路径github.com/liujianping/foo为例,正则匹配后,得出的查询路径就是:

https://github.com/liujianping/foo

再结合go-get参数,向远端VCS系统发起https://github.com/liujianping/foo?go-get=1请求。

查询得出包的远端仓库地址

包的远端仓库地址,可以通过go get请求的响应中的go-import的meta标签中的content中获取的。meta去标签格式如下:

  • pkg: 包名,例如gopkg.in/yaml.v2,也是import path(后续通过修改该参数实现自定义import path)
  • git: 版本控制系统
  • repo: 源代码地址

如:

$: curl https://github.com/liujianping/foo?go-get=1 | grep go-import

根据仓库地址Clone到本地

虽然版本控制系统VCS本身就存在各类区别,但是一些基础操作大多类似。在go get中具体clone的过程会根据具体的VCS采用对应的操作。

Proxy搭建

govanityurls原理

govanityurls的原理十分简单,它本身就好比一个“导航”服务器。当go get将请求发送给govanityurls时,govanityurls将请求中的repo的真实地址返回给go get,后续go get再从真实的repo地址获取package数据。


image.png

可以看出go get第一步是尝试获取自定义路径的包的真实地址,govanityurls将返回一个类似如下内容的http应答(针对go get tonybai.com/gowechat请求):



    
    
    
    
    
    
    
        Nothing to see here; see the package on godoc.
    

搭建环境

机器

  1. 测试机器:localhost

步骤

  1. 搭建Nginx,仅做一层反向代理
  • 路径:/root/go-get-proxy/nginx
  • 配置文件:
server {
    listen 80;
    listen 443 ssl;
    server_name test.com;

    ssl_certificate           ../cert/cert.crt; // 后续生成
    ssl_certificate_key       ../cert/cert.key; // 后续生成

    error_log logs/error.log;   #指定错误日志文件路径
    access_log logs/access.log; #指定访问日志文件路径

    location / {
            proxy_pass http://127.0.0.1:5000; // 为govanityurls端口
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    }
}
  1. 搭建govanityurls
  • 路径:/root/go-get-proxy/govanityurls
  • 配置文件:vanity.yaml(后续添加新包需要到这添加后重启)
/bluele/gcache:
        repo: https://github.com/bluele/gcache
  • 待完善代码:现在只有github.com的,需要补充其他来源的包
if strings.Contains(e.Repo, "github.com") {
  e.Display = fmt.Sprintf("%v %v/tree/master{/dir} %v/blob/master{/dir}/{file}#L{line}", e.Repo, e.Repo, e.Repo)
}
  1. https证书获取
  • 制作证书
$ openssl genrsa -out rootCA.key 2048
$ openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=*.test.com" -days 5000 -out rootCA.pem
$ openssl genrsa -out cert.key 2048
$ openssl req -new -key cert.key -subj "/CN=test.com" -out cert.csr
$ openssl x509 -req -in cert.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out cert.crt -days 5000
  • 放置证书
    • 将cert.crt和cert.key拷贝到nginx/cert目录下,重启nginx,让其加载新的cert.crt和cert.key。
    • rootCA.pem根据系统(指Client方)不一样有不一样的放置路径
      • MAC
        • sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain rootCA.pem
        • $GOROOT/src/crypto/x509/root_linux.go
package x509

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

Proxy使用

  1. 在mac上修改一下/etc/hosts,添加一条路由
localhost   test.com
  1. 添加CA证书(仅在goland自动下载的时候需要添加,手动go get下载可以使用-insecure)

    • sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain rootCA.pem
  2. 使用方式与其他包的使用相同

  3. 若需要引入新包,需要更新govanityurls并重启

参考资料

  1. https://tonybai.com/2017/06/28/set-custom-go-get-import-path-for-go-package/
  2. https://segmentfault.com/a/1190000018414744
  3. https://my.oschina.net/u/2306127/blog/787078
  4. https://github.com/golang/go/issues/27332

你可能感兴趣的:(Go-Get Proxy搭建)