下载git

yum install git

安装go

wget https://storage.googleapis.com/golang/go1.14.linux-amd64.tar.gz
tar -zxf go1.14.linux-amd64.tar.gz -C /usr/local/
在 /etc/profile 添加:

export GOROOT=/usr/local/go 
export GOPATH=/home/test
export PATH=$PATH:$GOROOT/bin

然后执行 source /etc/profile

也可以不安装go,直接运行其他环境上生成的二进制文件,
编译二进制文件:go build xxxx

下载quic-go代码

go get -v -t -u github.com/lucas-clemente/quic-go

依赖库被墙:golang.org/x/下不下来,需要设置代理
推荐方法:
设置环境变量(~/.bashrc等)

export GO111MODULE=on
export GOPROXY=https://goproxy.io

注:go1.13以上才支持这种方式,go version确定版本,低的话需要升级

如果go下载有问题可以使用git clone https://github.com/lucas-clemente/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

有时候直接重新下载也会成功。

使用localhost访问

如果是服务端和客户端都在本地,可以直接使用quic-go/internal/testdata下的ca和证书。
系统CA池在windows上可能获取不到,可以修改为用局部pool:

pool := testdata.GetRootCA()

制作证书(使用localhost访问不需要)

确定需要使用的域名,比如www.example.com,server的IP地址,比如172.2.202.17
下面给出的过程是使用openssl制作证书,可能有点复杂,简单的话可以使用mkcert:
https://blog.csdn.net/aashuii/article/details/111360665

制作CA证书

参考自

https://blog.csdn.net/qq_40210617/article/details/86659271

修改openssl配置文件: cat /etc/pki/tls/openssl.cnf

 dir             = /etc/pki/CA  真正的工作目录
certs           = $dir/certs   已经签发的CA证书
crl_dir         = $dir/crl      已经生成的吊销证书列表
database        = $dir/index.txt   签署的所有证书的目录主体信息
new_certs_dir   = $dir/newcerts  刚刚签发的证书

certificate     = $dir/cacert.pem        CA自己的证书
serial          = $dir/serial           证书的序列号
crlnumber       = $dir/crlnumber        吊销证书的序列号,标记吊销序列号
crl             = $dir/crl.pem          # The current CRL
private_key     = $dir/private/cakey.pem   CA自己的私钥证书
RANDFILE        = $dir/private/.rand  

创建所需要的文件

  touch index.txt
  echo 01 > serial

CA自签证书(由于自己失误,重新生成一次证书)

    (umask 077; openssl genrsa -out private/cakey.pem 2048)

openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -days 7300 -out cacert.pem

颁发证书

1、生成请求

 (umask 077; openssl genrsa -out httpd.key 2048)
openssl req -new -key httpd.key -days 365 -out httpd.csr

2、把请求httpd.csr发给CA (可在同一台机器上)

3、CA颁发证书

openssl ca -in /tmp/httpd.csr -out /tmp/httpd.crt -days 365

4、颁发的证书httpd.crt文件在传送回请求客户端

本地认证和寻址

修改客户端DNS(使用localhost可略过)

修改/etc/hosts
增加 172.2.202.17 www.example.com(本机测试用127.0.0.1)
重启网络服务或者重启linux

windows上hosts位置:c:/windows/system32/drivers/etc/hosts
修改后刷新ipconfig /flushdns
查看是否生效ipconfig /displaydns

修改服务端DNS

再hosts中增加:
0.0.0.0 example.com

客户端增加证书信任机构

Ubuntu

 cp  cacert.crt /usr/local/share/ca-certificates(颁发机构证书)
 update-ca-certificates

centOS

 cp  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.go
cd client
go build -o client.go

老的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,如果测试两台机器之间的连通性需要替换证书或者修改代码

服务端

server端修改example/main.go

err = server.ListenAndServeTLS("/home/test/httpd.crt", "/home/test/httpd.key")

注意:windows路径中不能使用\要使用\

或者把证书和私钥放到testdata下面,并替换掉原来的证书。

客户端

客户端主要是增加信任自己的根证书,代码逻辑是先加载系统的ca pool,然后添加testdata中的证书,所以把自制根证书加载在系统中或者替换到internal\testdata下都可以(名为ca.pem,crt转pem使用openssl命令)

linux把信任CA根证书加载到系统中:
Ubuntu

 cp  cacert.crt /usr/local/share/ca-certificates(颁发机构证书)
 update-ca-certificates

centOS

 cp  cacert.crt  /etc/ssl/certs/
 update-ca-trust

Windows加载系统根证书pool可以通过修改代码(linux也可以这样,不用把根证书加载到系统里了):

//pool, err := x509.SystemCertPool()
//if err != nil {
	//log.Fatal(err)
//}
pool := x509.NewCertPool()
testdata.AddRootCA(pool)

运行

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://www.example.com:4443/test001.dat (要求服务端返回test001中数据)
go run /home/mylib/src/github.com/lucas-clemente/quic-go/example/client/main.go https://www.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; charset=utf-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)找不到,可能是路径问题或者文件不存在。

Logo

更多推荐