使用tls-alpn-01部署Let’s Encrypt证书

TLS-SNI-01已经deprecated,但certbot尚不支持tls-alpn-01验证方法,因此可以使用dehydrated或者acme.sh通过https来获取Let’s Encrypt证书。

使用TLS_ALPN获取证书,需要使用443端口进行验证,借助nginx的ngx_stream_ssl_preread_module模块,可以路由来自443的请求到不同的处理后端。

确保nginx支持ssl_preread特性

1
2
$ nginx -V 2>&1 grep -o ssl_preread
ssl_preread

配置nginx
/etc/nginx/nginx.conf文件最后添加

1
2
3
4
5
6
7
8
9
10
11
12
stream {
map $ssl_preread_alpn_protocols $tls_port {
~\\bacme-tls/1\\b 10443;
default 8443;
}
server {
listen 443;
listen \[::\]:443;
proxy_pass 127.0.0.1:$tls_port;
ssl_preread on;
}
}

这样来自签发证书时的验证请求会被路由到10443端口,而其他对443端口的访问会被路由到8443端口,所以虚拟主机应该在8443端口上监听ssl连接。

reload nginx使新配置生效

1
$ sudo systemctl reload nginx

申请证书

1
2
3
4
5
6
7
8
9
# acme.sh --issue --alpn --tlsport 10443 -d openwares.net
```

**安装证书**
```js
# acme.sh --installcert -d openwares.net \\
--key-file /etc/nginx/ssl/openwares.net.key \\
--fullchain-file /etc/nginx/ssl/fullchain.cer \\
--reloadcmd "systemctl force-reload nginx"

更新证书

1
# acme.sh --renew -d openwares.net --force

注意(updated 02/29/2020):
如果启用了proxy_protocol以获取客户端的真实地址,申请或者更新证书时会出现错误:

1
Verify error:Error getting validation data

因此申请或更新证书时需要临时禁止proxy_protocol协议。

References:
[1]Deploying Let’s Encrypt certificates using tls-alpn-01 (https)
[2]使用TLS-ALPN-01验证签发证书
[3]TLS ALPN without downtime
[4]ssl_preread_protocol, multiplex HTTPS and SSH on the same port