AI+运维提效--HTTPS 证书有效期监控方案

概述

本文档提供针对公网域名、内网域名、内网IP的HTTPS URL证书有效期监控方案,支持在证书有效期低于30天时触发告警。涵盖以下三种监控系统:

  1. Prometheus + Blackbox Exporter + Alertmanager
  2. Zabbix
  3. 夜莺监控 (Nightingale)

一、Prometheus 方案

1.1 架构说明

  • Blackbox Exporter: 负责探测HTTPS端点,获取SSL证书信息
  • Prometheus: 采集Blackbox Exporter的指标
  • Alertmanager: 处理告警规则,发送通知

1.2 安装 Blackbox Exporter

复制代码
# 下载 Blackbox Exporter
wget https://github.com/prometheus/blackbox_exporter/releases/download/v0.25.0/blackbox_exporter-0.25.0.linux-amd64.tar.gz
tar xvfz blackbox_exporter-*.tar.gz
cd blackbox_exporter-*

# 创建配置文件 blackbox.yml
cat > blackbox.yml << 'EOF'
modules:
  http_ssl:
    prober: http
    http:
      method: GET
      preferred_ip_protocol: "ip4"
      tls: true
      tls_config:
        insecure_skip_verify: false
EOF

1.3 Prometheus 配置

编辑 prometheus.yml,添加Blackbox Exporter的scrape配置:

复制代码
# prometheus.yml
global:
  scrape_interval: 60s

scrape_configs:
  - job_name: 'blackbox-ssl'
    metrics_path: /probe
    params:
      module: [http_ssl]
    static_configs:
      - targets:
        # 公网域名
        - https://www.google.com
        - https://github.com
        # 内网域名
        - https://internal.example.com
        - https://jenkins.internal.com
        # 内网IP
        - https://192.168.1.100:8443
        - https://10.0.0.50
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: 127.0.0.1:9115  # Blackbox Exporter地址

1.4 SSL 证书有效期告警规则

创建告警规则文件 ssl_cert_alerts.yml

复制代码
# ssl_cert_alerts.yml
groups:
  - name: ssl_cert_alerts
    rules:
      # 证书有效期小于30天告警
      - alert: SSLCertExpirySoon
        expr: |
          probe_ssl_earliest_cert_expiry - time() < 30 * 24 * 3600
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "SSL证书即将过期 (instance {{ $labels.instance }})"
          description: |
            SSL证书将在 {{ printf "%.1f" (div (sub $value (time)) 86400)) }} 天后过期。
            当前时间: {{ $labels.instance }}
            到期时间: {{ $labels.cert_expiry | default "unknown" }}

      # 证书有效期小于7天严重告警
      - alert: SSLCertExpiryCritical
        expr: |
          probe_ssl_earliest_cert_expiry - time() < 7 * 24 * 3600
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "SSL证书即将严重过期 (instance {{ $labels.instance }})"
          description: |
            SSL证书将在 {{ printf "%.1f" (div (sub $value (time)) 86400)) }} 天后过期!
            请立即更新证书!

prometheus.yml 中引用告警规则:

yaml

复制

复制代码
rule_files:
  - "ssl_cert_alerts.yml"

1.5 Alertmanager 告警配置

yaml

复制

复制代码
# alertmanager.yml
global:
  smtp_smarthost: 'smtp.example.com:587'
  smtp_from: 'alert@example.com'

route:
  group_by: ['alertname', 'severity']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 12h
  receiver: 'email-notifications'

receivers:
  - name: 'email-notifications'
    email_configs:
      - to: 'admin@example.com'
        subject: '【告警】{{ .GroupLabels.alertname }}'
        body: |
          {{ range .Alerts }}
          告警: {{ .Annotations.summary }}
          详情: {{ .Annotations.description }}
          时间: {{ .StartsAt }}
          {{ end }}

1.6 验证指标

访问 Blackbox Exporter 进行手动测试:

bash

复制

复制代码
curl "http://localhost:9115/probe?target=https://www.google.com&module=http_ssl"

查看 Prometheus 指标:

复制代码
probe_ssl_earliest_cert_expiry

二、Zabbix 方案

2.1 方案一:使用 Web 场景监控

创建 Web 场景
  1. 进入 Zabbix 前端,选择 Configuration → Hosts
  2. 创建或选择一个主机,点击 Web
  3. 点击 Create web scenario

配置示例:

参数
Name SSL Certificate Check
Application SSL Monitoring
Update interval 1h

添加步骤:

Name URL Timeout
Check SSL https://your-domain.com 30s
创建监控项和触发器

使用 Zabbix 内置的 {SSL.CERT.EXPIRY} 宏或通过自定义脚本:

2.2 方案二:自定义脚本 + Zabbix Agent(推荐)

创建脚本 /etc/zabbix/scripts/check_ssl_cert.sh

bash

复制

复制代码
#!/bin/bash
# check_ssl_cert.sh - 检查SSL证书有效期
# 用法: ./check_ssl_cert.sh <host> <port>

HOST="$1"
PORT="${2:-443}"

if [ -z "$HOST" ]; then
    echo "Usage: $0 <host> [port]"
    exit 1
fi

# 获取证书过期时间
CERT_EXPIRY=$(echo | openssl s_client -servername "$HOST" -connect "$HOST:$PORT" 2>/dev/null | \
    openssl x509 -noout -enddate 2>/dev/null | \
    sed 's/notAfter=//')

if [ -z "$CERT_EXPIRY" ]; then
    echo "Failed to get certificate info"
    exit 1
fi

# 转换为时间戳
EXPIRY_TIMESTAMP=$(date -d "$CERT_EXPIRY" +%s 2>/dev/null || date -j -f "%b %d %T %Z %Y" "$CERT_EXPIRY" +%s 2>/dev/null)
CURRENT_TIMESTAMP=$(date +%s)

if [ -z "$EXPIRY_TIMESTAMP" ]; then
    echo "Failed to parse expiry date"
    exit 1
fi

# 计算剩余天数
DAYS_LEFT=$(( ($EXPIRY_TIMESTAMP - $CURRENT_TIMESTAMP) / 86400 ))

echo "$DAYS_LEFT"

# 退出码:0=正常, 1=警告(<30天), 2=严重(<7天)
if [ "$DAYS_LEFT" -lt 7 ]; then
    exit 2
elif [ "$DAYS_LEFT" -lt 30 ]; then
    exit 1
else
    exit 0
fi

设置权限:

bash

复制

复制代码
chmod +x /etc/zabbix/scripts/check_ssl_cert.sh
配置 Zabbix Agent

编辑 /etc/zabbix/zabbix_agentd.conf 或创建独立的配置文件:

复制代码
# /etc/zabbix/zabbix_agentd.d/ssl_cert.conf
UserParameter=ssl.cert.daysleft[*],/etc/zabbix/scripts/check_ssl_cert.sh "$1" "$2"
UserParameter=ssl.cert.expiry[*],echo | openssl s_client -servername "$1" -connect "$1:$2" 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | sed 's/notAfter=//'

重启 Zabbix Agent:

复制代码
systemctl restart zabbix-agent
在 Zabbix 前端配置监控
  1. 创建监控项 (Items)
名称 键值 类型 更新间隔
SSL证书剩余天数 - google.com ssl.cert.daysleft[www.google.com,443] Zabbix agent 1h
SSL证书剩余天数 - 内网IP ssl.cert.daysleft[192.168.1.100,8443] Zabbix agent 1h
  1. 创建触发器 (Triggers)
名称 表达式 严重性
SSL证书即将过期 (google.com) {Host:ssl.cert.daysleft[www.google.com,443].last()}<30 警告
SSL证书严重过期 (google.com) {Host:ssl.cert.daysleft[www.google.com,443].last()}<7 严重

触发器表达式示例:

复制代码
{SSL Monitor:ssl.cert.daysleft[www.google.com,443].last()}<30
配置告警媒介

进入 Administration → Media types,配置邮件/短信/Webhook等告警方式。

2.3 使用 Zabbix 官方模板

Zabbix 提供了 SSL 证书监控模板,可以直接导入使用:

  1. 下载模板:https://www.zabbix.com/integrations/ssl_certificate
  2. 导入模板:Configuration → Templates → Import
  3. 将模板链接到主机

三、夜莺监控 (Nightingale) 方案

3.1 架构说明

夜莺支持多种数据源,可以利用:

  • Prometheus 数据源:复用上面的 Prometheus 方案
  • Categraf:夜莺自带的采集器,支持 SSL 证书采集
  • 自定义脚本 :通过 script 采集插件

3.2 方案一:使用 Categraf 采集 SSL 证书

Categraf 自带 ssl_cert 采集插件。

配置 Categraf

编辑 conf/input.ssl_cert/ssl_cert.toml

复制代码
[[instances]]
# 公网域名
targets = [
    "https://www.google.com",
    "https://github.com",
]

# 内网域名
internal_targets = [
    "https://internal.example.com",
    "https://jenkins.internal.com",
]

# 内网IP
ip_targets = [
    "https://192.168.1.100:8443",
    "https://10.0.0.50:443",
]

# 超时时间
timeout = "10s"

# 忽略证书验证(用于自签名证书)
# insecure_skip_verify = false

# 标签
labels = { job = "ssl_cert_monitoring" }

启动 Categraf:

复制代码
./categraf --configs /path/to/conf
采集到的指标

Categraf 会采集以下指标:

  • ssl_cert_days_left - 证书剩余天数
  • ssl_cert_expiry_timestamp - 证书过期时间戳

3.3 方案二:复用 Prometheus Blackbox Exporter

夜莺可以直接接入 Prometheus 作为数据源:

  1. 在夜莺的 基础设施 → 数据源 中添加 Prometheus 数据源
  2. 使用前面 Prometheus 方案中配置的 Blackbox Exporter

3.4 配置夜莺告警规则

进入夜莺 告警管理 → 告警规则,创建告警规则:

告警规则配置

规则名称:SSL证书有效期告警

级别:警告

规则

promql

复制

复制代码
ssl_cert_days_left < 30

备注(告警模板)

复制代码
告警: SSL证书即将过期
证书地址: {{ $labels.instance }}
剩余天数: {{ $value }} 天
告警时间: {{ timestamp }}
请及时更新证书!
严重告警规则

规则名称:SSL证书严重过期告警

级别:严重

规则

复制代码
ssl_cert_days_left < 7

3.5 配置告警通知渠道

进入 告警管理 → 通知设置

支持的通知方式:

  • 邮件
  • 钉钉
  • 企业微信
  • 飞书
  • Webhook
  • Slack
  • Telegram

示例(钉钉配置):

复制代码
{
  "msgtype": "markdown",
  "markdown": {
    "title": "SSL证书告警",
    "text": "### SSL证书即将过期\n\n**地址**: {{ $labels.instance }}\n**剩余天数**: {{ $value }} 天\n**告警级别**: {{ $labels.severity }}"
  }
}

3.6 夜莺告警规则完整示例

yaml

复制


四、方案对比

特性 Prometheus Zabbix 夜莺监控
部署复杂度 中等
内网IP支持
公网域名支持
告警灵活性
可视化 Grafana 内置 内置
通知渠道 丰富 丰富 丰富
推荐场景 云原生/K8s 传统运维 云原生/传统混合

五、注意事项

  1. 内网证书 :自签名证书可能需要设置 insecure_skip_verify: true
  2. 证书链:确保监控工具能获取完整的证书链信息
  3. 权限:执行脚本的用户需要有 openssl 命令访问权限
  4. 频率:建议监控间隔设置为1小时或更长,避免频繁探测
  5. 告警抑制:防止证书过期后持续告警,可设置告警恢复或抑制规则

六、快速验证脚本

提供一个通用的证书检查脚本,可用于任何监控系统:

复制代码
#!/bin/bash
# check_ssl_expiry.sh - 通用SSL证书检查
# 支持域名和IP

check_ssl() {
    local target="$1"
    local port="${2:-443}"
    
    # 提取主机名(如果是URL)
    local host=$(echo "$target" | sed 's|https\?://||' | sed 's|/.*||')
    
    # 获取证书信息
    local cert_info=$(echo | timeout 10 openssl s_client -connect "$host:$port" -servername "$host" 2>/dev/null)
    
    if [ -z "$cert_info" ]; then
        echo "ERROR: Cannot connect to $host:$port"
        return 1
    fi
    
    local expiry_date=$(echo "$cert_info" | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
    local expiry_ts=$(date -d "$expiry_date" +%s 2>/dev/null)
    local now_ts=$(date +%s)
    local days_left=$(( ($expiry_ts - $now_ts) / 86400 ))
    
    echo "Host: $host:$port"
    echo "Expiry: $expiry_date"
    echo "Days left: $days_left"
    
    if [ "$days_left" -lt 7 ]; then
        echo "CRITICAL: Certificate expires in $days_left days!"
        return 2
    elif [ "$days_left" -lt 30 ]; then
        echo "WARNING: Certificate expires in $days_left days"
        return 1
    else
        echo "OK: Certificate is valid for $days_left more days"
        return 0
    fi
}

# 批量检查
targets=(
    "https://www.google.com"
    "https://github.com"
    "192.168.1.100:8443"
)

for target in "${targets[@]}"; do
    echo "========================"
    check_ssl "$target"
    echo ""
done

文档生成时间: 2026-05-01

相关推荐
计算机安禾7 小时前
【Linux从入门到精通】第44篇:Linux网络协议栈与TCP参数调优
linux·网络协议·tcp/ip
KnowSafe7 小时前
证书自动化革命:CaaS如何重塑企业数字信任体系
https·ssl·itrustssl·trustasia
凯瑟琳.奥古斯特7 小时前
UDP检验和原理详解
网络·网络协议
时空自由民.7 小时前
计算机网络通信之TCP/UDP
网络协议·tcp/ip·udp
落叶_Jim8 小时前
2026年最新Let’s Encrypt免费SSL证书申请与自动续期完整指南(泛域名证书)
安全·https·ssl
WIZnet8 小时前
W55MH32 RTThread+TCP通信测试
网络·网络协议·tcp/ip
HABuo10 小时前
【linux(四)】套接字编程--基于UDP协议的客户端服务端
linux·服务器·c++·网络协议·ubuntu·udp·centos
liann11919 小时前
3.2_红队攻击框架--MITRE ATT&CK‌
python·网络协议·安全·网络安全·系统安全·信息与通信
zjun100120 小时前
TCP专栏-1.TCP协议概念说明
网络·网络协议·tcp/ip