检测 HTTPS 证书过期的几种方式

388次阅读
没有评论

共计 8752 个字符,预计需要花费 22 分钟才能阅读完成。

HTTPS的必要性

为什么要使用https证书

用户信任

流行的浏览器,例如chrome,在访问http域名时会直接提示不安全。

检测 HTTPS 证书过期的几种方式

而https则会显示出一个锁状图标。

检测 HTTPS 证书过期的几种方式

当用户在浏览器地址栏中看到一个绿色的锁形图标或者网站地址前的”https://”前缀时,他们知道他们正在与一个安全的网站进行通信。这种信任感对于用户分享敏感信息、进行在线购物、进行网上银行等活动至关重要。

数据安全

HTTPS证书通过加密传输的数据,防止第三方截获或篡改信息。这种加密保护确保了用户的个人信息、登录凭据、支付数据等在传输过程中的安全性。HTTPS证书的存在可以防止恶意攻击者窃取敏感数据,保护用户的隐私。

SEO优化

搜索引擎优化(SEO)已经成为网站拓展和推广的重要策略之一。搜索引擎如Google已经将HTTPS作为搜索排名的一个因素。拥有有效的HTTPS证书可以提高网站的可信度和可见性,从而提高搜索引擎排名,吸引更多的访问者和潜在客户。

合规

许多行业和地区都有数据保护和隐私法规的要求。拥有有效的HTTPS证书是满足这些法规要求的重要组成部分。例如,欧洲的GDPR(通用数据保护条例)要求网站在处理欧洲用户的个人数据时采取适当的安全措施,其中包括使用HTTPS加密传输。

安全目前是互联网应用的焦点之一。不论是个人还是企业用户,都建议对域名使用HTTPS协议进行加密通信。

在个人应用下,我们可以使用零成本的域名证书,例如使用由Let’s Encrypt开发的ACME获取免费的https证书。

而在企业背景下,我们通常会购买更高规格的收费证书,例如GeoTrust,DigCert等证书提供商,提供的OV证书等。

https证书等级

HTTPS证书通常分为三个主要等级:DV(Domain Validation)、OV(Organization Validation)和EV(Extended Validation)。这些等级反映了证书颁发机构对域名所有者的验证程度和证书所提供的可信度级别。

  1. DV(Domain Validation)证书:
    DV证书是最基本的HTTPS证书等级,也是最常见的类型。它们通过验证域名所有权来确认网站的身份。验证过程通常是通过向域名所有者发送确认邮件,要求他们在邮件中点击链接或添加特定的DNS记录。DV证书可以在几分钟内颁发,是最快速、最经济实惠的证书类型。它们提供了加密连接和基本的身份验证,适用于个人网站、博客和小型企业。
  2. OV(Organization Validation)证书:
    OV证书提供了比DV证书更高级别的验证和可信度。在颁发OV证书之前,证书颁发机构会对域名所有者进行更严格的验证,以确保其身份和组织的真实性。验证过程通常包括验证域名所有权、组织注册信息、组织的合法性和存在性等。OV证书会在浏览器地址栏中显示域名所有者的名称,提供了更高级别的身份验证和信任感。它们适用于中小型企业、电子商务网站和需要更高级别身份验证的网站。
  3. EV(Extended Validation)证书:
    EV证书是最高级别的HTTPS证书,提供了最高级别的身份验证和可信度。在颁发EV证书之前,证书颁发机构会进行更严格的验证,包括验证域名所有权、组织的合法性、存在性、运营资质等。EV证书在浏览器地址栏中显示绿色的公司名称和锁形图标,提供了最高级别的身份验证和信任度。EV证书通常用于大型企业、金融机构、电子支付平台等对安全性和身份验证要求较高的网站。

在个人应用下,我们可以使用零成本的域名证书,例如使用由Let’s Encrypt开发的ACME获取免费的https证书。它们通常都是DV级别的。

如何申请免费https,可以参考站内文章:使用 acme 获取免费 https 证书

而在企业背景下,我们通常会购买更高规格的收费证书,例如从GeoTrust,DigCert等证书提供商,购买收费的OV证书或者EV证书。

https证书的购买方式

在中国,直接从根数字证书提供者购买证书并不那么方便,因为它们均是海外的厂商,不能提供覆盖国内的常见支付渠道。

我们一般会从第三方公司进行购买,例如天威.或者各大云提供商,例如华为云/阿里云/腾讯云等。

如何使用https证书

在nginx中配置https

以下是一个简单的nginx配置文件示例

server {
    listen 80;
    server_name test.pyw.one;
    location / {
        default_type text/html;
        return 200 "OK";
    }
}


server {
    listen 443 ssl http2;
    server_name test.pyw.one;

    ssl_certificate     /root/.acme.sh/*.pyw.one/fullchain.cer;
    ssl_certificate_key /root/.acme.sh/*.pyw.one/*.pyw.one.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSV1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_prefer_server_ciphers on;

    location / {
        default_type text/html;
        return 200 "OK";
    }
}

在LB中配置https

如果使用公有云,公有云一般都会提供负载均衡(Load Balancer)服务。

负载均衡器的监听器可以提供https卸载能力。这样ssl的加解密不必在nginx中进行,可以降低服务器的CPU压力。同时LB作为流量入口,只需要配置一次https证书即可,否则后端若为多实例的nginx,每个nginx都需要进行https配置。

本文不详述如何在各云厂配置证书,它们有完整的帮助文档。

证书检测的方式

公网域名监测

此方式针对域名暴露在公网的场景。无外乎三个步骤:

  1. 获取域名列表
  2. 探测域名,获取证书过期时间
  3. 消费结果,进行上报至IM & 邮件或者发出告警等。

获取域名列表​ 和 消费结果​,根据实际业务场景进行处理。

获取域名列表的方式,如果域名不多且改动不频繁,可以采取人工直接写入本地文件。反之,应该通过API获取。

在实际的业务场景中,我们可能不止采取一家dns托管商。由cmdb作为数据中台,拉取各dns域名解析。再通过cmdb的api获取全量域名记录,进行探测。

而证书过期时间的结果消费,告警或通知渠道因人而异,不做详细分析。

下面介绍的两种方式,主要用于解决 步骤2:获取证书过期时间。

shell 脚本

Linux下的openssl命令,可以对域名证书进行解析。

下面是示例脚本的内容:

root@ ubuntu-family /tmp/ssl_check]
18:00:43 # cat main.sh 
#!/bin/bash
#
# 描述: 这是一个示例脚本,用于检测域名ssl证书过期时间
#
# 作者: pengyinwei
# 日期: 2023年7月30日

# 检查域名列表
file_path="./domains.txt"

if [ ! -s "$file_path" ]; then
  echo "请配置域名,例如baidu.com。每行一条"
  exit 1
  exit
fi

# 探测域名是否开启443端口
domains_443=()
for domain in `cat $file_path`
do
  nc -vz $domain 443  >/dev/null 2>&1
  if [ $? -eq 0 ];then
    domains_443+=("$domain")
  else
    echo "【检测域名是否开放443端口...】"
    echo "$domain 未开放443端口"
  fi
done
echo

# 对开启443端口的域名进行https过期时间检测
days=30
expiration_threshold=$((60*60*24*$days))

current_timestamp=$(date +%s)

echo "【域名证书过期检测...】"
for domain in "${domains_443[@]}"
do
  echo | openssl s_client -servername ${domain}  -connect ${domain}:443 2>/dev/null | openssl x509 -noout -dates >/dev/null 2>&1
  if [ $? -eq 0 ];then
    expiration_date=`echo | openssl s_client -servername ${domain}  -connect ${domain}:443 2>/dev/null | openssl x509 -noout -dates \
    | grep 'After' \
    | awk -F '=' '{print $2}'`
    expiration_timestamp=$(date -d "$expiration_date" +%s)
    remaining_time=$((expiration_timestamp - current_timestamp))
    if [  "$remaining_time" -lt "$expiration_threshold" ];then
      echo "$domain 证书将在30天内过期"
    else
      echo "$domain 证书不会在30天内过期"
    fi
  fi
done

执行结果如下:

[root@ ubuntu-family /tmp/ssl_check]
18:01:02 # pwd
/tmp/ssl_check
[root@ ubuntu-family /tmp/ssl_check]
18:02:01 # ls -l
total 8
-rw-r--r-- 1 root root   60 Jul 30 17:56 domains.txt
-rwxr-xr-x 1 root root 1458 Jul 30 17:59 main.sh
[root@ ubuntu-family /tmp/ssl_check]
18:02:05 # cat domains.txt 
baidu.com
asdasdasdaslggg.com
qq.com
weibo.com
blog.pyw.one
[root@ ubuntu-family /tmp/ssl_check]
18:02:08 # bash main.sh 
【检测域名是否开放443端口...】
asdasdasdaslggg.com 未开放443端口

【域名证书过期检测...】
baidu.com 证书不会在30天内过期
qq.com 证书不会在30天内过期
weibo.com 证书不会在30天内过期
blog.pyw.one 证书不会在30天内过期

小结

上述脚本实现了对ssl证书的检测。仔细想想,它存在一些弊端和局限。

访问域名时,使用的/etc/reslov.conf下配置的dns server进行域名解析,那么

  1. 若域名在内网,则不会有dns解析结果,故也无法进行ssl探测。
  2. 若域名配置了GEO解析(即位置解析,一个域名可以同时对不同的位置做不同的解析。例如可以配置baidu.com在中国访问时解析至1.1.1.1,在国外访问时解析至2.2.2.2),那么很明显,此脚本只能够探测出一个结果。即执行脚本的服务器所在位置的IP返回的证书信息。

prometheus

prometheus​是一个开源的监控系统,它有丰富的生态。官方原生提供了Blackbox Exporter​用于监控和收集网络相关数据。它可以实现对域名ssl相关数据的收集。

blackbox配置

官方下载链接

安装和分发配置文件

wget https://github.com/prometheus/blackbox_exporter/releases/download/v0.24.0/blackbox_exporter-0.24.0.linux-amd64.tar.gz
tar xf blackbox_exporter-0.24.0.linux-amd64.tar.gz
cd blackbox_exporter-0.24.0.linux-amd64/
cp blackbox_exporter /usr/local/bin
cp blackbox.yml /etc/blackbox_exporter.yml

编辑配置文件,启用http module

# vim /etc/blackbox_exporter.yml
modules:
  http_2xx:
    prober: http
    http:
      preferred_ip_protocol: "ip4"
      follow_redirects: false
      tls_config:
        insecure_skip_verify: true

配置systemd管理blackbox

# vim /etc/systemd/system/prometheus.service
[Unit]
Description=Blackbox Exporter
After=network-online.target

[Service]
Type=simple
PIDFile=/var/run/blackbox_exporter.pid
PermissionsStartOnly=true
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/usr/local/bin/blackbox_exporter \
  --config.file=/etc/blackbox_exporter.yml \
  --web.listen-address=0.0.0.0:9119

SyslogIdentifier=blackbox_exporter
KillMode=process
Restart=always
RestartSec=5


NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true

ProtectSystem=full

[Install]
WantedBy=multi-user.target

# systemctl daemon-reload
# systemctl enable blackbox_exporter
# systemctl start blackbox_exporter

prometheus配置

官方下载链接

安装

wget https://github.com/prometheus/prometheus/releases/download/v2.46.0/prometheus-2.46.0.linux-amd64.tar.gz
tar xf prometheus-2.46.0.linux-amd64.tar.gz
mv prometheus-2.46.0.linux-amd64 /usr/local/prometheus

# 创建taget目录
mkdir /usr/local/prometheus/file_sd

# 创建数据目录
mkdir  /var/lib/prometheus/

编辑配置,增加需要监控的域名

# vim /etc/prometheus/file_sd/blackbox_http.yml
- labels:
    tag: '测试'
  targets:
  - https://www.google.com
  - https://www.youtube.com
  - https://platform.openai.com

编辑配置,添加blackbox的job

# vim /etc/prometheus/prometheus.yml
global:
  evaluation_interval: 15s
  scrape_interval: 30s
  scrape_timeout: 10s

scrape_configs:
- job_name: 'blackbox_http'
  scrape_interval: 30s
  metrics_path: /probe
  params:
    module: [http_2xx]
  file_sd_configs:
    - files:
      - '/etc/prometheus/file_sd/blackbox_http.yml'

配置systemd管理prometheus

# vim /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus
After=network.target

[Service]
Type=simple
Environment="GOMAXPROCS=4"
LimitCORE=infinity
LimitNOFILE=65535
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus \
  --storage.tsdb.retention=90d \
  --web.console.libraries=/etc/prometheus/console_libraries \
  --web.console.templates=/etc/prometheus/consoles \
  --web.listen-address=0.0.0.0:9090 \
  --web.external-url= \
  --web.enable-admin-api \
  --storage.tsdb.min-block-duration=1h \
  --storage.tsdb.max-block-duration=1h

PrivateTmp=true
PrivateDevices=true
ProtectHome=true
NoNewPrivileges=true
ReadWriteDirectories=/var/lib/prometheus
ProtectSystem=full


SyslogIdentifier=prometheus
Restart=always

[Install]
WantedBy=multi-user.target

# systemctl daemon-reload
# systemctl enable prometheus.service
# systemctl start prometheus.service

grafana绘制面板

此处自行选择是否要做,grafana只是一种数据消费方式,并不是本文的重点。

不做详细说明,仅用于预览效果:

检测 HTTPS 证书过期的几种方式

promql查询语句:(probe_ssl_earliest_cert_expiry - time() ) /86400

小结

此方式的配置与shell脚本相比,配置更繁琐些。而它也有和shell脚本方式同样的弊端,受限于dns解析。

好处是,shell脚本是一次性的,而prometheus可以将数据落盘,并且数据格式是规范的,可以更好的让数据被消费。例如绘制实时的grafana看板,或使用代码读取数据。

需要注意的是,需要合理的设置scrape_interval​,scrape_interval​过短会产生大量无效请求。同时域名若不存在/​路径,直接配置域名探测/​也会产生错误日志。

反向证书检测

上面的两种方式,其实探测的原理都是基于访问域名,通过dns解析再获取到后端的证书信息。那么我们应该怎么解决dns的弊端呢?

一种方式是,在多个location中进行探测。例如GEO解析有5个不同位置,则需要在这5个地理位置下都进行探测。很明显,这样成本比较大。

还有一种方式则依赖SRE基础设施的完备。

  1. 统一的数据中台,例如cmdb

cmdb收集了所有的域名解析以及证书信息。

  • 证书私钥和证书内容
  • 证书的过期时间
  • 域名和证书的使用方

  1. 网关可控

约定一致的网关进行ssl卸载。在实际业务场景中,并不会允许业务方自行操作证书。SRE会提供统一的网关作为流量入口,证书也均约定在此配置。网关可以是云厂ELB,或者自研的apisix & nginx等。

满足这两点后,我们即可以清楚的知道并实现

  • 有哪些域名
  • 哪些域名需要证书
  • 域名和证书的使用方是谁
  • 过期前通知方,是否需续费

结论

本文简单介绍了域名为什么要使用https,以及https证书过期的几种检测方式。

检测的架构是随着业务需求逐步演进的,前期域名少,并且没有复杂的dns解析策略,可以简单的使用shell脚本探测和通知。

随着dns解析策略复杂度变高,单机执行shell脚本已经不能满足诉求,而将脚本分发到多个location执行,脚本的维护和和合并通知,又变成一个痛点。于是我们利用已有的prometheus监控设施,进行实时探测。而数据落盘,也可以丰富我们的消费手段,例如使用告警组件查询prometheus数据配置过期策略 & 配置巡检,grafana绘制看板等。

而这样仍不能解决当下的所有问题,对于内网域名无法探测,对于geo域名,需要在每一个location下都部署prometheus。

于是我们最终选择完善基础设置

  1. 统一的数据中台,cmdb会自动从证书提供商导入全量的证书信息
  2. 统一的网关,用于流量分发和配置https
  3. 统一的证书分析平台,于分析证书是否过期并通知关联的业务团队
  4. 自动化工单,业务可自行提交工单进行证书更新
  5. chatops,业务直接在企业IM工具发送聊天信息,更新证书
  6. chatops,业务在企业IM工具收到证书通知,可点击按钮触发证书更新

在未来,我们将继续关注SSL证书管理的最佳实践,并持续改进我们的架构,以适应不断变化的需求。确保提供稳定可靠的服务。

引用链接

正文完
 
pengyinwei
版权声明:本站原创文章,由 pengyinwei 2023-07-31发表,共计8752字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处:https://www.opshub.cn
评论(没有评论)