签发 Let's Encrypt ECC 证书
UPDATE: 请查看 acme.sh - 极力推荐的 Let's Encrypt 工具 这篇博文。
在 Let's Encrypt 证书申请实测 这篇博文里,我们签到了 RSA 2048 位证书。不过听闻 Let's Encrypt 从二月开始就支持签发 ECC 证书了,于是乎赶紧签一个。相比 RSA,ECC 证书在相似安全性的同时体积大幅减小。如果想要进一步了解的,Digicert 的 这篇文章 有一个大概的介绍,可以去阅读一下。
首先新建一个文件夹,装各种产出的东西。
mkdir keys
cd keys
配置账号私钥
签 ECC 证书的话,还是用 acme-tiny
好些。这次换了新的 VPS,也不想再去装官方那全家桶了。因为我上次已经用官方工具签过了证书,所以已经有自己的账号私钥了。官方客户端使用的是 JWK 格式,所以要转换一下账号私钥到 PEM 格式:
wget -O - "https://gist.githubusercontent.com/JonLundy/f25c99ee0770e19dc595/raw/6035c1c8938fae85810de6aad1ecf6e2db663e26/conv.py" > conv.py
cp /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/<id>/private_key.json private_key.json
openssl asn1parse -noout -out private_key.der -genconf <(python conv.py private_key.json)
openssl rsa -in private_key.der -inform der > account.key
如果第一次签,直接 openssl genrsa 4096 > account.key
就好了,不需要转换。
创建 CSR
创建域名私钥,这个要保护好:
openssl ecparam -genkey -name secp384r1 | openssl ec -out domain.key
生成证书签名请求(CSR)文件,Common Name
要填写域名地址,其他的默认就好了:
openssl req -new -sha256 -key domain.key -out domain.csr
为 Nginx 添加验证
Let's Encrypt 会在域名下随机生成一个文件验证是否拥有域名。如果能够正常下载则验证通过。因此要配置文件服务器。
创建验证用的文件夹:
mkdir -p /var/www/challenges/
打开 Nginx 配置文件,添加如下字段:
server {
listen 80;
server_name yoursite.com www.yoursite.com;
location /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri =404;
}
#...the rest of your config
}
获取证书
首先下载 acme-tiny
:
wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
然后就可以签证书啦
python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/challenges/ > ./signed.crt
使用证书
首先先下载 Let's Encrypt 的中间证书,并和你的证书串到一起:
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem
打开你的 Nginx 配置文件,把 ssl_certificate
和 ssl_certificate_key
指向的证书地址修改掉,比如说我的:
server {
listen 443 ssl http2;
server_name niconiconi.xyz;
ssl_certificate /var/www/keys/niconiconi.xyz/chained.pem;
ssl_certificate_key /var/www/keys/niconiconi.xyz/domain.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /var/www/keys/niconiconi.xyz/chained.pem;
add_header Strict-Transport-Security "max-age=10886400; includeSubdomains; preload";
ssl_ct on;
ssl_ct_static_scts /var/www/scts;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:2368;
}
}
重启 Nginx:
sudo service nginx restart
好了,按理说应该可以用上新的证书了。比如这样的:
题外话
如果之前配置了 Certificate Transparency,更新证书就意味着要再获取一遍 SCT 文件。不过这并不麻烦,照着 这篇博文 做一遍就行了,两分钟搞定。