Linux 下基于 acme.sh 脚本实现域名证书的自动签注与续签部署


acme.sh_install_ubuntu_自动申请域名ssl证书

  • Linux 下基于 acme.sh 脚本实现域名证书的自动签注与续签部署
  • acme.sh_install_ubuntu_自动申请域名ssl证书
    • 0.前言
    • 1. 安装 acme.sh
      • 1.1.脚本安装
      • 2.git 仓库安装
    • 2.证书申请
      • 2.1.1.自行生成验证文件进行验证
      • 2.1.2.调用服务配置文件进行验证
    • 2.2.调用 DNS 服务商的 API 进行验证生成证书
      • 2.2.1.手动验证 DNS 解析生成证书
      • 2.2.2.自动验证 DNS 解析生成证书
  • 3.安装证书(copy)
  • 4.更新域名证书
  • 5.更新 acme.sh 脚本
  • 6.故障处理
  • 10.参考地址:

0.前言

  • 目前的网站如果不使用 https 进行加密的网站大多会被浏览器标注个大大的“不安全”,看着 low,实际上也不安全
  • 本文旨在解决上面这个问题,为你提供一个舒爽的上网站点,嘿嘿嘿
  • 基于 acme.sh 脚本工具实现域名证书的自动申请,签发,部署,自动续签并部署证书

1. 安装 acme.sh

  • 普通用户和 root 用户都可以安装使用,但是建议 root 安装
  • 使用说明:
    https://github.com/acmesh-official/acme.sh/wiki/How-to-install

1.1.脚本安装

curl  https://get.acme.sh | sh
# or
wget -O -  https://get.acme.sh | sh

2.git 仓库安装

# 简单安装
git clone https://github.com/acmesh-official/acme.sh.git
cd ./acme.sh
./acme.sh --install

# 或者自定义安装
git clone https://github.com/Neilpang/acme.sh.git
cd acme.sh
./acme.sh --install  \
--home ~/myacme \
--config-home ~/myacme/data \
--cert-home  ~/mycerts \
--accountemail  "my@example.com" \
--accountkey  ~/myaccount.key \
--accountconf ~/myaccount.conf \
--useragent  "this is my client."

----------------------
--home is a customized dir to install acme.sh in. By default, it installs into ~/.acme.sh
--config-home is a writable folder, acme.sh will write all the files(including cert/keys, configs) there. By default, it's in --home
--cert-home is a customized dir to save the certs you issue. By default, it's saved in --config-home.
--accountemail is the email used to register account to Let's Encrypt, you will receive renewal notice email here. Default is empty.
--accountkey is the file saving your account private key. By default it's saved in --config-home.
--useragent is the user-agent header value used to send to Let's Encrypt.
----------------------
  • 注意:安装完成,需要重新登陆控制台以便脚本命令生效

  • 实例演示:

--------------------------------------
root@zuiyoujie:/opt/scripts# curl  https://get.acme.sh | sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   775    0   775    0     0    612      0 --:--:--  0:00:01 --:--:--   612
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  201k  100  201k    0     0  27932      0  0:00:07  0:00:07 --:--:-- 15894
[Tue Aug 25 17:53:16 CST 2020] Installing from online archive.
[Tue Aug 25 17:53:16 CST 2020] Downloading https://github.com/acmesh-official/acme.sh/archive/master.tar.gz
[Tue Aug 25 17:53:27 CST 2020] Extracting master.tar.gz
[Tue Aug 25 17:53:27 CST 2020] It is recommended to install socat first.
[Tue Aug 25 17:53:27 CST 2020] We use socat for standalone server if you use standalone mode.
[Tue Aug 25 17:53:27 CST 2020] If you don't use standalone mode, just ignore this warning.
[Tue Aug 25 17:53:27 CST 2020] Installing to /root/.acme.sh
[Tue Aug 25 17:53:27 CST 2020] Installed to /root/.acme.sh/acme.sh
[Tue Aug 25 17:53:27 CST 2020] Installing alias to '/root/.bashrc'
[Tue Aug 25 17:53:27 CST 2020] OK, Close and reopen your terminal to start using acme.sh
[Tue Aug 25 17:53:27 CST 2020] Installing cron job
[Tue Aug 25 17:53:27 CST 2020] Good, bash is found, so change the shebang to use bash as preferred.
[Tue Aug 25 17:53:28 CST 2020] OK
[Tue Aug 25 17:53:28 CST 2020] Install success!
--------------------------------------
  • 具体的安装操作内容如下
1.把 acme.sh 安装到你的 home 目录下,并创建 一个 bash 的 alias 别名,方便使用: 
ll ~/.acme.sh/
alias acme.sh=~/.acme.sh/acme.sh

2.创建 cronjob, 每天 0:27 点自动检测所有的证书,如果快过期了,需要更新,则会自动更新证书
更高级的安装选项请参考: https://github.com/Neilpang/acme.sh/wiki/How-to-install
安装过程不会污染已有的系统任何功能和文件 , 所有的修改都限制在安装目录中: ~/.acme.sh/

2.证书申请

  • 确认工具对指定的域名是否有操作权限(域名归属)
  • HTTP 服务验证方式对服务器上安装的 web 服务有要求,需要有 web 服务器
  • 如果基础环境不合适可以选的DNS API方式生成证书,也更加方便

2.1.http 验证方式生成证书

2.1.1.自行生成验证文件进行验证

acme.sh  --issue -d www.zuiyoujie.com  --webroot  /home/wwwroot/www.zuiyoujie.com/

# 这种方式要求用户对 http 服务器有操作权限可以上传文件,最简单的是在 http 服务器上部署 acme.sh 脚本
# 该命令需要指定域名,指定域名站点所在网站的根目录,acme.sh 会在网站根目录生成验证文件,完成验证,之后自动清理验证文件

2.1.2.调用服务配置文件进行验证

# 如果 web 服务是 apt 或者 yum 安装的 apache,acme.sh 可以从 apache 的配置中自动完成验证,不需要指定网站根目录
acme.sh --issue  -d www.zuiyoujie.com.com   --apache

# 如果 web 服务是 apt 或者 yum 安装的 nginx,或者反代,acme.sh 可以从 nginx 的配置中自动完成验证,你不需要指定网站根目录:
acme.sh --issue  -d www.zuiyoujie.com.com  --nginx

# 如果服务器没有运行 web 服务,80 端口是空闲的,那么 acme.sh 还能伪装成一个 webserver, 临时监听 80 端口,完成验证:
acme.sh  --issue -d www.zuiyoujie.com.com  --standalone

2.2.调用 DNS 服务商的 API 进行验证生成证书

  • 特点:不需要有 web 服务器和任何公网 IP,但是如果不配置 AKSK 无法配置自动更新证书

2.2.1.手动验证 DNS 解析生成证书

# 执行以下命令,将返回的 txt 解析记录配置到对应的域名解析中
acme.sh  --issue  --dns  -d www.zuiyoujie.com --yes-I-know-dns-manual-mode-enough-go-ahead-please

# 解析完成后,使用以下命令生成证书
acme.sh  --renew   -d www.zuiyoujie.com

2.2.2.自动验证 DNS 解析生成证书

  • 支持主流 DNS 域名服务商(115个),具体参考以下地址:

https://github.com/acmesh-official/acme.sh/wiki/dnsapi

  • 更详细的 api 用法:

https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md

  • 这里以阿里云域名为例进行演示:
# 导入 AKSK,这里 api id 和 api key 会被自动记录到 account.conf 文件中,其他文件不需要修改
# 修改 account.conf 文件可以开启日志
# 具体的变量名称可以到上面的文档 或者 dnsapi 目录中的脚本中查看
Ali_Key="AKAKAKAK"
Ali_Secret="SKSKSKSK"
export Ali_Key="AKAKAKAK"
export Ali_Secret="SKSKSKSK"

# 自动验证 DNS,生成域名证书
acme.sh --issue --dns dns_ali -d www.zuiyoujie.com      #  可以单独申请单个域名证书
acme.sh --issue --dns dns_ali -d zuiyoujie.com -d *.zuiyoujie.com       # 可以申请顶级域名证书和通配符二级域名证书

# 注意:会在工作目录生成以第一个域名为名称的目录,里面存放生成的配置文件和证书文件
# 可以指定多个域名,但是域名不能有重复,例如 www.zuiyoujie.com 和 *.zuiyoujie.com,后者包含前者

# 强制重新生成证书(刷新证书有效期)
acme.sh --renew --dns dns_ali -d www.zuiyoujie.com

# 如果证书未到期可能需要加 --force 参数强制签注
acme.sh --renew --dns dns_ali -d www.zuiyoujie.com --force

# 查看现有证书列表
acme.sh --list

# 删除指定的证书(不会删除证书目录和文件)
acme.sh --remove -d www.zuiyoujie.com

# 或者直接删除证书目录
rm -rf www.zuiyoujie.com
  • 注意:申请通配符证书需要加 -d zuiyoujie.com -d *.zuiyoujie.com ,以下是解释部分:
# 关于泛域名需要注意的事项:

1.泛域名是带通配符的域名,只能代表所有的二级域名
类似 "com" "cn" 是顶级域名
类似 "zuiyoujie.com" 是一级域名,
类似 "www.zuiyoujie.com" 是二级域名
类似 "blog.www.zuiyoujie.com" 是三级域名
类似 "*.zuiyoujie.com" 是一个泛域名,可以涵盖所有二级域名
但是不包含一级域名 "zuiyoujie.com" 和三级域名 "blog.www.zuiyoujie.com"

2.申请一个泛域名证书并不能应用于所有网站,
需要同时为泛域名 "*.zuiyoujie.com" 和一级域名 "zuiyoujie.com" 申请证书

3.三级域名需要单独申请域名证书
  • 实例演示:
# 新签注证书 
-----------------------------------------------
root@zuiyoujie:~/.acme.sh# acme.sh --issue --dns dns_ali -d www.zuiyoujie.com
[Tue Aug 25 21:01:00 CST 2020] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Tue Aug 25 21:01:00 CST 2020] Creating domain key
[Tue Aug 25 21:01:00 CST 2020] The domain key is here: /root/.acme.sh/www.zuiyoujie.com/www.zuiyoujie.com.key
[Tue Aug 25 21:01:00 CST 2020] Single domain='www.zuiyoujie.com'
[Tue Aug 25 21:01:00 CST 2020] Getting domain auth token for each domain
[Tue Aug 25 21:01:12 CST 2020] Getting webroot for domain='www.zuiyoujie.com'
[Tue Aug 25 21:01:12 CST 2020] Adding txt value: TX4Rh-fS04vBqvfn3LwhtkbqOCTRaAb7OIaXIfgC_xU for domain:  _acme-challenge.www.zuiyoujie.com
[Tue Aug 25 21:01:15 CST 2020] The txt record is added: Success.
[Tue Aug 25 21:01:15 CST 2020] Let's check each DNS record now. Sleep 20 seconds first.
[Tue Aug 25 21:01:37 CST 2020] Checking www.zuiyoujie.com for _acme-challenge.www.zuiyoujie.com
[Tue Aug 25 21:01:39 CST 2020] Domain www.zuiyoujie.com '_acme-challenge.www.zuiyoujie.com' success.
[Tue Aug 25 21:01:39 CST 2020] All success, let's return
[Tue Aug 25 21:01:39 CST 2020] Verifying: www.zuiyoujie.com
[Tue Aug 25 21:01:46 CST 2020] Success
[Tue Aug 25 21:01:46 CST 2020] Removing DNS records.
[Tue Aug 25 21:01:46 CST 2020] Removing txt: TX4Rh-fS04vBqvfn3LwhtkbqOCTRaAb7OIaXIfgC_xU for domain: _acme-challenge.www.zuiyoujie.com
[Tue Aug 25 21:01:51 CST 2020] Removed: Success
[Tue Aug 25 21:01:51 CST 2020] Verify finished, start to sign.
[Tue Aug 25 21:01:51 CST 2020] Lets finalize the order.
[Tue Aug 25 21:01:51 CST 2020] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/94832153/4856970603'
[Tue Aug 25 21:01:54 CST 2020] Downloading cert.
[Tue Aug 25 21:01:54 CST 2020] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/037e802113f60dd7f59c52ec4d303b680e5e'
[Tue Aug 25 21:01:56 CST 2020] Cert success.
-----BEGIN CERTIFICATE-----
MIIFWjCCBEKgAwIBAgISA36AIRP2Ddf1nFLsTTA7aA5eMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
Ohpp06IcAAABdCW176gAAAQDAEYwRAIgJ1g0FuPEfiqdHF8MlnwWYP/CeQXq9bIy
8+DpsvczlWgCIGbReYrEhU5dyLReyfCdPe0Ik9KR2MvLCTP8j5w871IOMA0GCSqG
SIb3DQEBCwUAA4IBAQAnv5n1PTakyAlzbkKLY7AmTjcbmOHSN++q2c9Ph6ycIsz1
LWphNznuYk4Onhi3WhusaKSGckQsvLp/u1l3r/HefQqEe8yL7ZdnYcCF5cAgGZDK
dtWPMqRm4oNRxQJGvJcsLgdHmoukaplkgvTnYA9BhgVd0zpeFTz1ZpY1ulGS8+Nk
ZnFzz3SBXPNnF5gJUyxDivQB5SdgGLBbIcqYrPmekHSgs0xBBQ3ts1vK98oahVYG
pWo815t1FkY9kkxzFDu8ed8vMSl+inRi4rNh7+r1+3ODPLcweLtWBeAHFlygo8Hr
88UeigRbLvfJVvlpX33u0gHVnCsb2qMa1VZ2upJj
-----END CERTIFICATE-----
[Tue Aug 25 21:01:56 CST 2020] Your cert is in  /root/.acme.sh/www.zuiyoujie.com/www.zuiyoujie.com.cer 
[Tue Aug 25 21:01:56 CST 2020] Your cert key is in  /root/.acme.sh/www.zuiyoujie.com/www.zuiyoujie.com.key 
[Tue Aug 25 21:01:56 CST 2020] The intermediate CA cert is in  /root/.acme.sh/www.zuiyoujie.com/ca.cer 
[Tue Aug 25 21:01:56 CST 2020] And the full chain certs is there:  /root/.acme.sh/www.zuiyoujie.com/fullchain.cer 
root@zuiyoujie:~/.acme.sh# 
-----------------------------------------------

# 重新签注证书
-----------------------------------------------
root@zuiyoujie:~/.acme.sh# acme.sh --renew --dns dns_ali -d www.zuiyoujie.com       
[Tue Aug 25 21:05:50 CST 2020] Renew: 'www.zuiyoujie.com'
[Tue Aug 25 21:05:50 CST 2020] Skip, Next renewal time is: Sat Oct 24 13:01:56 UTC 2020
[Tue Aug 25 21:05:50 CST 2020] Add '--force' to force to renew.
-----------------------------------------------

# 强制重新签注证书
-----------------------------------------------
root@zuiyoujie:~/.acme.sh# acme.sh --renew --dns dns_ali -d www.zuiyoujie.com --force
[Tue Aug 25 21:06:54 CST 2020] Renew: 'www.zuiyoujie.com'
[Tue Aug 25 21:06:56 CST 2020] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Tue Aug 25 21:06:56 CST 2020] Single domain='www.zuiyoujie.com'
[Tue Aug 25 21:06:56 CST 2020] Getting domain auth token for each domain
[Tue Aug 25 21:07:03 CST 2020] Getting webroot for domain='www.zuiyoujie.com'
[Tue Aug 25 21:07:03 CST 2020] www.zuiyoujie.com is already verified, skip dns-01.
[Tue Aug 25 21:07:03 CST 2020] Verify finished, start to sign.
[Tue Aug 25 21:07:03 CST 2020] Lets finalize the order.
[Tue Aug 25 21:07:03 CST 2020] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/94832153/4857032854'
[Tue Aug 25 21:07:54 CST 2020] Downloading cert.
[Tue Aug 25 21:07:54 CST 2020] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/0391b18a4ab17af2f18fa21da8d2b6234b89'
[Tue Aug 25 21:07:55 CST 2020] Cert success.
-----BEGIN CERTIFICATE-----
MIIFWzCCBEOgAwIBAgISA5GxikqxevLxj6IdqNK2I0uJMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0yMDA4MjUxMjA3NTNaFw0y
CJo32RMAAAF0JbtrQQAABAMASDBGAiEA9qhlOq74XZ9Hjm3oaV87zR/vMaeij3n4
GBYRD2m7AZICIQCaC7v3ObY9WCvizZiig8H2byHHNHu7sN+neaRRGTcl/zANBgkq
hkiG9w0BAQsFAAOCAQEAZIgx3plCibm9WIPu9LIDfFzsvntLqbUA5Q9GUv/orxiW
93KMlJpek/buMDiQurjdvchTUD7jytmVepFKTrxnpmeDDd4/YBaO59URaCF+gSYn
rNhvXpgsct7D8Is0GzAp2UDjI2N/f6s64wMuTwAVh+/+YXe8LSarr9SdesX6KJd5
JRA7JtmGIGDM/6f/b7p/JgXTNLuxySGa1Lk/dwoldfrK1Ye3grt/iper3Apq+OL3
Hw6N1pRwlUsEULNJUPK98UMMJd4is0p2stbKpSX9W/2QUFER789BVJfW379a2eE1
nMz41Epzk3ymxGiVFkYrh6owhQIqx4xTpwL2/YErMQ==
-----END CERTIFICATE-----
[Tue Aug 25 21:07:55 CST 2020] Your cert is in  /root/.acme.sh/www.zuiyoujie.com/www.zuiyoujie.com.cer 
[Tue Aug 25 21:07:55 CST 2020] Your cert key is in  /root/.acme.sh/www.zuiyoujie.com/www.zuiyoujie.com.key 
[Tue Aug 25 21:07:55 CST 2020] The intermediate CA cert is in  /root/.acme.sh/www.zuiyoujie.com/ca.cer 
[Tue Aug 25 21:07:55 CST 2020] And the full chain certs is there:  /root/.acme.sh/www.zuiyoujie.com/fullchain.cer 
-----------------------------------------------

# 查看已经申请的证书
-----------------------------------------------
root@zuiyoujie:~/.acme.sh# acme.sh --list
Main_Domain        KeyLength  SAN_Domains      CA               Created                       Renew
www.zuiyoujie.com  ""         no               LetsEncrypt.org  Tue Aug 25 13:07:55 UTC 2020  Sat Oct 24 13:07:55 UTC 2020
zuiyoujie.com      ""         *.zuiyoujie.com  LetsEncrypt.org  Tue Aug 25 11:34:27 UTC 2020  Sat Oct 24 11:34:27 UTC 2020
-----------------------------------------------

3.安装证书(copy)

  • 前面证书生成以后,接下来需要把证书 copy 到真正需要用它的地方.
  • 注意:
默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件
这里面的文件都是内部使用,而且目录结构可能会变化
例如:不要直接让 nginx/apache 的配置文件使用这下面的文件
正确的使用方法是使用 --install-cert 命令,并指定目标位置,然后证书文件会被 copy 到相应的位置
  • 实例演示:
# apache2 示例:普通单域名
acme.sh --install-cert -d www.zuiyoujie.com \
--cert-file      /data/wwwroot/www.zuiyoujie.com/ssl/www.zuiyoujie.com.crt  \
--key-file       /data/wwwroot/www.zuiyoujie.com/ssl/www.zuiyoujie.com.key  \
--fullchain-file /data/wwwroot/www.zuiyoujie.com/ssl/fullchain.pem \
--reloadcmd     "service apache2 force-reload"

# nginx 示例:通配符域名
acme.sh --install-cert -d zuiyoujie.com \
--fullchain-file  /usr/local/openresty/nginx/conf/ssl/all.zuiyoujie.com.crt  \
--key-file       /usr/local/openresty/nginx/conf/ssl/all.zuiyoujie.com.key  \
--reloadcmd     "nginx -s reload"
  • 注意:
1.以上命令不会生成证书,而是在证书目录查找指定域名的目录进行证书复制,所以需要预先创建好需要的证书
2.这里的 -d 参数需要指定域名,但是如果是多个域名的证书,需要指定申请域名证书的第一个的域名,也就是指定域名证书文件夹的名称
3.这里是手动部署,部署时指定的的配置信息会添加到域名文件夹内的配置文件中,后续可以实现自动更新 + 自动部署

4.更新域名证书

  • 配置定时任务,每日 0 点过后执行,在自动安装脚本时已经配好了,可以检查下
  • 执行命令会检查现有的证书有效期,到期前一个月会自动进行签注,90天
crontab -e
-----------------------------
27 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
-----------------------------
  • 实例演示:
---------------------------------
root@zuiyoujie:~/.acme.sh# "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh"
[Tue Aug 25 19:38:43 CST 2020] ===Starting cron===
[Tue Aug 25 19:38:43 CST 2020] Already uptodate!
[Tue Aug 25 19:38:43 CST 2020] Upgrade success!
[Tue Aug 25 19:38:43 CST 2020] Auto upgraded to: 2.8.7
[Tue Aug 25 19:38:43 CST 2020] Renew: '39sky.com'
[Tue Aug 25 19:38:43 CST 2020] Skip, Next renewal time is: Sat Oct 24 11:25:42 UTC 2020
[Tue Aug 25 19:38:43 CST 2020] Add '--force' to force to renew.
[Tue Aug 25 19:38:43 CST 2020] Skipped 39sky.com
[Tue Aug 25 19:38:43 CST 2020] Renew: 'zuiyoujie.com'
[Tue Aug 25 19:38:43 CST 2020] Skip, Next renewal time is: Sat Oct 24 11:34:27 UTC 2020
[Tue Aug 25 19:38:43 CST 2020] Add '--force' to force to renew.
[Tue Aug 25 19:38:43 CST 2020] Skipped zuiyoujie.com
[Tue Aug 25 19:38:43 CST 2020] ===End cron===
------------------------------------

5.更新 acme.sh 脚本

# 手动更新
acme.sh --upgrade

# 配置自动更新
acme.sh  --upgrade  --auto-upgrade

# 关闭自动更新
acme.sh --upgrade  --auto-upgrade  0

6.故障处理

如果出错,请添加 debug log:
acme.sh  --issue  .....  --debug 

或者:
acme.sh  --issue  .....  --debug  2
  • 更多参考: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh

10.参考地址:

# 官方仓库
https://github.com/acmesh-official/acme.sh

# 官方文档-中文
https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E

# 其他地址
https://www.ioiox.com/archives/87.html
https://developer.aliyun.com/article/758133