Let’s Encrypt SSL證書申請

當前環境:

  • 阿里雲CoreOS
  • 所綁定的域名,解析管理也在阿里這兒,在該文檔中使用 example.com 作為示例。
  • Docker 鏡像 neilpang/acme.sh:2.8.8 //github.com/acmesh-official/acme.sh
  • nginx 申請證書並使用
  • 使用Docker-Compose
  • SSL證書為泛域名證書

實際應用中可以參考下面兩篇文章:

  • 2. Deploy certs from a container to another container 第二部分
  • DNS API 參考這部分 11. Use Aliyun domain API to automatically issue cert
  • acme.sh dns模式支援 Cloudflare, DNSPod.cn, CloudXNS.com, GoDaddy.com, Amazon Route53, Aliyun, Linode, FreeDNS, DigitalOcean 等大概一百多個域名解析提供商,本文使用的是阿里雲域名解析,申請SSL的時候會往域名解析力添加一條TXT記錄來驗證域名所有權。

目的:

  • 在阿里雲CoreOS操作環境中綁定 Let’s Encrypt SSL證書並使用。(不是很清楚使用這種方式能否實現證書自動續費,證書是3個月有效期,也許3個月之後就可以知道了。)

下載所需鏡像

個人習慣喜歡先把所需要的鏡像給下載下來,不喜歡用latest標籤,因為覺得如果新版本有功能更新的話,會讓人迷糊。
Docker-Compose的安裝略過。

$ sudo docker pull nginx:1.19.6-alpine
$ sudo docker pull neilpang/acme.sh:2.8.8

創建docker-compose.yml文件

version: '3'
  
services:
  runNginx:
    image: nginx:1.19.6-alpine
    container_name: runNginx
    volumes:
      - /data/docker_config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - /data/docker_config/nginx/ssl:/etc/nginx/ssl
    ports:
      - 80:80
      - 443:443
    depends_on:
      - runAcmesh
    environment:
      - NGINX_PORT=80
    labels:
      - sh.acme.autoload.domain=example.com
  runAcmesh:
    image: neilpang/acme.sh:2.8.8
    container_name: runAcmesh_example.com
    command: daemon
    volumes:
      - /data/docker_config/acme.sh:/acme.sh
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DEPLOY_DOCKER_CONTAINER_LABEL=sh.acme.autoload.domain=example.com
      - DEPLOY_DOCKER_CONTAINER_KEY_FILE="/etc/nginx/ssl/example.com/key.pem"
      - DEPLOY_DOCKER_CONTAINER_CERT_FILE="/etc/nginx/ssl/example.com/cert.pem"
      - DEPLOY_DOCKER_CONTAINER_CA_FILE="/etc/nginx/ssl/example.com/ca.pem"
      - DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/etc/nginx/ssl/example.com/full.pem"
      - DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload"

修改 /data/docker_config/nginx/nginx.conf 啟用 ssl, Configuring HTTPS servers

# HTTPS server

server {
    listen       443 ssl;
    server_name  example.com;

    ssl_certificate      /etc/nginx/ssl/example.com/cert.pem;
    ssl_certificate_key  /etc/nginx/ssl/example.com/key.pem;;

    location / {
        root   html;
        index  index.html index.htm;
    }
}

啟動 docker-compose

進入dockerr-compose.yml所在的目錄啟動容器 sudo docker-compose up -d

沒猜錯的話啟動結果應該是nginx啟動失敗,acme.sh啟動成功,啟動失敗無所謂,部署完SSL證書以後會進行一次重啟。

CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS                  PORTS                                      NAMES
64879a113906        nginx:1.19.6-alpine        "/docker-entrypoint.…"   About an hour ago   Exited ...              0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   runNginx
bfa2973c990a        neilpang/acme.sh:2.8.8     "/entry.sh daemon"       About an hour ago   Up About an hour                                                   runAcmesh_guorenjun.com.cn

申請證書

第一步需要獲取你的阿里雲 API Key, 既API KEYAPI Security,官方推薦使用子賬戶來申請,但是不確定需要賦值哪個許可權,總是提示Invalid Domain,用了Root的API Key一次申請通過,看了一下許可權列表好像是這個AliyunDNSFullAccess 管理雲解析(DNS)的許可權。阿里雲APIKEY管理頁面在這裡://ak-console.aliyun.com/#/accesskey

獲取API KEY之後,執行如下命令:

sudo docker exec -e Ali_Key="iAihASlUDxxxxxxx" -e Ali_Secret="FaYpsThfLRbQ99UaHWvvibqxxxxxxx" runAcmesh_example.com --issue --dns dns_ali -d *.example.com

Ali_KeyAli_Secret 就是獲取的阿里雲訪問許可權的KEY, runAcmesh_example.com是已運行的容器名字,也可以用容器ID來代替, *.example.com 要申請的域名,這個是泛域名,如果不想申請泛域名,只想申請 www.example.comexample.com 的話,可以指定多個 -d 參數,例如 -d www.example.com -d example.com -d test.example.com 不過好像每次申請的SSL證書有域名大小限制。

如果順利的話輸出內容如下:

[Sat Jan  9 08:20:20 UTC 2021] Using CA: //acme-v02.api.letsencrypt.org/directory
[Sat Jan  9 08:20:20 UTC 2021] Creating domain key
[Sat Jan  9 08:20:20 UTC 2021] The domain key is here: /acme.sh/*.example.com/*.example.com.key
[Sat Jan  9 08:20:20 UTC 2021] Single domain='*.example.com'
[Sat Jan  9 08:20:20 UTC 2021] Getting domain auth token for each domain
[Sat Jan  9 08:20:27 UTC 2021] Getting webroot for domain='*.example.com'
[Sat Jan  9 08:20:27 UTC 2021] Adding txt value: ToXXnzTdkmwb6Yqn85bl01MzbdrgVCpITb0U7_cB4nI for domain:  _acme-challenge.example.com
[Sat Jan  9 08:20:28 UTC 2021] The txt record is added: Success.
[Sat Jan  9 08:20:28 UTC 2021] Let's check each DNS record now. Sleep 20 seconds first.
[Sat Jan  9 08:20:48 UTC 2021] Checking example.com for _acme-challenge.example.com
[Sat Jan  9 08:20:52 UTC 2021] Domain guorenjun.com.cn '_acme-challenge.example.com' success.
[Sat Jan  9 08:20:52 UTC 2021] All success, let's return
[Sat Jan  9 08:20:52 UTC 2021] Verifying: *.example.com
[Sat Jan  9 08:20:57 UTC 2021] Success
[Sat Jan  9 08:20:57 UTC 2021] Removing DNS records.
[Sat Jan  9 08:20:57 UTC 2021] Removing txt: ToXXnzTdkmwb6Yqn85bl01MzbdrgVCpITb0U7_cB4nI for domain: _acme-challenge.example.com
[Sat Jan  9 08:20:59 UTC 2021] Removed: Success
[Sat Jan  9 08:20:59 UTC 2021] Verify finished, start to sign.
[Sat Jan  9 08:20:59 UTC 2021] Lets finalize the order.
[Sat Jan  9 08:20:59 UTC 2021] Le_OrderFinalize='//acme-v02.api.letsencrypt.org/acme/finalize/108848397/721xxxxxxx'
[Sat Jan  9 08:21:01 UTC 2021] Downloading cert.
[Sat Jan  9 08:21:01 UTC 2021] Le_LinkCert='//acme-v02.api.letsencrypt.org/acme/cert/0335cdb097496f91f09c53ea7af14xxxxxxx'
[Sat Jan  9 08:21:03 UTC 2021] Cert success.
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
[Sat Jan  9 08:21:03 UTC 2021] Your cert is in  /acme.sh/*.example.com/*.example.com.cer 
[Sat Jan  9 08:21:03 UTC 2021] Your cert key is in  /acme.sh/*.example.com/*.example.com.key 
[Sat Jan  9 08:21:03 UTC 2021] The intermediate CA cert is in  /acme.sh/*.example.com/ca.cer 
[Sat Jan  9 08:21:03 UTC 2021] And the full chain certs is there:  /acme.sh/*.example.com/fullchain.cer 

docker-compose.yml中已經將/acme.sh目錄link到了/data/docker_config/acme.sh目錄,在該目錄可以看到申請的一套ssl證書。

部署SSL證書

還差最後一步部署SSL證書,執行如下命令:

$ sudo docker exec runAcmesh_example.com --deploy -d *.example.com --deploy-hook docker

輸出如下命令:

[Sat Jan  9 08:22:53 UTC 2021] Container id: 64879a113906f04d0227b8fc26321bc030cd38a2b69d7fe7462c2e7726bxxxxx
[Sat Jan  9 08:22:53 UTC 2021] Copying file from /acme.sh/*.example.com/*.example.com.key to /etc/nginx/ssl/example.com/key.pem
[Sat Jan  9 08:22:54 UTC 2021] Copying file from /acme.sh/*.example.com/*.example.com.cer to /etc/nginx/ssl/example.com/cert.pem
[Sat Jan  9 08:22:54 UTC 2021] Copying file from /acme.sh/*.example.com/ca.cer to /etc/nginx/ssl/example.com/ca.pem
[Sat Jan  9 08:22:55 UTC 2021] Copying file from /acme.sh/*.example.com/fullchain.cer to /etc/nginx/ssl/example.com/full.pem
[Sat Jan  9 08:22:55 UTC 2021] Reloading: service nginx force-reload
[Sat Jan  9 08:22:56 UTC 2021] Success

至此部署完成.

docker-compose.yml中的配置項/data/docker_config/nginx/ssl:/etc/nginx/ssl,猜測部署是把SSL文件移動到nginx容器中,但是容器重啟會將文件丟失,所以link到了物理機上面,在執行 docker-compose up 文件是否會自動複製沒有進行驗證,只是多做了一步link。

不出意外的話,用https協議訪問網址應該就沒問題了。

其他不知道有沒用的參考:

Tags: