1.下载quic-go代码

环境go1.13以上。

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

2.locahost运行

下载完成后,推荐不用编译直接运行代码。但只限locahost。要ip运行需安装证书。

3.制作CA证书

确定需要使用的域名,比如www.example.com,server的IP地址,比如172.2.202.17。

3.1 修改openssl配置文件

cat /etc/pki/tls/openssl.cnf,也有系统在/usr/lib/ssl/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

3.2 创建所需要的文件

touch index.txt
echo 01 > serial

3.3 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

4.颁发证书

4.1 生成请求

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

4.2 把请求httpd.csr发给CA

4.3 CA颁发证书

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

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

5.本地认证和寻址

5.1 修改客户端DNS

修改/etc/hosts

并增加172.2.202.17 www.example.com

重启网络服务或者重启linux。

windows上hosts位置:c:/windows/system32/drivers/etc/hosts。

修改后刷新,ipconfig /flushdns。

查看是否生效ipconfig /displaydns。

5.2 修改服务端DNS

再hosts中增加:

0.0.0.0 example.com

6.客户端增加证书信任机构

PEM转换成CRT方法:

openssl x509 -outform der -in your-cert.pem -out your-cert.crt

6.1 Ubuntu

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

6.2 centOS

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

7.创建http数据

<html><head><title></title></head>
<body>HELLO WORLD</body>
</html>

8.证书加载

8.1 服务端

server端修改example/main.go。

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

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

9.客户端

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

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

Windows加载系统根证书pool一直出错,暂时没找到办法。

10.运行

go run /home/mylib/src/github.com/lucas-clemente/quic-go/example/main.go -bind example.com:4443 -www /home/test/ (index.html或test01.dat路径)
go run /home/mylib/src/github.com/lucas-clemente/quic-go/example/client/main.go https://www.example.com:4443/test001.dat (要求服务端返回中数据)
go run /home/mylib/src/github.com/lucas-clemente/quic-go/example/client/main.go https://www.example.com:4443 (服务端默认返回index.html)

11.运行中的问题

服务端可打开 -v true查看具体信息。

11.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()

11.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到最新版本后解决。