使用 Certbot 的 TLS§
若要设置Unit 中的 SSL/TLS 访问,您需要证书包。虽然可以使用自签名证书,但建议从证书颁发机构 (CA) 为您的网站获取证书。为此,您可以使用 EFF 的Certbot,它会签发由Let’s Encrypt(一家非营利性 CA)签名的免费证书。
生成证书§
在您网站的服务器上安装Unit。
在同一服务器上安装Certbot,在 EFF 网站的软件下拉列表中选择以上都不是,在系统下拉列表中选择服务器的操作系统。
运行certbot实用程序并按照其说明创建证书包。系统会提示您输入网站的域名并验证域名所有权;后者可以通过不同的方式完成。也许最简单的方法是使用webroot方法,让 Certbot 本地存储某个文件,然后通过您的域名访问该文件。首先,使用 80 端口在 Unit 中配置一个临时路由
{ "listeners": { "*:80": { "pass": "routes/acme" } }, "routes": { "acme": [ { "match": { "uri": "/.well-known/acme-challenge/*" }, "action": { "share": "/var/www/www.example.com$uri/" } } ] } }
确保share目录对 Unit 的路由器进程用户帐户(通常为unit:unit)可访问。
接下来,运行 certbot,提供 share 目录作为 webroot 路径
# certbot certonly --webroot -w /var/www/www.example.com/ -d www.example.com
如果您由于某种原因无法使用前一种方法,请尝试使用 DNS 记录来验证您的域名
# certbot certonly --manual --preferred-challenges dns -d www.example.com
Certbot 将提供有关更新 DNS 条目以证明域名所有权的说明。
任何此类 certbot 命令都会将生成的 .pem 文件存储如下
/etc/letsencrypt/ └── live/ └── www.example.com ├── cert.pem ├── chain.pem ├── fullchain.pem └── privkey.pem
注意
Certbot 也提供其他验证方法 (验证器),但为了简洁起见,此处省略了这些方法。
创建一个适合 Unit 的证书包,并将其上传到 Unit 的 控制 API 的 certificates 部分
# cat /etc/letsencrypt/live/www.example.com/fullchain.pem \ /etc/letsencrypt/live/www.example.com/privkey.pem > bundle1.pem # curl -X PUT --data-binary @bundle1.pem \ --unix-socket /path/to/control.unit.sock \ http://localhost/certificates/certbot1 { "success": "Certificate chain uploaded." }
在 Unit 中创建或更新 监听器 以使用上传的包
# curl -X PUT --data-binary \ '{"pass": "applications/ssl_app", "tls": {"certificate": "certbot1"}}' \ --unix-socket /path/to/control.unit.sock \ 'http://localhost/config/listeners/*:443'
尝试通过 HTTPS 访问您的网站
$ curl https://www.example.com -v ... * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS Unknown, Certificate Status (22): * TLSv1.3 (IN), TLS handshake, Unknown (8): * TLSv1.3 (IN), TLS Unknown, Certificate Status (22): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS Unknown, Certificate Status (22): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS Unknown, Certificate Status (22): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Client hello (1): * TLSv1.3 (OUT), TLS Unknown, Certificate Status (22): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server did not agree to a protocol * Server certificate: * subject: CN=www.example.com * start date: Sep 21 22:10:42 2020 GMT * expire date: Dec 20 22:10:42 2020 GMT ...
续订证书§
Certbot 允许手动或 自动续订证书 手动。对于手动续订和更新
重复上述步骤以续订证书,并以不同的名称上传新包
# certbot certonly --standalone What would you like to do? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: Keep the existing certificate for now 2: Renew & replace the cert (may be subject to CA rate limits) # cat /etc/letsencrypt/live/www.example.com/fullchain.pem \ /etc/letsencrypt/live/www.example.com/privkey.pem > bundle2.pem # curl -X PUT --data-binary @bundle2.pem \ --unix-socket /path/to/control.unit.sock \ http://localhost/certificates/certbot2 { "success": "Certificate chain uploaded." }
现在您已上传两个证书包;Unit 将它们识别为 certbot1 和 certbot2。或者,查询 certificates 部分以查看常见详细信息,例如到期日期、主题或颁发者
# curl --unix-socket /path/to/control.unit.sock \ http://localhost/certificates
更新 监听器,将其切换到续订的证书包
# curl -X PUT --data-binary 'certbot2' \ --unix-socket /path/to/control.unit.sock \ 'http://localhost/config/listeners/*:443/tls/certificate'
注意
无需关闭 Unit;您的服务器可以在更新期间保持在线状态。
删除已过期的包
# curl -X DELETE --unix-socket /path/to/control.unit.sock \ 'http://localhost/certificates/certbot1' { "success": "Certificate deleted." }
您还可以通过为监听器配置多个证书包来利用 Unit 的 SNI 支持。
假设您已成功使用 Certbot 为两个域名(www.example.com 和 cdn.example.com)获取 Let's Encrypt 证书。首先,使用与之前相同的步骤将它们上传到 Unit
# cat /etc/letsencrypt/live/cdn.example.com/fullchain.pem \ /etc/letsencrypt/live/cdn.example.com/privkey.pem > cdn.example.com.pem # cat /etc/letsencrypt/live/www.example.com/fullchain.pem \ /etc/letsencrypt/live/www.example.com/privkey.pem > www.example.com.pem # curl -X PUT --data-binary @cdn.example.com.pem \ --unix-socket /path/to/control.unit.sock \ http://localhost/certificates/cdn.example.com { "success": "Certificate chain uploaded." } # curl -X PUT --data-binary @www.example.com.pem \ --unix-socket /path/to/control.unit.sock \ http://localhost/certificates/www.example.com { "success": "Certificate chain uploaded." }
接下来,配置侦听器,为 tls/certificate 选项提供两个捆绑包作为数组值
# curl -X PUT --data-binary '{"certificate": ["cdn.example.com", "www.example.com"]}' \ --unix-socket /path/to/control.unit.sock \ 'http://localhost/config/listeners/*:443/tls'
Unit 完成其余工作,自动找出为连接到两个域名中的每个传入连接生成哪个捆绑包。