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