前言

最近做数据迁移,准备把一些自建服务都迁移到群晖上,但群晖自带的Let's Encrypt证书申请总是提示:命令运行失败,请重新登陆DSM再试一次

1.png

按提示多次尝试未果,没办法,那就自己动手吧。

说明

- 此脚本主要针对群晖系统进行 Let's Encrypt 证书申请,若需要在非群晖系统上使用此脚本,需要 DSM_CERT_PATHDSM_CERT_INFO 两个初始环境变量,或者更改 CopyFile() 方法,以及 ReloadNginx() 方法。

- 此脚本基于 acmesh-official/acme.sh - v3.0.0 ,故此,在未来若新版本中的调用方法与此脚本中所调用方法不一致导致申请失效,需要适当调整此脚本调用中调用代码部分以作适配。

- 同时,acmesh-official/acme.sh 针对不同 ISP服务商 提供的 DNS变更 的API调用实现证书申请,即表示随着 ISP服务商 的API变更,也会导致申请失败,此时需要对 acme.sh 程序进行升级,升级指令为: acme.sh --upgrade

解决的问题

如果你也因为和我遇到相同的问题导致 Let's Encrypt 证书申请失败,听一句劝!别踩坑!

Download it! Run it!

Download it! Run it!

Download it! Run it!

- 1、群晖自带的 Let's Encrypt 申请失败问题

- 2、使用 acme.sh 申请过程中 idn 指令不存在的问题

解决问题的方法

- 1、群晖自带的 Let's Encrypt 申请失败问题

略,详见问题2的解决办法
- 2、使用 acme.sh 申请过程中 idn 指令不存在的问题

本仓库已包含编译完成的 idn 可执行文件并修改 idn 相关环境变量以保证 idn 正常运行,若运行非x86平台,请自行下载 idn 源码编译,下方提供几点关键信息以供参考:
- libidn 官方下载地址:GNU - IDN

- 本项目所使用的版本:libidn-1.19 (GNU社区推荐使用libidn2以支持IDNA 2008TR46,需要的同学请对应下载)
- 本项目所编译的平台:Ubuntu 21.04 x64

- 编译完成后需要修改:(在libidn-1.19中为第35行relink_command处)

主要修改环境变量 PATH 以及 LD_LIBRARY_PATH

以下为我的修改内容,供使用其他版本时参考


# 此处仅演示 libidn-1.19 版本中我所做的修改内容
W21_LIBIDN_ROOT_PATH=$(cd "$(dirname "$0")/..";pwd)
W21_LIBIDN_ROOT_SRC_PATH=$(cd "$(dirname "$0")";pwd)
relink_command="(cd $W21_LIBIDN_ROOT_SRC_PATH; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"$PATH\"; export PATH; gcc -g -O2 -o \$progdir/\$file idn.o idn_cmd.o  ../lib/.libs/libidn.so ../gl/.libs/libgnu.a  -Wl,--rpath -Wl,$W21_LIBIDN_ROOT_PATH/lib/.libs ) "

可能存在的其它问题

- nss验证失败

该问题在Ubuntu测试运行时出现,CentOS运行过程中未发现此问题

目前暂未发现该依赖在群晖中的影响,此问题主要在curl过程中会导致域名验证失败

Ubuntu 的解决办法: sudo apt-get install libnss-tls

技术关键点

如果希望深入了解本脚本实现,了解以下几个关键信息或许能有所帮助:
- 1、群晖系统的证书存储

- 证书配置路径:/usr/syno/etc/certificate/_archive

- 证书存放关系: /usr/syno/etc/certificate/_archive/INFO

- 2、群晖中nginx的重新加载方式


/usr/syno/etc/rc.sysv/nginx.sh reload

- 3、acme.sh程序申请证书过程中所需的依赖项

- libidn

- 4、其它

- 使用脚本解析/封装 JSON,jq 的使用

使用方法

1、准备工作

- 阿里云或其它域名服务商的API调用Key

此过程不作详细阐述,登陆阿里云后台,在右侧头像位置悬停

选择AccessKey管理新建子账户并保存好AccessKey ID以及AccessKey Secret

之后,给刚创建的账户添加AliyunDNSFullAccess授权

2、下载

- Gitee 仓库: https://gitee.com/w0x0021/w21dsm_acme.sh/repository/archive/v1.0?format=zip
- Github 仓库: https://github.com/w0x0021/w21dsm_acme.sh/archive/refs/tags/v1.0.zip

3、上传文件到DSM并解压缩

我演示所用的文件目录为:/volume1/Tools/Tools/Encrypt/test/

- 1、更改config配置参数

打开config文件按照注释内容进行修改即可

其它域名服务的API用法参考:acme.sh/wiki/dnsapi
2.png

- 2、复制脚本程序绝对路径

之后进入目录右键w21_acme.sh文件查看属性,复制出脚本程序的绝对路径得到:/volume1/Tools/Tools/Encrypt/test/w21dsm_acme.sh/w21_acme.sh

3.png

4、添加任务计划

如果希望全过程无需登录SSH,在添加任务计划时,时间选择比当前时间后一分钟,可以在添加完任务一分钟后立即执行,等待执行完毕之后,即可调整时间为每月一日自动执行,或者不作修改,等下一个周期自动执行,关键点如图中步骤:

- 1、所属用户必须选择:root,同时勾选“已启动”

4.png
- 2、设置当前时间的后一分钟执行

5.png
- 3、运行指令,粘帖之前复制得到的脚本程序绝对路径,并添加日志输出

- 我的运行命令:


/volume1/Tools/Tools/Encrypt/test/w21dsm_acme.sh/w21_acme.sh >> /volume1/Tools/Tools/Encrypt/test/w21dsm_acme.sh/run.log &

6.png

5、查看运行日志以及证书设置

- 1、查看运行日志

等待时间触发任务计划,查看日志 /volume1/Tools/Tools/Encrypt/test/w21dsm_acme.sh/run.log (即:上传的脚本根目录下的run.log) 最后出现如下内容表示运行完成


[+] Copy certificate.
    [*] Copying: example1.domain.com
    [*] Set DSM certificate information.
    [*] Copying: example2.domain.com
    [*] Set DSM certificate information.
[-] Copy certificate finish.
alias-register stop/waiting

或者可以直接登录到SSH,可以使用sudo -s切换到root账户运行此脚本
- 2、控制面板查看/设置证书列表

7.png
最后到控制面板查看证书即可