申请并部署免费的 SSL/TLS 证书

对于囊中羞涩的我们来说,只要能白嫖,就绝不乱花钱。惯常申请免费 SSL/TLS 证书的途径有:

  • 各大云服务平台限量提供。比如阿里云会给每个账号每年 20 个证书的申请额度。缺点是不支持泛域名,一年后须重新申请并部署;
  • 一些网络服务商如Cloudflare会提供自动化的证书服务,只要在它们的官网作简单配置即可。缺点是流量都要经其中转,在某些未很好覆盖的区域网站性能会受限;
  • 直接从免费证书颁发机构(CA)那里申请。通过脚本可使得获取、安装和续期 SSL/TLS 证书完全自动化。缺点是有一定的操作门槛。

本文介绍最后这种方式。

免费 CA 选择

免费 CA,常考虑的有 Let's EncryptZeroSSL。两者差异可自行网搜,基本上都能满足我们普通用户的需求,选择哪一个更依赖于申请过程是否顺利。

以 Let's Encrypt 作一简单介绍。它是由 Internet Security Research Group (ISRG) 发起的公共利益项目,于2016年推出,由 Mozilla, Cisco, Akamai, Linux Foundation, Google, Microsoft, OVH 和其它一些组织支持。这个项目的主要目标是促进 HTTPS 协议的普及。Let's Encrypt 使用 ACME 协议来验证您对给定域名的控制权并向您颁发证书,也就是说,要获得 Let's Encrypt 证书,需要选择一个 ACME 客户端。

这里以 acme.sh 为例。acme.sh 实现了 ACME 协议, 默认 CA 是 ZeroSSL。然而笔者在申请时一直报Order status is processing, lets sleep and retry,retry 多次后报 504,不知为何。所以笔者将默认 CA 设置为 Let's Encrypt:acme.sh --set-default-ca --server letsencrypt

申请并部署证书

安装 acme.sh

不清楚 docker 模式安装会否自动续期,所以直接安装到宿主机 curl https://get.acme.sh | sh -s email=xxx@xxx。直接安装会自动创建 cronjob, 每天自动检测所有的证书, 如果快过期了需要更新, 则会自动更新证书。

如前所述,设置默认 CA:acme.sh --set-default-ca --server letsencrypt

申请

在证书申请过程中,acme.sh 需要确认域名属于你本人,有两种验证方式:http 和 dns。

  • http mode: 支持自动更新证书;不支持通配符即泛域名。
  • dns mode:支持泛域名;但如果不同时配置 Automatic DNS API,将无法自动更新证书,每次都需要手动再次重新解析验证域名所有权。所以,如果你有多个二级域名需要绑定证书,要么就使用下述 http mode 的指令,要么就去 dns 服务商处拿到 API Access(可能会有一些要求)。 参看acme.sh 支持的 dns 服务商列表

这里我们以 http mode 为例。

先设置好 DNS 解析记录,将待申请证书的域名 A 记录到服务器 IP。然后如下脚本申请证书,acme.sh 会同时进行域名验证。

acme.sh --issue -d demo.com -d www.demo.com -d admin.demo.com --webroot /srv/www/html/

只需要指定域名,并指定对应的网站根目录,acme.sh 会自动生成验证文件,并放到网站根目录,然后自动完成验证,最后会删除验证文件。

如果你用的是直接在宿主机安装的 nginx 服务器,甚至不需要指定网站根目录。acme.sh 可以智能地依据 nginx 配置自动完成验证:

acme.sh --issue -d demo.com ... --nginx

上述脚本的前提是 acme.sh 可以调用 nginx 指令,否则会报 nginx command is not found 错误。所以如果 nginx 是以 docker 方式安装,这种方式将无法成功;还是得使用 --webroot 的方式,只要将 nginx 根目录映射出来即可,如下:

docker run --name ngix -v /srv/www/html:/usr/share/nginx/html:ro -v /srv/www/nginx.conf:/etc/nginx/nginx.conf:ro -p 80:80 -p 443:443 --network inner_net --restart=always -d --label=sh.acme.autoload.domain=anything nginx:stable-alpine

注意脚本中的 label,用于后续部署证书时 acme.sh 定位该容器。这里的 anything 可以替换为任意字符。

域名验证无误的话,acme.sh 会去 CA 那里获取证书,并下载到本地。一个主域名及其多个子域名同时申请的话,CA 只为它们签发一张证书。

部署

还是以 nginx docker 容器为例。

shell 复制代码
# The label value to find the container
# 多个不同域名申请证书时可重复使用该容器
export DEPLOY_DOCKER_CONTAINER_LABEL=sh.acme.autoload.domain=anything

# The target file path in the container.
# The files will be copied to the position in the container.
export DEPLOY_DOCKER_CONTAINER_KEY_FILE="/etc/nginx/ssl/demo.com/key.pem"
export DEPLOY_DOCKER_CONTAINER_CERT_FILE="/etc/nginx/ssl/demo.com/cert.pem"
export DEPLOY_DOCKER_CONTAINER_CA_FILE="/etc/nginx/ssl/demo.com/ca.pem"
export DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/etc/nginx/ssl/demo.com/full.pem"

# The command to reload the service in the container.
export DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="nginx -s reload"

# -d 指定 acme.sh --issue 时第一个[二级]域名或其执行结果产生的目录名
acme.sh --deploy --deploy-hook docker -d demo.com

笔者尚不清楚自动更新证书时是否会将新证书自动拷贝至容器内,推测应该是会的,这些临时环境变量应该会以当前申请的域名配置项的形式固化到磁盘中。

配置 nginx.conf

在 http 节中加入如下配置

conf 复制代码
server {
     listen 443 ssl;
     # 二级域名配置相同,本文略过
     server_name demo.com;
     root /usr/share/nginx/html;
     # 上一步证书拷贝的地址
     ssl_certificate /etc/nginx/ssl/demo.com/cert.pem;
     ssl_certificate_key /etc/nginx/ssl/demo.com/key.pem;
 
     ssl_session_cache shared:SSL:1m;
     ssl_session_timeout 5m;
 
     #默认加密套件
     ssl_ciphers HIGH:!aNULL:!MD5;
     #表示优先使用服务端加密套件。默认开启
     ssl_prefer_server_ciphers on; 
 
    location / {
           index index.html index.htm;
    }
}

吊销证书

假如因某种原因需要吊销证书的话,可执行如下脚本:

shell 复制代码
acme.sh --revoke -d demo.com -d www.demo.com -d admin.demo.com

笔者尚不清楚在一个主域名及其多个子域名共用一张证书的情况下,是否可只给部分域名吊销证书。

相关推荐
疯狂飙车的蜗牛2 分钟前
从零玩转CanMV-K230(4)-小核Linux驱动开发参考
linux·运维·驱动开发
恩爸编程1 小时前
探索 Nginx:Web 世界的幕后英雄
运维·nginx·nginx反向代理·nginx是什么·nginx静态资源服务器·nginx服务器·nginx解决哪些问题
Michaelwubo2 小时前
Docker dockerfile镜像编码 centos7
运维·docker·容器
好像是个likun3 小时前
使用docker拉取镜像很慢或者总是超时的问题
运维·docker·容器
cominglately5 小时前
centos单机部署seata
linux·运维·centos
CircleMouse5 小时前
Centos7, 使用yum工具,出现 Could not resolve host: mirrorlist.centos.org
linux·运维·服务器·centos
Karoku0666 小时前
【k8s集群应用】kubeadm1.20高可用部署(3master)
运维·docker·云原生·容器·kubernetes
木子Linux6 小时前
【Linux打怪升级记 | 问题01】安装Linux系统忘记设置时区怎么办?3个方法教你回到东八区
linux·运维·服务器·centos·云计算
mit6.8246 小时前
Ubuntu 系统下性能剖析工具: perf
linux·运维·ubuntu
watermelonoops6 小时前
Windows安装Ubuntu,Deepin三系统启动问题(XXX has invalid signature 您需要先加载内核)
linux·运维·ubuntu·deepin