万有斥力 发表于 2025-3-12 14:09:04

windows在cygwin64下利用acme.sh批量签发的ssl/https证书,并用powershell

利用前提

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

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

cygwin64配置参考

acme.sh配置

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

最终路径就是项目路径

一、安装cygwin64

1. 下载

cygwin64官网下载
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回答
https://img2024.cnblogs.com/blog/938468/202408/938468-20240806143612640-1718740508.png
2. 非老旧体系配置镜像点

如果不是老久体系 ,则可以思量利用阿里云镜像

阿里云镜像点: https://mirrors.aliyun.com
https://img2024.cnblogs.com/blog/938468/202408/938468-20240806143947323-1631663028.png
3. 安装包参考列表

curl
cron
bzip2
wget
gcc-core
gcc-g++
make
openssh
openssl
lynx
dos2unix
vim
4. Windows配置情况变量

在Path后加;C:\cygwin64\bin;C:\cygwin64\usr\local\bin
https://img2024.cnblogs.com/blog/938468/202408/938468-20240814111428076-692852107.png
5. 如果遇到VIM不能粘贴复制

打开cygwin64桌面图标Cygwin64 Terminal,进入控制台
cd /home
vim .vimrc
i键进入编辑模式,键入以下内容
set mouse=c
syntax onesc键退出编辑模式,输入:wq即可生存文件
shift+ins 是cygwin64控制台下的粘贴键

二、安装acme.sh

1. 通过curl命令直接安装acme.sh

curl -k https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | sh -s -- --install-online -mmy@example.com如果报错如图
https://img2024.cnblogs.com/blog/938468/202408/938468-20240806162143897-2115413768.png
输入以下,使curl忽略全局ssl认证,成功后 ,再去通过curl安装acme.sh试试
echo insecure > ~/.curlrc2. 如果步骤二.1成功则不需要看此条

1)直接去git下载acme.sh的源码

acme.sh git资源
acme.sh 百度云
https://img2024.cnblogs.com/blog/938468/202408/938468-20240806153943065-427906236.png
利用解压软件如7z将acme.sh-3.0.7.tar.gz解压两次放在/usr/download目录下,并重命名为acme.sh,如图
https://img2024.cnblogs.com/blog/938468/202408/938468-20240806154759772-385386995.png
2)安装acme.sh

切换到cygwin64控制台
cd /usr/download/acme.sh
./acme.sh --install -m example@qq.com3. 配置acme.sh

0)安装完成后重新加载 Bash

source ~/.bashrc1)配置自动更新

acme.sh --upgrade --auto-upgrade2)切换至Letsencrypt

acme.sh --set-default-ca --server letsencrypt3)配置DNSApi,这里是参考阿里云的dnsapi,其他请参考acme.sh的dns相关文档

cd /home/Administrator/.acme.sh
vim account.conf
i键进入编辑模式,输入阿里云帐号的AccessKey相关内容
export Ali_Key="LTAIsadfd8J9qs4fxxxxxxxxxx"
export Ali_Secret="Xp3adgfNDOW0CJcPLKoUwqxxxxxxxxxx"esc键退出编辑模式,输入 :wq 生存文件并退出
三、准备powershell脚本

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以下是PowerShell脚本,如果乱码,请将文件生存为GB2312字符文件

1.acme自动申请证书脚本,请生存在cygwin64批量自动签发证书.ps1文件中

# 设定bash别名,如果系统装了wsl可能冲突,使用别名强制使用cygwin64命令
Set-Alias -Name bash C:\cygwin64\bin\bash.exe
# 设定openssl别名,如果系统装了wsl可能冲突,使用别名强制使用cygwin64命令
Set-Alias -Name openssl C:\cygwin64\bin\openssl.exe
# 公共证书备份路径,务必带盘符
$commonPath = "E:\cert"
# cygwin64用户路径,务必带盘符,Administrator是计算机安装cygwin64的用户名,不同情况名字不同
$userPath = "C:\Cygwin64\home\Administrator"
# cygwin64内部用户路径
$cygwinUserPath = "/home/Administrator"
# pfx文件密钥
$pfxPassword = "dgfdgsdfg"

# 证书在以下列表中添加即可
$data = @(
    @{
      # 要申请的域名
      domain = "buy.test.com";
      # 项目路径,可空
      path   = "D:\Web\Main"
    },
    @{
      domain = "go.test.com";
    },
    @{
      domain = "*.test.com";
    }
)

# 如果公共路径不存在,那么创建,如果路径已存在,不影响命令继续执行
if (!::Exists($commonPath)) {
    md $commonPath
}

# 获取公共证书备份路径在cygwin64环境下的路径
$cygwinCommonPath = "/cygdrive/" + $commonPath.Replace(":", "").Replace("\", "/");

# 重试次数
$retryCnt = 0

function IssueKey {
    param (
      $currDomain,
      $currPath,
      $force
    )
    # 如果重试次数大于2,那么退出当前函数
    if ($retryCnt -gt 2) {
      return
    }

    # 替换特殊路径名
    $domain = $currDomain.Replace("*", "_")
    $cygDomain = $currDomain.Replace("*", "\*")

    # 设置执行命令后缀,这里是acme.sh相关命令,修改dns api就在这里
    $issueCmd = "--issue --dns dns_ali -d $($currDomain) --key-file $($cygwinCommonPath)/$($domain).key --fullchain-file $($cygwinCommonPath)/$($domain)_fullchain.cer"
    #如果是强制重发
    if ($force) {
      $issueCmd += " --force"
    }
    Write-Host 被执行的acme.sh后缀命令 $issueCmd
    bash --login -i -c "acme.sh $($issueCmd)"
   
    Write-Host 检查$currDomain key文件大小和backup目录是否存在文件
   
    $commonFullChainPath = "$($commonPath)\$($domain)_fullchain.cer"
    $commonKeyPath = "$($commonPath)\$($domain).key"
    $commonPfxPath = "$($commonPath)\$($domain).pfx"
    $commonPemPath = "$($commonPath)\$($domain).pem"
    # cygwin环境下的目录
    $cygwinCertPath = "$($cygwinUserPath)/.acme.sh/$($cygDomain)_ecc"

    Write-Host 赋予权限
    bash --login -i -c "chmod -R g+rw $($cygwinCertPath)"

    Write-Host 拷贝Key、Fullchain文件到公共目录
    bash --login -i -c "cp -f $($cygwinCertPath)/$($cygDomain).key $($cygwinCommonPath)/$($domain).key"
    bash --login -i -c "cp -f $($cygwinCertPath)/fullchain.cer $($cygwinCommonPath)/$($domain)_fullchain.cer"

    # 判断绝对路径下证书文件是否存在,如果不存在直接强制重新生成证书
    Write-Host 第一次检查$commonKeyPath 文件是否存在
    if (!::Exists($commonKeyPath)) {
      Write-Host 检查key.bak是否存在
      # 尝试从备份中恢复文件到原目录
      bash --login -i -c "cp -f $($cygwinCertPath)/backup/key.bak $($cygwinCertPath)/$($cygDomain).key"
      # 尝试从原目录拷贝文件到公共目录
      bash --login -i -c "cp -f $($cygwinCertPath)/$($cygDomain).key $($cygwinCommonPath)/$($domain).key"
      Write-Host 第二次检查$commonKeyPath 文件是否存在
      if (!::Exists($commonKeyPath)) {
            Write-Host 公共路径证书文件不存在 $commonKeyPath 即将强制重新申请
            # 重试次数+1
            $retryCnt += 1
            IssueKey -currDomain $currDomain -currPath $currPath -force $true
      }
    }

    Write-Host 第一次检查 $($domain).pfx 文件是否存在
    if (!::Exists($commonPfxPath)) {
      Write-Host openssl转换pfx   
      # openssl 3.x 版本
      openssl pkcs12 -export -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES -nomac -out $commonPfxPath -inkey $commonKeyPath -in $commonFullChainPath -password pass:$pfxPassword
      # openssl 1.0 版本
      # openssl pkcs12 -export -out $commonPfxPath -inkey $commonKeyPath -in $commonFullChainPath -password pass:$pfxPassword
    }

    Write-Host 第二次检查 $($domain).pfx 文件是否存在
    if (!::Exists($commonPfxPath)) {
      # 如果重试次数大于2,那么退出当前函数
      if ($retryCnt -gt 2) {
            return
      }
      else {
            # 重试次数+1
            $retryCnt += 1
            IssueKey -currDomain $currDomain -currPath $currPath -force $true
      }
    }

    # 如果pem格式文件不存在,那么使用openssl转换成pem格式
    if (!::Exists($commonPemPath)) {
      Write-Host openssl转换pem
      openssl pkcs12 -in $commonPfxPath -out $commonPemPath -nodes -password pass:$pfxPassword
    }

    # 如果对象path不为空且存在,将证书拷贝到项目路径下
    if (!::IsNullOrEmpty($currPath)) {
      Write-Host 拷贝$domain 证书文件到项目目录
      Copy-Item -Path $commonKeyPath -Destination "$($currPath)\$($domain).key" -Force
      Copy-Item -Path $commonPfxPath -Destination "$($currPath)\$($domain).pfx" -Force
      Copy-Item -Path $commonPemPath -Destination "$($currPath)\$($domain).pem" -Force
    }
}

foreach ($curr in $data) {
    # 每次弄新的,就重置次数
    $retryCnt = 0

    try {
      # 登录到cygwin使用acme.sh签发证书,并将文件拷贝到公共证书目录,并转成pfx格式,密码统一使用$pfxPassword
      Write-Host 地址 $curr.path
      Write-Host 签发 $curr.domain 证书
      IssueKey -currDomain $curr.domain -currPath $curr.path -force $false
    }
    catch {
      Write-Host "发生异常:$_"
      break
    }
}
# 执行完后退出
exit2.iis分配证书脚本,请生存在iis批量重新分配证书.ps1文件中

# 使用前先将策略设置为不严格 Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
# 保证证书有效的情况下再运行次脚本,将证书名称、证书目录、密钥放入以下数组
# 公共证书密钥
$pfxpassword = "dgfdgsdfg"
# 公共证书路径
$pfxCommandDir= "E:\cert"
# 域名
$domain="test.com"
# 服务器上的证书与端口映射关系
$data = @(
    @{subDomain = '*';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) {
    $currDomain=$element.subDomain.Replace("*","_");
    $pfxPath = "$($pfxCommandDir)\$($currDomain).$($domain).pfx"
    Write-Host $pfxPath
    # 创建pfx对象
    try {
      $certificateObject = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($pfxPath, $pfxpassword)
      if (!$certificateObject.Verify()) {
            Write-Host $element.subDomain证书验证失败, 请检查相关配置
            break
      }
      else {
            Write-Host 证书验证成功
      }
      # 存储证书到个人
      if (!$store.Certificates.Contains($certificateObject)) {
            $store.Add($certificateObject)
            Write-Host 导入证书成功
      }
      $newThumbprint = $certificateObject.Thumbprint
      Write-Host 获取证书信息成功
      $guid = ::NewGuid()
      $applicationID = "{$($guid)}"
      $addr = "0.0.0.0:$($element.port)"
      Write-Host $addr $newThumbprint
      # netsh删除原有监听端口
      netsh http delete sslcert ipport=$addr
      # netsh添加端口
      netsh http add sslcert ipport=$addr certhash=$newThumbprint appid=$applicationID
      # 如果对象path不为空且存在,将证书拷贝到项目路径下
      if (!::IsNullOrEmpty($element.path)) {
            $dest = "$($element.path)\$($currDomain).$($domain).pfx"
            Copy-Item -Path $pfxPath -Destination $dest -Force
            Write-Host 拷贝文件到项目目录成功
      }
    }
    catch {
      Write-Host "发生异常:$_"
      break
    }
}
# 关闭证书存储
$store.close()

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

在常规页面中,勾选“只在用户登录时运行”以及“利用最高权限”,生存即可
任务计划步伐是按照顺序执行的。

任务计划步伐设置界面结果最终如图

以Windows Server 2008R2所示:
https://img2024.cnblogs.com/blog/938468/202408/938468-20240806165519037-1355615323.png
https://img2024.cnblogs.com/blog/938468/202408/938468-20240806165732418-2114043586.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: windows在cygwin64下利用acme.sh批量签发的ssl/https证书,并用powershell