阿里云 Let's Encrypt 泛域名证书申请记录


Let's Encrypt 在去年 3 月份就已经推出泛域名证书支持了,十分不便。

目前比较常用的为 Let's Encrypt 生成证书的工具比较多,如:

  • cerbot
  • acme.sh
  • acme-tiny

这里我们将使用 acme.sh 这个工具来安装 Let's Encrypt 证书。acme.sh 是一个非常优秀的证书生成工具,其 官网 更是有详细的中文文档支持 ,基本使用只要看 GitHub 就好,这里我们着重讲 wiki 没有提到的内容。

生成证书

acme.sh 实现了 acme 协议支持的所有验证协议,一般有两种方式验证: httpdns 验证。由于泛域名证书的解析目前仅支持 DNS 方式验证,下面我们将阿里云解析的例子,其他地方的生成方法参考官方 wiki

1. 获取阿里云 App_KeyApp_Secret

考虑到安全性建议开启 RAM 访问控制 子账户accesskey和secret,然后给它分配云解析DNS的读写权限。

2. 配置环境变量。

export Ali_Key="你的key"
export Ali_Secret="你的secret"

acme.sh 会保存 App_KeyApp_Secret,如果更换了 App_KeyApp_Secret,一定要重新执行。

3. 生成证书。

acme.sh --issue -d byfuh.com -d '*.byfuh.com' --dns dns_ali

dns_ali 表示使用阿里云的 dns 验证脚本,其他地方的参考官方 wiki

4. 安装证书。

acme.sh --installcert -d byfuh.com -d *.byfuh.com\
    --key-file /etc/nginx/ssl/byfuh.com.key \
    --fullchain-file /etc/nginx/ssl/fullchain.cer \
    --reloadcmd "service nginx force-reload"

5. 生成 dhparam.pem 文件。

openssl dhparam -dsaparam -out /etc/nginx/ssl/dhparam.pem 4096

6. 配置Nginx

server {
    listen 80;
    listen [::]:80;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name byfuh.om www.byfuh.com;
    root /your-path/DjangoBlog/;

    access_log /your-path/django_access.log;
    error_log /your-path/django_error.log;

    location /static/ {
        alias /your-path/DjangoBlog/collectedstatic/;
        expires max;
        access_log        off;
        log_not_found     off;
    }

    location ~ \.py$ {
        return 403;
    }

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
        if (!-f $request_filename) {
            proxy_pass http://127.0.0.1:8000;
            break;
        }
    }

    ssl_certificate /your-path/ssl/fullchain.cer;
    ssl_certificate_key /your-path/ssl/byfuh.com.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;
    ssl_session_tickets off;

    ssl_dhparam /your-path/ssl/dhparam.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    add_header Strict-Transport-Security "max-age=63072000" always;

    ssl_stapling on;
    ssl_stapling_verify on;

    resolver 127.0.0.1;
}

常见错误

1. 没有配置环境变量或环境变量配置错误

root@localhost:/etc/letsencrypt# ./acme.sh --issue -d "*.byfuh.com" --dns dns_ali
[Tue Jan 20 17:21:28 CST 2019] Single domain='*.byfuh.com'
[Tue Jan 20 17:21:28 CST 2019] Getting domain auth token for each domain
[Tue Jan 20 17:21:30 CST 2019] Getting webroot for domain='*.byfuh.com'
[Tue Jan 20 17:21:30 CST 2019] Found domain api file: /etc/letsencrypt/dnsapi/dns_ali.sh
[Tue Jan 20 17:21:30 CST 2019] You don't specify aliyun api key and secret yet.
[Tue Jan 20 17:21:30 CST 2019] Error add txt for domain:_acme-challenge.byfuh.com
[Tue Jan 20 17:21:30 CST 2019] Please add '--debug' or '--log' to check more details.
[Tue Jan 20 17:21:30 CST 2019] See: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh

2. 子账户权限错误

root@localhost:/etc/letsencrypt# ./acme.sh --issue -d "*.byfuh.com" --dns dns_ali
[Tue Jan 20 17:23:27 CST 2019] Single domain='*.byfuh.com'
[Tue Jan 20 17:23:27 CST 2019] Getting domain auth token for each domain
[Tue Jan 20 17:23:29 CST 2019] Getting webroot for domain='*.byfuh.com'
[Tue Jan 20 17:23:29 CST 2019] Found domain api file: /etc/letsencrypt/dnsapi/dns_ali.sh
[Tue Jan 20 17:23:30 CST 2019] User not authorized to operate on the specified resource, or this API doesn't support RAM.
[Tue Jan 20 17:23:30 CST 2019] Error add txt for domain:_acme-challenge.byfuh.com
[Tue Jan 20 17:23:30 CST 2019] Please add '--debug' or '--log' to check more details.
[Tue Jan 20 17:23:30 CST 2019] See: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh

留意:这里并不需要授权整个RAM的权限,只需要给它管理云解析DNS的权限即可。

成功以后

  1. 删除 TXT 解析记录。
  2. 修改 Nginx 配置。