acme 自动申请ssl证书,使用 https
现在,随便一个网站都实现了 https 协议,相比于http,s是security(安全),这里有对称加密和非对称加密的知识点。
我的个人网站,也接入了https。https证书有免费的也有收费的,个人网站搞免费的就行了。
acme介绍
acme.sh 是一个开源的,实现 ACME 客户端协议的纯 Unix shell 脚本,提供颁发、安装和自动更新证书、邮件通知等功能。随着作者不断更新,未来将支持更多 CA,默认的 CA 是 ZeroSSL,也可以切换为 Let’s Encrypt
自动化更新ssl证书
- 安装 acme.sh
- 生成证书
- copy 证书到 nginx/apache 或者其他服务
- nginx修改conf引用证书
其他步骤和命令都是以上 4 个步骤的扩展,比如acme的更新、定时任务处理、信息查询等等。
第一步,安装。可以用命令安装。
curl https://get.acme.sh | sh -s email=my@example.com
但是,我发现我的腾讯云服务器安装很慢,那也可以去github或者gitee把完整的 git 仓库用https下载下来,再用sftp传到云服务器中,再解压安装,它是绿色免安装的。
第二步,生成证书。
方法有 http 或者 dns 两种模式。
- HTTP 模式,需要在你的网站根目录下放置一个文件, 来验证你的域名所有权。
- DNS 模式,手动或使用 DNS 解析服务商提供的 api 添加 txt 解析记录验证域名所有权。
二选一即可,我们的目标是选择最自动化、最简单的那种,另一种不考虑也不学习。所以选择 DNS 模式。
步骤:
- 会使用域名服务商提供的 api 自动为你的域名添加一条 txt 解析,验证成功后, 这条解析记录会被删除,大概需要等待 1、2 分钟 等待 DNS 解析。 这需要在域名服务商后台申请 Api Token,各个厂商的链接合集是:
- 执行以下命令申请证书(以腾讯云为例,其他厂商以此类推,变量名不同而已)
export Tencent_SecretId="你从腾讯云拿到的id"
export Tencent_SecretKey="你从腾讯云拿到的key"
# 申请证书,执行后参数将保存至 ~/.acme.sh/account.conf 在自动续期时使用。
acme.sh --issue --dns dns_tencent -d xiaoqiuqiu.cn -d *.xiaoqiuqiu.cn
打印日志出现 Cert success 表示成功。
- acme 会生成证书,放到acme自带的目录下,和nginx目录不同,这两个目录不要共用,因为会变。所以要拷贝证书文件。
有 2 种方式,一种是copy命令;另一种是用 acme 提供的命令,第二种集成了几个操作,更方便,我们用第二种。
# 使用本机命令安装
$ acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com/key.pem \
--fullchain-file /etc/nginx/ssl/example.com/fullchain.pem \
--reloadcmd "nginx -s reload"
优点是:执行命令后,证书文件会被copy到相应的位置,随后命令中的参数将保存在 ~/.acme.sh/example.com 目录下的 example.com.conf 文件里, 定时任务在自动更新证书的时候会使用这里的参数部署新的证书和 reload 服务器。
所以,第一种手动也是可以的,copy后自己reload nginx,但以后都要自己处理,定时任务维护也要关注了,那还不如用 acme 的 --install-cert
更方便。
- 我们需要在
/etc/nginx/conf/nginx.conf
增加 https ssl 的配置,
- 可以直接在 nginx.conf 加上 ssl
- 也可以另外搞个 ssl.conf 配置,然后 nginx.conf include(引用)
第二种间接模式,维护更清晰,后者也是我写文章后才知道的,前者网上一堆的文档。我们试试后者。
在 /etc/nginx/snippets 目录下创建代码片段文件 ssl-params.conf 专门拿来配置 SSL 相关的设置
PS: 其实,不需要这么多字段配置,只需要开启和对应的路径就可以跑起来了,其他配置都是优化项。
/etc/nginx/snippets/ssl-params.conf
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 60m;
ssl_session_tickets on;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 10s;
ssl_prefer_server_ciphers on;
# 证书文件绝对路径
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
# 以下配置来自 [提高安全性的最佳 Nginx 配置](https://godruoyi.com/posts/best-nginx-configuration-for-improved-security),建议参考。
server_tokens off;
add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload";
add_header X-Frame-Options deny;
add_header X-Content-Type-Options nosniff;
add_header x-xss-protection "1; mode=block";
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: https:; connect-src 'self' https:; img-src 'self' data: https: blob:; style-src 'unsafe-inline' https:; font-src https:";
/etc/nginx/nginx.conf
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server
{
listen 443 ssl http2 fastopen=3 reuseport;
server_name example.com www.example.com;
# 引入 ssl 配置,如果申请的是泛域名证书,使用 include 就可以很方便地管理多个站点
include snippets/ssl-params.conf;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
#root /www/example.com;
#index index.html index.htm;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8080;
}
}
# 测试配置是否成功
$ nginx -t
# 重启 web 服务
$ nginx -s reload
ssl 证书自动续期
acme.sh 安装时会使用 cron 创建定时任务, 默认的计划任务是每天 0:00 点检查一次是否需要续期。 定时任务可以通过 crontab -l 命令查看。
手动配置也可以,具体看 acme.sh -help,这里面一大堆命令提示使用。
参考文档
其实,就是安装、配置、重启nginx的工作,至于acme的协议和原理,可以不关心。
它本质是个shell和定时任务,实现了acme协议,实现了去 CA机构申请证书,并做 DNS 解析的工作,把人工在云服务器上的申请操作用脚本替代了。
网上有很多文档,推荐看github 中文版或者英文版的 wiki readme
https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E
https://mucen.cn/blog/acme/#:~:text=acme.sh%20%E5%AE%89%E8%A3%85
ssl证书,免费和收费的区别
- 免费SSL证书 通常为网站 域名 型DV SSL证书,仅用以出示基础级别的身份认证,常见于中小型网址和搏客等服务平台。免费SSL证书没有机构认证(OV)和拓展认证(EV)证书的种类。
- 收费SSL证书则有OV和EV种类的SSL证书,这针对维护商务网站是绝对必需的。
- 免费SSL证书仅搜索框显示信息HTTPS和程序锁标志,收费的OV和EV SSL证书除开显示信息HTTPS和程序锁标志,还能查寻到企业详细资料,EV SSL证书还能使搜索框变为绿色,并在搜索框立即展现公司名字。这种标志提升了顾客对网址的信任感,并且顾客在网址买卖交易的机遇大大增加。
acme协议
- ACME,即自动自动证书管理环境(Automatic Certificate Management Environment),是一种协议,用于自动颁发和更新证书,无需人工干预。
- 自动化证书管理环境(ACME)是用于自动验证X.509证书的域验证,安装和管理的标准协议。 ACME协议由Internet安全研究小组设计,并在 IETF RFC 8555。 作为具有许多可用的客户端实现的文档齐全的开放标准,ACME被广泛用作企业证书自动化解决方案。
杂谈
很多配置和方案,并不是只有一种解决方法,但我们仅需要熟悉简单的那种即可,至于复杂的,知道名字就好了,实际上用不到的。
- 我们知道 MySQL 有 MyISAM 引擎,但是实际上用的时候有用吗?大部分场景没使用,而是用了 InnoDB
- 我们知道 Java 做 web 不仅仅有 SpringBoot 这一套,还有老式的自带tomcat、SpringMVC、甚至其他web容器,但市面上大多数用的就是 SpringBoot,现在新入行的人都不知道 tomcat 这小狐狸。
现在工具这么多,每个场景都有更合适的组件来实现,最佳实践和配置也很丰富,我们不需要知道「茴香豆的茴有多少种写法」,而是要知道「会写多少个字」。
很多东西知道大致、原理、步骤即可,真需要用的时候再查询文档,这样脑袋才够用啊。