一、为什么需要监控FTPS证书有效期

想象一下这个场景:凌晨三点,公司核心文件传输服务突然中断,业务部门疯狂打电话。排查半天发现是FTPS证书过期了——这种"惊喜"谁都不想要。证书就像食品保质期,过期就会"变质",而手动检查就像每天翻冰箱看牛奶保质期,既低效又容易遗漏。

我曾见过一个金融公司因为证书过期导致跨境支付延迟,每小时损失超百万。更可怕的是,某些老系统在证书过期后会产生不可预知的行为,比如某ERP系统会持续写错误日志直到磁盘爆满。自动化监控就是给证书装上"智能冰箱",快过期时主动提醒你。

二、基于PowerShell的监控方案设计

技术栈选择PowerShell,因为:

  1. 原生支持证书操作
  2. 可直连Exchange发送告警邮件
  3. 所有Windows服务器预装

核心思路分三步走:

  1. 从指定路径读取证书
  2. 计算剩余有效期
  3. 触发阈值发告警
# 证书检查核心函数
function Check-CertExpiry {
    param (
        [string]$CertPath,  # 证书路径
        [int]$AlertDays = 30  # 默认提前30天告警
    )
    
    # 获取证书对象
    $cert = Get-PfxCertificate -FilePath $CertPath
    
    # 计算剩余天数
    $expiryDate = $cert.NotAfter
    $daysLeft = ($expiryDate - (Get-Date)).Days
    
    # 判断是否需要告警
    if ($daysLeft -le $AlertDays) {
        $subject = "[紧急] FTPS证书将在${daysLeft}天后过期!"
        $body = @"
证书详情:
路径: $CertPath
过期时间: $($expiryDate.ToString('yyyy-MM-dd'))
指纹: $($cert.Thumbprint)
"@
        # 调用邮件发送函数
        Send-AlertEmail -Subject $subject -Body $body
    }
}

# 邮件发送函数示例
function Send-AlertEmail {
    param (
        [string]$Subject,
        [string]$Body
    )
    # 实际使用时替换为真实SMTP配置
    $smtpServer = "smtp.company.com"
    Send-MailMessage -From "noreply@company.com" -To "admin@company.com" `
                     -Subject $Subject -Body $Body -SmtpServer $smtpServer
}

三、进阶功能实现

基础版只能监控单个证书,实际生产环境需要这些增强功能:

3.1 批量扫描证书目录

# 扫描整个目录下的PFX文件
$certFolder = "D:\FTPS_Certs"
Get-ChildItem -Path $certFolder -Filter *.pfx | ForEach-Object {
    Check-CertExpiry -CertPath $_.FullName
}

3.2 证书链验证

# 验证证书链完整性
function Test-CertChain {
    param ([string]$CertPath)
    $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
    $cert.Import($CertPath)
    
    # 创建证书链引擎
    $chain = New-Object Security.Cryptography.X509Certificates.X509Chain
    $chain.ChainPolicy.RevocationMode = "Online"
    
    if (-not $chain.Build($cert)) {
        Write-Warning "证书链验证失败: $CertPath"
        $chain.ChainStatus | ForEach-Object {
            Write-Output "错误类型: $($_.Status) 描述: $($_.StatusInformation)"
        }
    }
}

3.3 与运维系统集成

# 调用企业微信机器人API示例
function Send-WeChatAlert {
    param (
        [string]$Content
    )
    $webhookUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY"
    $payload = @{
        msgtype = "text"
        text = @{
            content = $Content
        }
    } | ConvertTo-Json
    
    Invoke-RestMethod -Uri $webhookUrl -Method Post `
                      -Body $payload -ContentType "application/json"
}

四、生产环境注意事项

  1. 权限控制:运行脚本的账户需要:

    • 对证书目录有读取权限
    • 注册表权限:HKLM:\SOFTWARE\Microsoft\SystemCertificates
  2. 证书密码管理:建议使用:

    # 从加密文件读取密码
    $password = Get-Content "D:\secure\cert_password.txt" | ConvertTo-SecureString
    
  3. 日志记录:必须记录操作日志:

    Start-Transcript -Path "C:\Logs\CertMonitor_$(Get-Date -Format 'yyyyMMdd').log"
    
  4. 性能优化:当证书超过100个时:

    • 采用多线程处理:Start-Job
    • 缓存上次检查结果
  5. 监控脚本自身:最讽刺的是监控脚本挂了没人知道,所以需要:

    # 心跳检测脚本
    if (-not (Test-Path "C:\temp\certmonitor.heartbeat")) {
        Send-WeChatAlert "证书监控脚本可能已停止运行!"
    }
    

五、方案优缺点分析

优势

  • 零成本:利用现有PowerShell环境
  • 高扩展:可对接各种告警渠道
  • 可视化:可导出HTML报告

局限

  • Windows限定:Linux需改用OpenSSL
  • 无界面:对非技术人员不友好
  • 需定期维护:证书路径变更需更新脚本

六、完整方案示例

结合所有功能的完整脚本框架:

<#
.SYNOPSIS
    FTPS证书监控全功能脚本
.VERSION
    1.2.0
#>
param (
    [string]$ConfigFile = "config.json"
)

# 加载配置
$config = Get-Content $ConfigFile | ConvertFrom-Json

# 初始化日志
Start-Transcript -Path $config.LogPath

try {
    # 批量检查证书
    $config.CertFolders | ForEach-Object {
        Get-ChildItem $_ -Recurse -Filter *.pfx | ForEach-Object {
            Check-CertExpiry -CertPath $_.FullName -AlertDays $config.AlertDays
            Test-CertChain -CertPath $_.FullName
        }
    }
    
    # 更新心跳文件
    Set-Content -Path $config.HeartbeatFile -Value (Get-Date)
}
catch {
    $errorMsg = $_.Exception.Message
    Send-WeChatAlert "证书监控脚本异常:$errorMsg"
    Write-Error $errorMsg
}
finally {
    Stop-Transcript
}

配套的config.json示例:

{
    "CertFolders": [
        "D:\\Certs\\FTPS",
        "E:\\Secure\\Certificates"
    ],
    "AlertDays": 30,
    "LogPath": "C:\\Logs\\CertMonitor.log",
    "HeartbeatFile": "C:\\temp\\certmonitor.heartbeat"
}

七、总结

这个方案就像给证书装上了智能闹钟。实际部署时建议:

  1. 先在测试环境验证
  2. 设置多级告警(15天/7天/1天)
  3. 定期检查脚本运行状态

对于大型企业,可以考虑升级到专业证书管理系统。但对于大多数场景,这个脚本方案已经能解决90%的问题。记住:自动化监控不是为了增加工作量,而是为了让你们能睡个安稳觉。