前两天收到 Let’s Encrypt 发来的邮件,说现在的证书的验证方式是 TLS-SNI-01 ,即将结束支持。趁着这个机会,顺便把之前一直攒着的想换外卡和想换ECC的两个小坑填了。
第一个要解决的问题是 Nginx。Nginx在Ubuntu
16.04源里的最近版本是v1.10.4,并不支持写多个
tls_certificate
命令,这样就没法配置双证书。因此解决方案是
sudo apt-add-repository ppa:nginx/stable
sudo apt update
sudo apt remove nginx nginx-core nginx-common
sudo apt install nginx
最后一步会询问你是否覆盖配置文件,默认填 N
就好了。
第二步是安装 acme.sh 。这里我先吐槽一下, Certbot 是真的难用。
# Root shell
curl https://get.acme.sh | sh
# or you can use wget if you prefer
# wget -O - https://get.acme.sh | sh
source .bashrc
然后就可以签发证书了。
讲一下证书验证( ACME challenge )吧。签发一个证书之前需要验证该域名属于你。Let’s Encrypt目前支持这么几种验证方式:在DNS里加入TXT记录;通过http(s)访问某子目录进行验证;通过SNI进行验证(即将废弃);通过ALPN进行验证;等。我个人使用的是 Aliyun 来进行DNS管理的,恰好acme.sh提供了阿里云的dns api,可以方便很多操作。需要现在阿里的控制台里面签一个AccessKey出来;如果使用RAM权限控制,需要给出DNS的读写权限。
export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export Ali_Secret="jlsdflanljkljlfdsaklkjflsa"
acme.sh --issue --dns dns_ali -d example.com -d *.example.com
# You need to wait 120s for the TXT record to take effect
注意,只签 *.example.com
是不行的,会导致根域名无法访问。
这里签发了一张RSA的证书。如果要签ECC的,需要额外执行一步
acme.sh --issue --dns dns_ali -d example.com -d *.example.com --keylength ec-384
# OR:
acme.sh --issue --dns dns_ali -d example.com -d *.example.com --keylength ec-256
签发完了之后,证书会存在 ~/.acme.sh/
中,这是一个临时目录,可能会随着 acme.sh
的更新而变化,不应该用来直接引用,所以要安装证书到特定位置。
acme.sh --install-cert -d example.com \
\
--key-file /etc/letsencrypt/keys/rsa.key.pem \
--fullchain-file /etc/letsencrypt/keys/rsa.cert.pem "service nginx force-reload"
--reloadcmd acme.sh --install-cert -d example.com --ecc \
\
--key-file /etc/letsencrypt/keys/ecc.key.pem \
--fullchain-file /etc/letsencrypt/keys/ecc.cert.pem "service nginx force-reload" --reloadcmd
之后将以下代码加入到 nginx 配置文件即可。
ssl_certificate /etc/letsencrypt/keys/ecc.cert.pem;
ssl_certificate_key /etc/letsencrypt/keys/ecc.key.pem;
ssl_certificate /etc/letsencrypt/keys/rsa.cert.pem;
ssl_certificate_key /etc/letsencrypt/keys/rsa.key.pem;
另外,为了拿到 A+ ,还有一个加密算法优先级的问题;本站自用的:
ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";
The Ultimate Solution
用 Caddy。真香!