You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure APIM自定义域名SSL证书过期检测脚本返回空白求助

解决Azure APIM自定义域名证书过期检测脚本返回空白的问题

问题根源分析

  1. JMESPath查询的字符串匹配问题:原脚本中hostnameConfigurations[?hostName=='$DOMAIN']的单引号嵌套会导致Bash解析错误,无法正确匹配域名。
  2. 托管证书的字段缺失:如果APIM自定义域名使用的是Azure自动托管的证书(而非手动上传的证书),certificate字段不会出现在返回结果中,此时需要通过defaultSslBinding字段获取过期时间。
  3. 循环变量的安全处理:原脚本用for DOMAIN in $customDomains处理域名,若域名包含特殊字符(虽少见)会导致拆分错误,改用while read更可靠。

修正后的完整脚本

parameters:
  - name: apimName
    type: string
    default: 'myapim'
  - name: resourceGroup
    type: string
    default: 'myapim-rg'
  - name: thresholdDays
    type: string
    default: 60

jobs:
  - job: CheckAPIMSSL
    displayName: 'Check SSL Certificate Expiry for APIM Custom Domains'
    steps:
      - task: AzureCLI@2
        displayName: 'Check SSL Certificate Expiry'
        inputs:
          azureSubscription: 'mysubscription'
          scriptType: bash
          scriptLocation: inlineScript
          inlineScript: |
            APIM_NAME='${{ parameters.apimName }}'
            RESOURCE_GROUP='${{ parameters.resourceGroup }}'
            THRESHOLD_DAYS=${{ parameters.thresholdDays }}
            EXPIRED=0
            
            echo "Fetching custom domain details for APIM: $APIM_NAME"
            # 用JSON+jq获取域名列表,避免TSV格式拆分问题
            az apim show --name "$APIM_NAME" --resource-group "$RESOURCE_GROUP" --query "hostnameConfigurations" -o json | jq -r '.[] | .hostName' | while read DOMAIN
            do
              echo "Checking SSL certificate for custom domain: $DOMAIN"
              # 修复JMESPath查询,兼容自定义证书和托管证书场景
              EXPIRY_DATE=$(az apim show --name "$APIM_NAME" --resource-group "$RESOURCE_GROUP" \
                --query "hostnameConfigurations[] | [?hostName == '$DOMAIN'] | [0].{expiry: certificate.expirationDate || defaultSslBinding.certificate.expirationDate}" \
                -o tsv)
              
              if [ -z "$EXPIRY_DATE" ]; then
                echo "ERROR: Could not retrieve SSL certificate info for $DOMAIN. This may be a managed certificate or the domain is misconfigured."
                EXPIRED=1
                continue
              fi
              
              # 增加日期解析错误处理
              EXPIRY_TIMESTAMP=$(date -d "$EXPIRY_DATE" +%s 2>/dev/null)
              if [ $? -ne 0 ]; then
                echo "ERROR: Failed to parse expiry date '$EXPIRY_DATE' for $DOMAIN"
                EXPIRED=1
                continue
              fi
              
              CURRENT_TIMESTAMP=$(date +%s)
              DAYS_LEFT=$(( (EXPIRY_TIMESTAMP - CURRENT_TIMESTAMP) / 86400 ))
              
              echo "SSL certificate for $DOMAIN expires in $DAYS_LEFT days."
              
              if [ "$DAYS_LEFT" -lt "$THRESHOLD_DAYS" ]; then
                echo "ALERT: SSL certificate for $DOMAIN is expiring in less than $THRESHOLD_DAYS days!"
                EXPIRED=1
              else
                echo "SSL certificate for $DOMAIN is valid for more than $THRESHOLD_DAYS days."
              fi
            done
            
            if [ "$EXPIRED" -eq 1 ]; then
              echo "One or more certificates are expiring soon or cannot be retrieved."
              exit 1
            else
              echo "All certificates are valid for more than $THRESHOLD_DAYS days."
            fi

关键修改说明

  1. 改用JSON+jq处理域名列表:使用az apim show输出JSON,再用jq提取域名,避免TSV格式在特殊场景下的拆分错误,同时用while read循环确保每个域名被正确处理。
  2. 修复JMESPath查询逻辑:
    • 使用双引号包裹整个查询字符串,避免Bash解析单引号嵌套的问题。
    • 添加|| defaultSslBinding.certificate.expirationDate,兼容Azure托管证书的场景,这类证书的过期时间存储在defaultSslBinding字段下。
  3. 增加日期解析错误处理:捕获date命令解析失败的情况,避免脚本因日期格式问题直接崩溃。
  4. 优化错误提示信息:更明确地指出无法获取证书信息的可能原因,帮助排查问题。

额外注意事项

  • 确保Azure CLI任务的代理环境中安装了jq工具(大多数Azure DevOps托管代理默认已安装)。
  • 验证服务连接(mysubscription)拥有APIM实例的读取权限,否则无法获取证书详情。

内容的提问来源于stack exchange,提问作者Vowneee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 07:54:56