使用 acme.sh 申请免费的 SSL/TLS 通配符证书

# 简介

为了提升网站的安全性, 我们需要将 HTTP 协议升级为 HTTPS 协议, 其中的一个重要组成部分就是 SSL/TLS 证书.

你可以选择自己签发一张证书, 也可以选择向 证书签发机构 (CA) (opens new window) 申请一张证书.

这两种证书在功能上没有太大的区别, 但是浏览器检查到不受信任的证书时, 会拦截相关请求, 并用显著的方式提示用户, 极大地降低了用户体验.

而 CA 签发的证书则根据不同的证书等级, 要求浏览器对证书进行多重校验. 企业级的证书校验最为严格, 同时也非常昂贵.

对于个人与小规模企业而言, 则更倾向于使用免费证书. 但国内云厂商对于免费证书的签发有不同的限制, 比较常见地是只能签发单域名证书, 并且限制免费证书的数量.

那么有没有免费的通配符证书可供使用呢? 答案是肯定的.

Let's Encrypt (opens new window) 是一家免费, 开放和自动化的证书颁发机构. 由非盈利组织互联网安全研究小组 (ISRG) 运营.

接下来我们将演示如何使用 acme.sh (opens new window) 向 Let's Encrypt 申请一张免费的通配符证书.

# 准备环境

首先我们需要下载并安装 acme.sh (opens new window). 官方推荐使用 curl https://get.acme.sh | shwget -O - https://get.acme.sh | sh 进行在线的下载安装, 但国内时常访问不了 raw.githubusercontent.com (opens new window), 因此可以使用第二种方式进行安装:

git clone https://github.com/acmesh-official/acme.sh.git
cd ./acme.sh
./acme.sh --install

安装完成后重启终端以便 acme.sh 设置的环境变量生效. 另外, 刚刚 clone 下来的仓库可以删除, 只保留 .acme.sh 文件夹即可.

# 申请测试证书

我们可以先申请一张测试证书用于确认网络通畅, 并避免由于配置错误导致多次申请正式证书被拒绝而触发限流 (opens new window).

以阿里云为例, 将域名解析托管到阿里云后, 创建一个新的 RAM 用户 (opens new window), 开启 编程访问, 并授予 AliyunDNSFullAccess 权限, 然后将 AccessKey IDAccessKey Secret 保存到本地.

在终端中设置好环境变量 Ali_KeyAli_Secret 以便 acme.sh 能使用 dns 模式 (opens new window)申请证书:

export Ali_Key="${YOUR_RAM_ACCESS_KEY_ID}"
export Ali_Secret="${YOUR_RAM_ACCESS_KEY_SECRET}"

设置好以后, 即可通过命令:

acme.sh --issue *.sample.com --dns dns_ali --test --debug

申请一张测试用的证书. 如果你在申请测试证书时遇到异常, acme.sh 通常会给出相应的文档以协助你解决问题.

申请测试证书成功时, 你将看到类似以下的日志:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ...
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = Fake LE Intermediate X1
        Validity
            Not Before: Sep 16 06:46:23 2020 GMT
            Not After : Dec 15 06:46:23 2020 GMT
        Subject: CN = *.sample.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                ...
            X509v3 Authority Key Identifier:
                keyid:...

            Authority Information Access:
                OCSP - URI:http://ocsp.stg-int-x1.letsencrypt.org
                CA Issuers - URI:http://cert.stg-int-x1.letsencrypt.org/

            X509v3 Subject Alternative Name:
                DNS:*.sample.com
            X509v3 Certificate Policies:
                Policy: 2.23.140.1.2.1
                Policy: 1.3.6.1.4.1.44947.1.1.1
                  CPS: http://cps.letsencrypt.org

            CT Precertificate SCTs:
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : ...
                    Timestamp : Sep 16 07:46:23.148 2020 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                ...
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : ...
                    Timestamp : Sep 16 07:46:23.185 2020 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                ...
    Signature Algorithm: sha256WithRSAEncryption
         ...
[Wed Sep 16 15:46:23 CST 2020] Cert success.
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
[Wed Sep 16 15:46:23 CST 2020] Your cert is in  /root/.acme.sh/*.sample.com/*.sample.com.cer
[Wed Sep 16 15:46:23 CST 2020] v2 chain.
[Wed Sep 16 15:46:23 CST 2020] The intermediate CA cert is in  /root/.acme.sh/*.sample.com/ca.cer
[Wed Sep 16 15:46:24 CST 2020] And the full chain certs is there:  /root/.acme.sh/*.sample.com/fullchain.cer
[Wed Sep 16 15:46:24 CST 2020] _on_issue_success

现在, 你可以在 /root/.acme.sh/${YOUR_DOMAIN} 文件夹里找到以下文件:

  • ca.cer: PEM 格式的 CA 证书
  • fullchain.cer: PEM 格式的全链路证书
  • ${YOUR_DOMAIN}.cer: PEM 格式的证书
  • ${YOUR_DOMAIN}.conf: 申请证书时的配置
  • ${YOUR_DOMAIN}.csr: 证书请求
  • ${YOUR_DOMAIN}.csr.conf: 证书请求的配置
  • ${YOUR_DOMAIN}.key: PEM 格式的 RSA 密钥

# 申请正式证书

确认网络通畅并且配置无误后, 即可申请正式证书了:

acme.sh --issue *.sample.com --dns dns_ali --force

拿到正式证书以后, 你就可以把它部署到服务器上了.

关于 acme.sh 的更多使用方式, 请参考 wiki (opens new window)

# 参考