代码和编译下载gityum install git安装gowget https://storage.googleapis.com/golang/go1.14.linux-amd64.tar.gz或者从https://golang.google.cn/dl/或者https://studygolang.com/dl下载tar -zxf go1.14.linux-amd64.tar.gz -C /usr/local/在 /etc/profile 添加#go安装路径 export GOROOT/usr/local/go #go代码的运行路径 export GOPATH/home/test export PATH$PATH:$GOROOT/bin然后执行 source /etc/profile也可以不安装go直接运行其他环境上生成的二进制文件编译二进制文件go build xxxx下载quic-go代码#老的路径是github.com/lucas-clemente/quic-go go get -v -t -u github.com/quic-go/quic-go依赖库被墙golang.org/x/下不下来需要设置代理推荐方法设置环境变量~/.bashrc等export GO111MODULEon export GOPROXYhttps://goproxy.cn,direct注go1.13以上才支持这种方式go version确定版本低的话需要升级如果go下载有问题可以使用git clone https://github.com/quic-go/quic-go.git然后go build或者go run自动下载依赖库提示错误error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054 fatal: the remote end hung up unexpectedly fatal: early EOF fatal: index-pack failed一般是本地缓存不够可重新设置git config http.postBuffer 524288000有时候直接重新下载也会成功。证书和密钥服务端代码example/main.go默认读取quic-go/internal/testdata下的cert.pem和priv.key客户端代码example/client/main.go默认加载系统ca证书。客户端quic-go/internal/testdata下的根证书ca.pem需要加载到系统中见客户端增加证书信任机构章节查看证书内容openssl x509-incert.pem-text-noout证书的域名如图所示使用localhost访问如果是服务端和客户端都在本地可以直接使用quic-go/internal/testdata下的ca和证书。系统CA池在windows上可能获取不到client可以修改为用局部poolexample/client/main.gopool, err : x509.SystemCertPool() 修改为 pool : testdata.NewCertPool()制作证书使用localhost访问不需要生成ca证书internal/testdata下的ca证书没有配套的key没办法颁发服务端证书重新生成ca.pem和ca.key可参考internal/testdata下的generate_key.sh:openssl req-x509-sha256-nodes-days3650-newkeyrsa:2048\-keyoutca.key-outca.pem\-subj/Oquic-go Certificate Authority/确定需要使用的域名比如www.example.comserver的IP地址比如172.2.202.17颁发证书1、编写配置文件catexample.cnf[req]default_bits2048distinguished_namereq_distinguished_name req_extensionsreq_ext promptno[req_distinguished_name]countryNameCN stateOrProvinceNameBeijing localityNameBeijing organizationNameExample Inc commonNameexample.com[req_ext]subjectAltNamealt_names[alt_names]DNS.1example.com DNS.2www.example.com IP.1192.168.1.82、CA颁发证书openssl req -new -newkey rsa:2048 -nodes -keyout example.key -out example.csr -config example.cnf #使用刚才生成的ca.pem和ca.key颁发 openssl x509 -req -in example.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out example.crt -days 365 -extensions req_ext -extfile example.cnf # 代码中使用的是cert.pem cp example.crt cert.pem本地认证和寻址修改客户端DNS使用localhost可略过修改/etc/hosts增加 172.2.202.17 www.example.com本机测试用127.0.0.1重启网络服务或者重启linuxsudosystemctl restart systemd-resolvedwindows上hosts位置c:/windows/system32/drivers/etc/hosts修改后刷新ipconfig /flushdns查看是否生效ipconfig /displaydns修改服务端DNS再hosts中增加0.0.0.0 example.com客户端增加证书信任机构Ubuntucp ca.crt /usr/local/share/ca-certificates颁发机构证书 update-ca-certificatescentOScp cacert.crt /etc/ssl/certs/ update-ca-trust编译go若提示招不到某import包先检查执行目录是否正确一般需要在github.com/lucas-clemente/quic-go下执行然后确定环境变量GOMOD是否正确如/home/mylib/src/github.com/lucas-clemente/quic-go/go.mod到代码目录下编译二进制文件qui-go/example/go build -o server cd client go build -o client老的go版本需要在quic-go下执行go mod init go mod vendor新的go版本如果提示依赖找不到可以执行go mod tidy创建http数据源码中给出了/demo/tile、/demo/tiles、/demo/echo等的http处理客户端访问这几个url不需要特别处理但如果直接获取/服务端默认返回index.html需要自己创建文件html head title /title /head body HELLO WORLD!! /body /html请求具体数据test001.dat可以随便加内容证书加载源码中默认放在lucas-clemente/quic-go/internal\testdata下但源码中测试的域名是localhost如果测试两台机器之间的连通性需要替换证书或者修改代码可以使用openssl x509 -in cert.pem -text -noout查看证书内容服务端server端修改example/main.goerr server.ListenAndServeTLS(/home/test/httpd.crt, /home/test/httpd.key)注意windows路径中不能使用\要使用\或者把证书和私钥放到testdata下面并替换掉原来的证书。客户端客户端主要是增加信任自己的根证书代码逻辑是先加载系统的ca pool然后添加testdata中的证书所以把自制根证书加载在系统中或者替换到internal\testdata下都可以名为ca.pemcrt转pem使用openssl命令linux把信任CA根证书加载到系统中Ubuntucp cacert.crt /usr/local/share/ca-certificates颁发机构证书 update-ca-certificatescentOScp cacert.crt /etc/ssl/certs/ update-ca-trust运行go run /home/mylib/src/github.com/lucas-clemente/quic-go/example/main.go -bind example.com:4443 -www /home/test/ index.html或者test001.dat路径go run /home/mylib/src/github.com/lucas-clemente/quic-go/example/client/main.go https://example.com:4443/test001.dat 要求服务端返回test001中数据go run /home/mylib/src/github.com/lucas-clemente/quic-go/example/client/main.go https://example.com:4443 服务端默认返回index.html或者./server.exe -v true -qlog true ./client.exe -v true -qlog true https://localhost:6121/demo/tile https://localhost:6121/demo/tiles注意windows路径中不要使用\一律换成\比如 D:\test###运行中的问题服务端可打开 -v true查看具体信息1、windows客户端提示crypto/x509: system root pool is not available on Windows原因x509.SystemCertPool()返回错误具体原因为止解决办法修改main.go中先获取本机cert pool再添加测试ca根证书的逻辑为先new一个pool再添加ca根证书pool, err : x509.SystemCertPool()if err ! nil {log.Fatal(err)}testdata.AddRootCA(pool)修改为pool : testdata.GetRootCA()2、服务端提示 CRYPTO_ERROR: ALPN negotiation failed. Client offered: [“h3-27”]客户端提示client Peer closed session with error: CRYPTO_ERROR: tls: no application protocol原因tls版本不一致解决办法两端更新github.com/marten-seemann/qtls到最新版本后解决。3、http提示错误Got response for https://www.example.com:4443: http.Response{Status:404 Not Found, StatusCode:404, Proto:HTTP/3, ProtoMajor:3, ProtoMinor:0, Header:http.Header{Content-Type:[]string{text/plain; charsetutf-8}, X-Content-Type-Options:[]string{nosniff}}, Body:(*http3.body)(0xc000086240), ContentLength:0, TransferEncoding:[]string(nil), Close:false, Uncompressed:false, Trailer:http.Header(nil), Request:(*http.Request)(nil), TLS:(*tls.ConnectionState)(nil)} Request Body: 404 page not found client Closing session with error: Application error 0x100原因一般是http文件客户端请求的文件或者默认的index.html找不到可能是路径问题或者文件不存在。