ECC证书 相比 RSA证书, 密钥短了很少,但安全性还是有保证,ECC 是Elliptic curve cryptography的简写, 是一种建立公开密钥加密的算法,基于椭圆曲线。由于其密钥较短,运算速度较快,所以渐渐开始在一些网站上使用。但是由于有些老旧 浏览器/系统 不支持ECC证书,为了使他们能够访问,我们还得提供一份 RSA证书。
申请
下面这个脚本使用acme.sh配置、部署RSA、ECC双证书
根据自己的DNS提供商,按照DNSAPI对应着去申请API,并使用
export
命令声明变量
#!/bin/sh
DOMAIN="example.com" # 域名
CERT_FOLDER="/etc/nginx/certs" # 证书存放的目录,结尾不能是"/"字符
#export Ali_Key="123456AbCdEfGh1234567890" # 阿里云
#export Ali_Secret="aBcDEfGhHiJkLmNOpQrStUvWxYz234" # 阿里云
#export DP_Key="123456AbCdEfGh1234567890" # DNSPod
#export DP_Id="aBcDEfGhHiJkLmNOpQrStUvWxYz234" # DNSPod
#######################################################################
# 安装acme.sh
# apt install socat # 仅stand alone模式需要
curl https://get.acme.sh | sh
alias acme.sh='/root/.acme.sh/acme.sh'
acme.sh --upgrade --auto-upgrade # 更新acme.sh
acme.sh --set-default-ca --server letsencrypt # 设置默认CA为let's Encrypt
# 申请RSA证书
acme.sh --issue -d ${DOMAIN} -d *.${DOMAIN} --dns dns_ali \
--dnssleep 30 --ocsp --days 30 --keylength 2048
# 申请ECC证书
acme.sh --issue -d ${DOMAIN} -d *.${DOMAIN} --dns dns_ali \
--dnssleep 30 --ocsp --days 30 --keylength ec-256
# 创建证书安装所需要的目录
mkdir ${CERT_FOLDER}
mkdir ${CERT_FOLDER}/rsa
mkdir ${CERT_FOLDER}/ecc
# 安装RSA证书
acme.sh --install-cert -d ${DOMAIN} \
--cert-file ${CERT_FOLDER}/rsa/$(DOMAIN).cer \
--key-file ${CERT_FOLDER}/rsa/$(DOMAIN).key \
--fullchain-file ${CERT_FOLDER}/rsa/$(DOMAIN).fullchain.cer \
--reloadcmd "systemctl restart nginx"
# 安装ECC证书
acme.sh --install-cert -d ${DOMAIN} --ecc \
--cert-file ${CERT_FOLDER}/ecc/$(DOMAIN).cer \
--key-file ${CERT_FOLDER}/ecc/$(DOMAIN).key \
--fullchain-file ${CERT_FOLDER}/ecc/$(DOMAIN).fullchain.cer.fullchain.pem \
--reloadcmd "systemctl restart nginx"
# 手动更新证书
#acme.sh --renew -d example.com --force
#acme.sh --renew -d example.com --force --ecc
启用
Web 服务器我使用的Nginx,一切准备妥当之后,将证书配置改为双份,一份填写ecc证书地址,另一份则填写rsa证书地址
ssl_certificate /etc/nginx/certs/rsa/fullchain.rsa.cer;
ssl_certificate_key /etc/nginx/certs/rsa/rsa.key;
ssl_certificate /etc/nginx/certs/ecc/fullchain.ecc.cer;
ssl_certificate_key /etc/nginx/certs/ecc/ecc.key;
修改ssl_ciphers
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE+AES128:RSA+AES128:ECDHE+AES256:RSA+AES256:ECDHE+3DES:RSA+3DES;
也可以参考Mozilla提供的
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
重启nginx后使用ssllabs检查应该是能发现有两张证书的
自动更新证书
#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
DOMAIN="example.com"
CERT_FOLDER="/etc/nginx/certs"
systemctl stop nginx &> /dev/null
sleep 1
"/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" &> /dev/null
"/root/.acme.sh"/acme.sh --installcert -d ${DOMAIN} --fullchainpath ${CERT_FOLDER}/rsa/fullchain.cer --keypath ${CERT_FOLDER}/rsa/${DOMAIN}.key
"/root/.acme.sh"/acme.sh --installcert -d ${DOMAIN} --fullchainpath ${CERT_FOLDER}/ecc/fullchain.cer --keypath ${CERT_FOLDER}/ecc/${DOMAIN}.key --ecc
sleep 1
systemctl start nginx &> /dev/null
将这个脚本添加到crontab
0 3 * * 0 bash /root/.acme.sh/ssl_update.sh
自动续期+钉钉告警(参考脚本,根据实际自己改动)
#!/bin/bash
set -x
DOMAIN_LIST="
admin.example.com
api.example.com
www.example.com
"
SSL_DIR="/etc/nginx/certs"
WEBROOT="/var/nginx/html"
ACMESH="/root/.acme.sh/acme.sh"
NOTICE_DINGDING_TOBOT="https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
noticeDingding(){
msg="{\"msgtype\": \"text\",\"text\": {\"content\": "\'"${1}"\'"},\"at\": {\"isAtAll\": true}}"
curl "$NOTICE_DINGDING_TOBOT" -H 'Content-Type: application/json' -d "$msg"
}
applyFreeSSLCertificate(){
status=0
# 1、强制申请免费ssl证书
$ACMESH --issue -d $domain -w $WEBROOT --force
[ $? -eq 0 ] && status=`expr $status + 1`
# 2、安装ssl证书到nginx
$ACMESH --install-cert -d ${domain} --key-file "${SSL_DIR}/${domain}.key" --fullchain-file "${SSL_DIR}/${domain}.cer" --reloadcmd "nginx -s reload" # 自动部署到nginx
[ $? -eq 0 ] && status=`expr $status + 1`
if [ $status -eq 2 ];then
noticeDingding "申请并部署、续期(提前一周)免费ssl证书"${domain}"成功!"
else
noticeDingding "申请并部署、续期(提前一周)免费ssl证书"${domain}"失败!请手动执行本脚本程序再次申请、续期以观测失败原因!"
fi
}
for domain in $DOMAIN_LIST;do
echo "自动申请部署并续期ssl证书,域名=$domain"
# 申请部署免费SSL证书
# 如果证书文件不存在则自动申请并部署免费的SSL证书
if [ ! -e ${SSL_DIR}/${domain}.cer ];then
applyFreeSSLCertificate
fi
# 自动续期
# 检查ssl证书到期时间,提前一周自动续期并部署新的ssl证书
expirationTimeGMT=`openssl x509 -in ${SSL_DIR}/${domain}.cer -noout -dates|grep notAfter|awk -F '=' '{print $2}'` # 证书到期GMT时间
expirationTime=`date -d "$expirationTimeGMT" +%s` # 证书到期时间,转换为以秒为单位的时间戳
currTime=`date +%s` # 当前时间戳
echo "当前证书到期时间还有$(expr $(expr $expirationTime - $currTime) / 60 / 60 / 24)天"
if [ $(expr $(expr $expirationTime - $currTime) / 60 / 60 / 24) -lt 7 ];then
applyFreeSSLCertificate
fi
done
转载请注明来源