盘就完了 发表于 2024-6-28 08:28:14

windows在cygwin64下使用acme.sh批量签发Let's Encrypt的ssl证书,并用

使用前提

本脚本是在使用阿里云Windows服务器的前提,如果使用其他dns服务,请参看acme.sh的dns相关文档

配置好cygwin64、acme.sh并配置好阿里云账户,openssl最好也安装上

cygwin64配置

如果windows server 08R2启动安装程序失败,请使用cmd运行
setup-x86_64.exe --allow-unsupported-windows --site http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215 --no-verify其他老旧系统请参考cygwin64官网网页的How can I install the last Cygwin version for an old, unsupported Windows回答
acme.sh配置

openssl参考,添加-certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES -nomac 是为了应对pfx输入密钥不正确

最终路径就是项目路径

以下是batch脚本,请保存在autoacme.bat文件中
@echo off & setlocal EnableDelayedExpansion

:: 数组长度,不用管,会自己加值
set objLength=0
:: 公共证书备份路径
set commonPath=E:\cert
:: cygwin64用户路径
set cygwinPath=E:\Cygwin64\home\Administrator
:: cygwin64内部用户路径
set cygwinUserPath=/home/Administrator
:: pfx文件密钥,这里的密钥必须和powershell里的pfx密钥一致
set pfxPassword=dgfdgsdfg

:: 如果公共路径不存在,那么创建,如果路径已存在,不影响命令继续执行
md %commonPath%

:: 证书在以下列表中添加即可
:: 指定域名
set obj[%objLength%]*domain=www.test.com
:: 最终路径
set obj[%objLength%]*path=D:\Web\Main

set /a objLength+=1
:: 指定域名
set obj[%objLength%]*domain=buy.test.com
:: 最终路径
set obj[%objLength%]*path=D:\Web\buy

set /a objLength+=1
:: 指定域名
set obj[%objLength%]*domain=go.test.com
:: 最终路径
set obj[%objLength%]*path=D:\Web\Go

:: 初始索引
set objIndex=0
:: 重试次数
set retryCnt=0
::循环
:loopStart
::判断索引值是否大于数组长度,大于的话跳到结束,不大于的话继续循环
if %objIndex% gtr %objLength% goto end

::初始化当前变量
set curr.domain=0
set curr.path=0
::重置重试次数
set /a retryCnt=0

:: delims==*表示使用=和*分割字符串,tokens=1-3是取切割后字符串的前1到3个,循环对象的每个属性,%%i 是如 obj 标识是第几个对象, %%j 标识是对象的那个属性,%%k 是指定对象属性的值
for /f "usebackq delims==* tokens=1-3" %%i in (`set obj[%objIndex%]`) do (
    :: 赋值变量
    set curr.%%j=%%k
)

echo domain=%curr.domain%
echo path=%curr.path%

:: 登录到cygwin使用acme.sh签发证书,并将文件拷贝到公共证书目录,并转成pfx格式,密码统一使用%pfxPassword%
echo 签发%curr.domain%证书
:: 设置执行命令后缀,这里是acme.sh相关命令,修改dns api就在这里
set issueCmd=--issue --dns dns_ali -d %curr.domain% --fullchain-file %cygwinUserPath%/.acme.sh/%curr.domain%_ecc/%curr.domain%.pem --key-file %cygwinUserPath%/.acme.sh/%curr.domain%_ecc/%curr.domain%.key
bash --login -i -c "acme.sh %issueCmd%"

echo 检查%curr.domain%key文件大小和backup目录是否存在文件
set byte=0
for %%A in ("%cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.key") do (
        set /a byte=%%~zA
)

echo %curr.domain%.key大小:%byte%字节
:: 如果key文件大小为零
if %byte% equ 0 (
    if EXIST %cygwinPath%\.acme.sh\%curr.domain%_ecc\backup\key.bak (
      echo 检查key.bak的大小
      for %%A in ("%cygwinPath%\.acme.sh\%curr.domain%_ecc\backup\key.bak") do (
            set /a byte=%%~zA
      )
      :: bak文件不为零,那么拷贝覆盖
      echo /backup/key.bak大小:%byte%字节
      if %byte% equ 0 (
            echo 拷贝key.bak到根目录
            copy %cygwinPath%\.acme.sh\%curr.domain%_ecc\backup\key.bak %cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.key /y
      ) else (
            :: 如果全部失败,那么直接重新申请
            :forceIssue
            echo 尝试重新申请%curr.domain%证书第%retryCnt%次
            bash --login -i -c "acme.sh %issueCmd% --force"
            :: 重试一次,加一次次数
            set /a retryCnt+=1
      )
    )
)

echo 拷贝key文件到公共目录
copy %cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.key %commonPath%\%curr.domain%.key /y

echo 赋予权限
bash --login -i -c "chmod -R g+rw %cygwinUserPath%/.acme.sh/%curr.domain%_ecc"

echo 第一次检查%curr.domain%.pfx文件是否存在
IF NOT EXIST %cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.pfx (
    echo openssl转换pfx,因为acme.sh转换失败
    openssl pkcs12 -export -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES -nomac -out %cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.pfx -inkey %cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.key -in %cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.cer -password pass:"%pfxPassword%"
)

echo 第二次检查%curr.domain%.pfx文件是否存在
IF NOT EXIST %cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.pfx (
    IF %retryCnt% gtr 3 goto skipCurr
    else goto forceIssue
)

echo 拷贝pfx文件到公共目录
copy %cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.pfx %commonPath%\%curr.domain%.pfx /y

:: 如果pem格式文件不存在,那么使用openssl转换成pem格式
IF NOT EXIST %cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.pem (
    echo openssl转换pem
    openssl pkcs12 -in %cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.pfx -out %cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.pem -nodes -password pass:"%pfxPassword%"
)

:: 拷贝pem文件到公共目录
echo 拷贝pem到公共目录
copy %cygwinPath%\.acme.sh\%curr.domain%_ecc\%curr.domain%.pem %commonPath%\%curr.domain%.pem /y

:: 拷贝证书到最终路径,如果路径相等会直接拷贝失败,如果最终路径不存在,也会拷贝失败
echo 拷贝%curr.domain%证书到项目目录
copy %commonPath%\%curr.domain%.pem %curr.path%\%curr.domain%.pem /y & copy %commonPath%\%curr.domain%.key %curr.path%\%curr.domain%.key /y & copy %commonPath%\%curr.domain%.pfx %curr.path%\%curr.domain%.pfx /y


:skipCurr
:: 索引+1
set /a objIndex=%objIndex% + 1
:: 继续循环
goto loopStart

:end
:: 暂停看结果
:: pause
:: 执行完后退出
exitPowerShell 脚本,使用前,更改执行策略

关于执行策略:
https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.4#powershell-execution-policies
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser将以下脚本保存为reissueIISCert.ps1文件
# 使用前先将策略设置为不严格 Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
# 保证证书有效的情况下再运行次脚本,将证书名称、证书目录、密钥放入以下数组
# 公共证书密钥
$pfxpassword = "dgfdgsdfg"
# 公共证书路径
$pfxCommandDir= "E:\cert"
# 域名
$domain="test.com"
# 服务器上的证书与端口映射关系
$data = @(
    @{subDomain = 'www';port=443}
    @{subDomain = 'buy';port=8443}
    @{subDomain = 'go';port=7443}
)
$certRootStore = "localmachine"
$certStore = "My"
# 创建证书存储
$store = new-object System.Security.Cryptography.X509Certificates.X509Store($certStore, $certRootStore)
$store.open("MaxAllowed")

# 开始循环数组操作
foreach ($element in $data) {
    $pfxPath = "$($pfxCommandDir)\$($element.subDomain).$($domain).pfx"
    Write-Host $pfxPath
    # 创建pfx对象
    try {
      $certificateObject = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($pfxPath, $pfxpassword)
      # 存储证书到个人
      $store.Add($certificateObject)
      Write-Host 导入证书成功
      $newThumbprint = $certificateObject.Thumbprint
      Write-Host 获取证书信息成功
      $guid = New-Guid
      $applicationID = "{$($guid)}"
      $addr = "0.0.0.0:$($element.port)"
      Write-Host $addr $newThumbprint
      netsh http delete sslcert ipport=$addr
      netsh http add sslcert ipport=$addr certhash=$newThumbprint appid=$applicationID
    }
    catch {
      Write-Host "发生异常:$_"
      break
    }
}
# 关闭证书存储
$store.close()

# 执行完后退出
exit创建任务计划程序参考

将启动程序设置为autoacme.bat即可,设置完成后,右键对应任务计划程序->属性->操作,在这一对话框中,将reissueIISCert.ps1加入到队列中。在常规页面中,勾选“不管用户是否登录都要运行”以及“使用最高权限”,保存即可
任务计划程序是按照顺序执行的。

来源:https://www.cnblogs.com/NickSmith/p/18270573
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: windows在cygwin64下使用acme.sh批量签发Let's Encrypt的ssl证书,并用