windows在cygwin64下使用acme.sh批量签发Let's Encrypt的ssl证书,并用powershell重新分配iis证书

cnblogs 2024-06-27 11:15:00 阅读 90

使用前提

本脚本是在使用阿里云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[0] 标识是第几个对象, %%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

:: 执行完后退出

exit

PowerShell 脚本,使用前,更改执行策略

关于执行策略:

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 = @(

[pscustomobject]@{subDomain = 'www';port=443}

[pscustomobject]@{subDomain = 'buy';port=8443}

[pscustomobject]@{subDomain = 'go';port=7443}

)

# 开始循环数组操作

foreach ($element in $data) {

$pfxPath="$($pfxCommandDir)\$($element.subDomain).$($domain).pfx"

Write-Host $pfxPath

$securePfxKey = ConvertTo-SecureString -String $pfxpassword -AsPlainText -Force

Import-PfxCertificate -FilePath $pfxPath -CertStoreLocation Cert:\LocalMachine\My -Password $securePfxKey

$pfxData = Get-PfxData -FilePath $pfxPath -Password $securePfxKey

$newThumbprint = $pfxData.EndEntityCertificates.Thumbprint

$guid=New-Guid

$applicationID = "{$($guid)}" # hardcode it once

$addr="0.0.0.0:$($element.port)"

netsh http delete sslcert ipport=$addr

netsh http add sslcert ipport=$addr certhash=$newThumbprint appid=$applicationID

}

# 执行完后退出

exit

创建任务计划程序参考

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

任务计划程序是按照顺序执行的。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。