1. 引言
之前有两篇文章简单介绍了什么是CA以及Openssl的简单的操作,本篇介绍如何快速通过acme.sh这个开源项目,向Let’s Encrypt进行证书申请
协议方面,Let's Encrypt
用于自动注册证书颁发机构的质问-响应协议称为自动证书管理环境(ACME),它涉及对证书涵盖的域上的Web服务器的各种请求,基于所得到的响应是否与期望相匹配,确保了对域的登记者的控制(域验证)。
Let's Encrypt
在签发过程中,这种行为称之为会向签发者的挑战,让签发者证明其为被签发的域名的拥有者,除了本文介绍的在服务器上进行证书挑战,还有基于DNS方式的挑战等
2. 安装acme.sh
安装细节,参见 https://github.com/Neilpang/acme.sh
如何签发证书
参考: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
- 单域名签发:
- Nginx服务:
acme.sh --issue -d example.com -w /home/wwwroot/example.com
- 单独签发For Email服务:
acme.sh --issue -d example.com --standalone
acme.sh --issue -d example.com --standalone --httpport 88
acme.sh --issue -d example.com --alpn
- 基于DNS API认证方式(acme.sh会动态的增加、删除NX解析,以证明域名是归你管理)
DNS API
- DNS manual mode:
- DNS alias mode
- Apache mode
- Nginx mode
- Nginx服务:
- 多域名,SAN模式
- Webroot mode:
acme.sh --issue -d example.com -w /home/wwwroot/example.com -d www.example.com
- Standalone mode:
acme.sh --issue -d example.com --standalone -d www.example.com
- Dns api mode:
Export .., acme.sh --issue -d example.com --dns dns_cf -d www.example.com
- Dns manual mode:
acme.sh --issue -d example.com --dns -d www.example.com
- Webroot mode:
- 多域名、SAN混合模式:
acme.sh --issue \
-d aa.com -w /home/wwwroot/aa.com \
-d bb.com --dns dns_cf \
-d cc.com --apache \
-d dd.com -w /home/wwwroot/dd.com
3. 基于DNS认证方式
具体云厂商DNS API认证挑战:https://github.com/acmesh-official/acme.sh/wiki/dnsapi
-
进入到阿里云官网,设置访问key,安全方面基于最小权限设定(建立组、给组分配仅可设定dns相关的权限,指定特定的账户的访问key) https://ak-console.aliyun.com/#/accesskey
-
将有限权限的dns账户,获取对应的key和秘钥,加入到
.bashrc
中 export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje” export Ali_Secret="jlsdflanljkljlfdsaklkjflsa” -
签发多个通配符相关的证书、安装到指定目录、并设定重启:
acme.sh --issue --dns dns_ali -d tkstorm.com -d *.tkstorm.com -d archstat.com -d *.archstat.com -d perf.plus -d lupguo.cool \
--fullchain-file /usr/local/nginx/conf/ssl/tkstorm.com.chained.cert --key-file /usr/local/nginx/conf/ssl/tkstorm.com.key \
--reloadcmd "service nginx reload"
4. 基于domain认证方式步骤
4.1. 配置Nginx服务器相关信息
- 创建一个独有可访问的URI(
location ~ ^/.well-known/acme-challenge/
)提供给Let’s Encrypt检测,用于证书授权挑战(其他的还有诸如dns挑战等) - 创建一个专门用于证书申请的server(参见下述配置),将挑战文件统一将认证的文件root指定到(
/data/lets_challenge
)
4.2. nginx挑战服务配置
server {
listen 80 default_server;
# 1) 52explore.com (博客)
server_name 52explore.com www.52explore.com
# 2) archsatt.com (资料)
server_name archstat.com www.archstat.com;
# 3) tkstorm.com (博客)
server_name tkstorm.com www.tkstorm.com static.tkstorm.com;
# 4) psr100.cn (静态资源)
server_name psr100.cn www.psr100.cn;
server_name static.psr100.cn;
server_name pac.psr100.cn;
server_name git.psr100.cn;
server_name disqus.psr100.cn;
# 5) psr100.com
# server_name psr100.com www.psr100.com;
# 6) ioio.cool
# server_name ioio.cool www.ioio.cool;
# 7) heyman.cool
# server_name heyman.cool www.heyman.cool;
# let's encrypt域验证,我们把证书生成的内容存储到`/data/lets_challenge`中,让Let'S Encrypt进行查询认证
location ~ ^/.well-known/acme-challenge/ {
alias /data/lets_challenge;
try_files $uri =404;
}
# http请求转https
location / {
return 301 https://$host$request_uri;
}
}
针对所有域名80端口相关,提供给Let’ Encrypt的挑战,这个nginx服务,做了以下几个事情:
- 列出了所有需要进行证书签发的域名,进行统一管理授权和签发
- 将acme.sh把证书生成的内容存储到
/data/lets_challenge
中,设置一个locaiton,让Let’S Encrypt进行查询认证 - 为了统一处理,后续请求这些域名的http协议统一转发到https协议处理(这块当然也可以在各自的vhost中设定)
4.3. 通过acme.sh代理,进行ssl证书签发挑战:(正式申请去掉—test、debug)
// 签发支持多个域名的SAN证书
acme.sh --issue \
-d archstat.com -d www.archstat.com -d docker.archstat.com \
-d tkstorm.com -d www.tkstorm.com -d static.tkstorm.com \
-w /data/lets_challenge \
--test --debug
// psr100.cn
acme.sh --issue \
-d psr100.cn -d www.psr100.cn -d static.psr100.cn -d pac.psr100.cn -d git.psr100.cn -d disqus.psr100.cn\
-w /data/lets_challenge \
--test --debug
// psr100.com
acme.sh --issue \
-d psr100.com -d www.psr100.com\
-d 52explore.com -d www.52explore.com \
-w /data/lets_challenge \
--test --debug
4.4. domain认证挑战成功后,进行证书安装,acme.sh将自动创建一个cron任务,并自动签署和更新证书
acme.sh --install-cert \
-d archstat.com -d www.archstat.com -d docker.archstat.com\
-d tkstorm.com -d www.tkstorm.com -d static.tkstorm.com \
--cert-file /usr/local/nginx/conf/ssl/arch_tkstorm.cert \
--key-file /usr/local/nginx/conf/ssl/arch_tkstorm.key \
--fullchain-file /usr/local/nginx/conf/ssl/arch_tkstorm.fullchain \
--reloadcmd "systemctl restart nginx.service"
acme.sh --install-cert \
-d psr100.cn -d www.psr100.cn -d static.psr100.cn -d pac.psr100.cn -d git.psr100.cn -d disqus.psr100.cn\
--cert-file /usr/local/nginx/conf/ssl/psr100.cert \
--key-file /usr/local/nginx/conf/ssl/psr100.key \
--fullchain-file /usr/local/nginx/conf/ssl/psr100.fullchain \
--reloadcmd "systemctl restart nginx.service”
[root@tkstorm_proxy ~]# acme.sh --install-cert -d psr100.com -d www.psr100.com -d ip.psr100.com -d dns.psr100.com \
--cert-file /usr/local/nginx/conf/ssl/psr100.com.crt \
--key-file /usr/local/nginx/conf/ssl/psr100.com.key \
--fullchain-file /usr/local/nginx/conf/ssl/psr100.com.fullchain \
--reloadcmd "systemctl restart nginx.service”
4.5. 如果定时任务没有开启的话,开启定时任务自动更新签发证书,
acme.sh --install-cronjob
5. 结合使用又拍云CDN遇到的一些问题
考虑到站点CDN的使用,国内选择了又拍云,为了https的开启这块,需要把证书以及私钥提供给到CDN,或者是基于又拍云的HTTPS域名证书(貌似只支持单个域名,不是我希望的),故选择了前者,由此有几个问题需要特别注意下:
- ssl证书管理中的,https自签名证书的话,要提前上传(可能存在过期限制,需要定期更新)
- https的回源管理,源站证书检测不能开(否则出现503)
- https配置,需要添加源证书才可以访问
6. 参考
- 使用acme.sh: https://github.com/Neilpang/acme.sh
- staging-environment: letsencrypt.org的预发布环境
- using-acme-sh-with-nginx: https://www.rmedgar.com/blog/using-acme-sh-with-nginx