检查证书
基于Go的工具来检查/验证证书(例如,作为Nagios服务检查的一部分)。
概述
此版本包含用于监控/验证证书的各种工具。
| 工具名称 | 状态 | 描述 |
|---|---|---|
check_certs | 测试版 | 用来监控证书链的Nagios插件。 |
lscert | 测试版 | 小型CLI应用,用于生成证书元数据和过期状态的摘要。 |
fixsn | 阿尔法 | 小型CLI应用,用于将给定的10进制序列号转换为16进制、以冒号分隔的十六进制字符串格式。 |
certsum | 阿尔法 | CLI应用程序用于扫描一个或多个给定的CIDR IP范围的证书,并提供一份总结报告。 |
check_certs
Nagios插件用于监控证书链。除了
与lscert 共享的
功能外
,该应用程序还根据
证书的通用名称或
可用的SAN条目之一验证所提供的主机名
。
这个应用程序的输出旨在提供
Nagios需要的
单行摘要
,以便快速识别问题,同时提供更长、
更详细的信息,用于电子邮件和团队通知
(atc0005/send2teams
)。
lscert
小型CLI工具,用于快速审查更换证书的结果
和/或故障排除,为什么连接到支持证书的服务可能
失败。
证书元数据可以从以下方面检索。
- 指定全称域名(如:
www.github.com)或IP地址和端口(如:443)
的远程服务 - 本地证书 "包 "或独立的叶子证书文件
如果通过 IP 地址指定主机,将发出警告,除非该 IP
地址在证书的 SANs 列表中。如果你
想应用主机名验证
,
提供一个有效的FQDN作为
服务器名称或 "dns name",
这个警告可以被忽略。
fixsn
一个小型的CLI应用程序,用于将给定的(假定的)基数10转换成基数
16,以冒号分隔的十六进制字符串,代表证书序列号。
这个项目
以前
的版本不正确地将序列号显示为基数为10的数值
,而不是基数为16、以冒号分隔的十六进制字符串。使用这个工具可以将
旧的数值一次性转换为正确的格式(例如,
文档中保持的
证书
列表)。
除非其他人发现它很有用
,否则这个工具很可能
在未来的某一天
被移除或被折叠到另一个工具中。
certsum
certsum 是一个IP范围证书扫描器的原型。这个工具目前是
"阿尔法 "级别的质量;许多暴露的标志、帮助文本和摘要输出
在以后的版本中会有很大变化。
这个工具旨在扫描一个或多个给定的IP范围,以便
为发现的证书生成一份报告,但也可以用来扫描
少至一个目标。
对于较小的IP范围来说,性能可能是可以接受的,但可以
根据需要使用速率限制调整标志(详见配置
选项
部分)来调整。目前的
默认值是为了平衡扫描速度和操作系统对
开放文件句柄数量
的
限制
。如果调整这个值,从小的
增量
开始
,以确定对你的环境的最佳结果。
默认的不活动超时是用来终止应用程序的,如果扫描
尝试停滞了一段指定的时间。详情见配置
选项
部分。
IP地址可以被指定为逗号分隔的值。
- 单个IP地址
- CIDR IP范围
- 部分范围
- 使用八位数范围寻址的部分实现(例如,
192.168.2.10-15)
。
- 使用八位数范围寻址的部分实现(例如,
- 全称域名(FQDNs)
- 主机名**(脆弱的)**
-
这在很大程度上取决于你的DNS配置,特别是任何
配置的搜索列表(又称Windows
术语
中的DNS Suffix Search List
)条目,用于限定短名/主机名值
-
支持过滤 "OK "状态的主机和证书
,以增加或减少
生成的摘要输出
中提供的信息量(尽管有限)。
提供两种摘要模式,以控制
所提供的输出中的详细程度。
特点
-
验证证书的多种工具
lscertCLI工具- 验证指定服务使用的证书
- 验证本地证书 "包 "或独立的叶子证书文件
check_certNagios插件- 验证指定服务使用的证书
- 验证本地证书 "包 "或独立的叶子证书文件
certsumCLI工具- 生成从给定的主机(单个或
IP地址范围、主机名或FQDNs)和端口
发现的证书的摘要
- 生成从给定的主机(单个或
-
检查所提供的证书链中的所有证书的过期情况,用于
支持证书的服务- 未过期
- 即将到期"。
- 警告阈值
- 关键阈值
-
根据通用名称或可用的
SANs条目
之一验证提供的主机名
(见配置选项 -
可选支持对照
所提供的列表
验证证书上的SANs条目-
如果提供
SKIPSANSCHECKS关键字作为值,
将
不
执行
SANs条目检查
;这个关键字对于定义共享的Nagios
检查命令和服务检查
非常有用
,因为一些主机可能不使用
定义有SANs条目的证书。
-
-
详细的 "报告 "发现
- 证书顺序
- 证书类型
- 状态(OK, CRITICAL, WARNING)
- SANs条目
- 序列号
- 发行者
-
可选择从目标证书启用的
服务或文件名
生成类似OpenSSL的文本输出- 感谢
grantae/certinfo包
- 感谢
-
可选的,使用
rs/zerolog包的分级日志记录- JSON格式的输出(到
stderr) - 可选择
disabled,panic,fatal,error,warn,info(
默认),debug或trace。
- JSON格式的输出(到
-
可选的,用户指定的TCP连接尝试的超时值
更新日志
参见该 CHANGELOG.md文件,以了解与
本应用程序的每个版本
相关的变化
。已经合并到master ,
但还没有正式发布的
变化
也可以在文件中
的
Unreleased
部分下注明。
还提供了
一个指向自上次
正式发布
以来的Git提交历史的有用链接
,以便进一步审查。
要求
以下是一个宽松的指导原则。其他
用于构建和运行本软件库中的工具
的Go和操作系统的组合
可能有效,但没有
经过测试。
构建源代码
- Go 1.13以上
- GCC
- 如果使用自定义选项进行构建(如所提供的
Makefile所示)
- 如果使用自定义选项进行构建(如所提供的
make- 如果使用提供的
Makefile
- 如果使用提供的
运行
- Windows 7, Server 2008R2或更高版本
- 按照官方的[Go安装说明][go-docs-install]。
- Windows 10 1909版
- 经过测试
- Ubuntu Linux 16.04, 18.04
安装
-
[下载][go-docs-download] Go
-
[安装][go-docs-install] 去
- 注意:请特别注意以下的备注
$HOME/.profile
- 注意:请特别注意以下的备注
-
克隆该版本
cd /tmpgit clone https://github.com/atc0005/check-certcd check-cert
-
安装依赖项(可选)
- 适用于Ubuntu Linux
sudo apt-get install make gcc
- 适用于CentOS Linux
sudo yum install make gcc
- 适用于Windows
-
仿真环境*(更简单*)
- 跳过所有这些,在
Windows
中使用默认的go build命令进行构建
(关于-mod=vendor标志的使用,见下文)
。 - 使用Windows Subsystem for Linux Ubuntu环境构建,只需
从该环境中复制出Windows二进制文件
即可 - 如果已经运行Docker环境,使用
已经安装
Go
工具链
的容器 - 如果已经熟悉LXD,创建一个容器,并按照
前面给出的安装步骤安装所需的依赖
。
- 跳过所有这些,在
-
本地工具*(更难)* *
关于
在Windows上安装make的 潜在选择 ,请参见 [参考资料](https://golangexample.com/go-based-tooling-to-check-verify-certs-e-g-as-part-of-a-nagios-service-check/references.md) 部分的StackOverflow问题`32127524` 链接。-
参见
参考文献
中的mingw-w64项目主页链接
,了解
在Windows上
安装gcc和相关软件包的
选项
。
-
-
- 适用于Ubuntu Linux
-
构建二进制文件
-
对于当前的操作系统,明确使用
顶级vendor文件夹go build -mod=vendor ./cmd/check_cert/go build -mod=vendor ./cmd/lscert/go build -mod=vendor ./cmd/fixsn/go build -mod=vendor ./cmd/certsum/
中
的捆绑的依赖项。 -
适用于所有支持的平台(已安装
make)make all
-
在Windows上使用
make windows
-
在Linux上使用
make linux
-
-
从
下面
适用的/tmp子目录路径中复制新编译的二进制文件
(基于本节中的克隆说明),并在
需要的
地方部署
。- 如果使用
Makefile-
,请在
/tmp/check-cert/release_assets/check_cert/
-
,请在
-
-
/tmp/check-cert/release_assets/lscert/
-
,请在
-
/tmp/check-cert/release_assets/fixsn/- ,请在
/tmp/check-cert/release_assets/certsum/
-
,如果使用
go build
,
-
-
请在
/tmp/check-cert/
-
- 如果使用
配置选项
阈值计算
check_cert插件的行为与
check_http v2.1.2
有些不同
;
对于相同的WARNING 和
CRITICAL
阈值,该插件的触发
时间比check_http 晚
一整天
。
例如,如果我们使用WARNING 阈值的默认值为30天
,CRITICAL 阈值为15天。
-
阈值的计算
WARNING:现在(UTC中的确切时间)+30天CRITICAL:现在(UTC中的确切时间)+15天
-
检查证书过期日期,最开始的匹配(按
顺序)决定服务检查的状态-
,如果证书在当前时间之前过期,状态为
EXPIRED -
,如果证书在CRITICAL阈值之前过期,状态
为 -
CRITICAL -
,如果证书在WARNING阈值之前过期,状态
为 -
WARNING
,
-
否则,假设证书的状态为
OK
-
不进行四舍五入。
其他信息见GH-32。
命令行参数
- 使用
-h或--help标志来显示当前使用信息。 - 标记为 **
required**必须通过CLI标志来设置。 - 没有标记为需要的标志是用于
已经定义了
有用的默认值的设置
,但如果需要,可以重写。
check_cert
| 标志 | 需要 | 默认值 | 重复 | 可能的 | 说明 |
|---|---|---|---|---|---|
f,filename | 没有 | false | 没有 | 有效的文件名字符 | 包含一个或多个证书的PEM格式的证书文件的全称路径。 |
branding | 没有 | false | 没有 | branding | 切换品牌细节与插件状态细节的排放。该输出默认是禁用的。 |
h,help | 没有 | false | 没有 | h,help | 显示帮助文本和支持的标志列表。 |
v,verbose | 没有 | false | 不 | v,verbose | 切换详细证书元数据的排放。默认情况下,该级别的输出是禁用的。 |
version | 没有 | false | 不 | version | 是否显示应用程序的版本,然后立即退出应用程序。 |
c,age-critical | 否 | 15 | 否 | 正整数天数 | 证书检查的CRITICAL 状态的阈值。如果证书在这个天数之前过期,那么服务检查将被视为处于CRITICAL 状态。 |
w,age-warning | 否 | 30 | 没有 | 正整数天数 | 证书检查的WARNING 状态的阈值。如果证书在这个天数之前过期,但在age-critical 值之前没有过期,那么服务检查将被视为处于WARNING 状态。 |
ll,log-level | 没有 | info | 没有 | disabled,panic,fatal,error,warn,info,debug 。trace | 日志消息优先级过滤器。具有较低级别的日志消息被忽略。 |
p,port | 没有 | 443 | 没有 | 1-65535之间的正整数,包括在内 | 远程证书启用的服务的TCP端口。这通常是443(HTTPS)或636(LDAPS)。 |
t,timeout | 没有 | 10 | 没有 | 正整数秒 | 在放弃与远程认证服务的连接尝试(为了检索证书)并返回错误之前,允许的超时值(秒)。 |
se,sans-entries | 没有 | 没有 | 逗号分隔的数值列表 | 预计远程服务使用的证书的一个或多个主题替代名称(SAN)。如果提供,这个逗号分隔(可选)的值列表是证书通过验证的必要条件。如果提供了不区分大小写的SKIPSANSCHECKS关键字,则验证将被跳过,有效地将该标志的使用变成NOOP。 | |
s,server | 是 | 没有 | 全称域名或IP地址 | 远程系统的全称域名或IP地址,其证书将被监控。该值用于与服务器建立连接,以检索证书链。对于只有一个证书的主机,这个值通常是主机本身的FQDN,但对于多证书的服务器,用户指定的值将是至关重要的,以便让远程主机选择适当的证书(支持服务器名称指示(SNI))。对于托管在这些服务器上的网站,有必要改为提供网站的FQDN而不是服务器主机名。例如,指定www.example.org ,而不是host7.example.com 。如果有疑问,请指定网站的FQDN。用户指定的值也将根据通用名称和主题替代名称字段进行验证*,除非*还指定了dns-name 标志,在这种情况下,这个值只用于建立初始连接。 | |
dn,dns-name | 没有 | 没有 | 全称域名或IP地址 | 远程系统的全称域名,用于主机名验证。该选项可用于初始连接使用与证书无关的名称或 IP 地址的情况。更多信息请参见server 标志描述。 |
lscert
| 标志 | 需要 | 默认值 | 重复 | 可能的 | 说明 |
|---|---|---|---|---|---|
f,filename | 没有 | false | 没有 | 有效的文件名字符 | 包含一个或多个证书的PEM格式的证书文件的全称路径。 |
text | 没有 | false | 没有 | true,false | 切换x509 TLS证书在OpenSSL启发的文本格式中的排放。该输出在默认情况下是禁用的。 |
h,help | 不 | false | 没有 | h,help | 显示帮助文本和支持的标志列表。 |
v,verbose | 没有 | false | 不 | v,verbose | 切换详细证书元数据的排放。默认情况下,该级别的输出是禁用的。 |
version | 没有 | false | 不 | version | 是否显示应用程序的版本,然后立即退出应用程序。 |
c,age-critical | 否 | 15 | 否 | 正整数天数 | 证书检查的CRITICAL 状态的阈值。如果证书在这个天数之前过期,那么服务检查将被视为处于CRITICAL 状态。 |
w,age-warning | 否 | 30 | 没有 | 正整数天数 | 证书检查的WARNING 状态的阈值。如果证书在这个天数之前过期,但在age-critical 值之前没有过期,那么该服务检查将被视为处于WARNING 状态。 |
ll,log-level | 没有 | info | 没有 | disabled,panic,fatal,error,warn,info,debug 。trace | 日志消息优先级过滤器。具有较低级别的日志消息被忽略。 |
p,port | 没有 | 443 | 没有 | 1-65535之间的正整数,包括在内 | 远程证书启用的服务的TCP端口。这通常是443(HTTPS)或636(LDAPS)。 |
t,timeout | 没有 | 10 | 没有 | 正整数秒 | 在放弃与远程认证服务的连接尝试(为了检索证书)并返回错误之前,允许的超时值(秒)。 |
se,sans-entries | 没有 | 没有 | 逗号分隔的数值列表 | 预计远程服务使用的证书的一个或多个主题替代名称(SAN)。如果提供,这个逗号分隔的(可选)值列表是证书通过验证的必要条件。如果提供了不区分大小写的SKIPSANSCHECKS关键字,则验证将被跳过,有效地将该标志的使用变成NOOP。 | |
s,server | 是 | 没有 | 全称域名或IP地址 | 远程系统的全称域名或IP地址,其证书将被监控。该值用于与服务器建立连接,以检索证书链。对于只有一个证书的主机,这个值通常是主机本身的FQDN,但对于多证书的服务器,用户指定的值将是至关重要的,以便让远程主机选择适当的证书(支持服务器名称指示(SNI))。对于托管在这些服务器上的网站,有必要改为提供网站的FQDN而不是服务器主机名。例如,指定www.example.org ,而不是host7.example.com 。如果有疑问,请指定网站的FQDN。用户指定的值也将根据通用名称和主题替代名称字段进行验证*,除非*还指定了dns-name 标志,在这种情况下,这个值只用于建立初始连接。 | |
dn,dns-name | 没有 | 没有 | 完全合格的域名或IP地址 | 用于主机名验证的远程系统的完全限定域名。该选项可用于初始连接使用与证书无关的名称或 IP 地址的情况。更多信息见server 标志描述。 |
fixsn
这个工具不接受任何标志。相反,它只希望收到一个
参数:一个基数为10的格式化证书序列号,内部处理为
*big.Int 。这个值被转换为一个以16为基数、以冒号为分隔符的十六进制
字符串。这种格式是用于检查证书的工具所共有的。
使用方法见实例部分。
certsum
这个工具正在早期开发中。这个工具的选项可能会有
变化,也许在未来的版本中会有很大的变化。
| 标志 | 需要 | 默认值 | 重复 | 可能的 | 说明 |
|---|---|---|---|---|---|
h,help | 没有 | false | 没有 | h,help | 显示帮助文本和支持的标志列表。 |
version | 没有 | false | 不 | version | 是否显示应用程序的版本,然后立即退出应用程序。 |
c,age-critical | 否 | 15 | 否 | 正整数天数 | 证书检查的CRITICAL 状态的阈值。如果证书在这个天数之前过期,那么服务检查将被视为处于CRITICAL 状态。 |
w,age-warning | 否 | 30 | 没有 | 正整数的天数 | 证书检查的WARNING 状态的阈值。如果证书在这个天数之前过期,但在age-critical 值之前没有过期,那么该服务检查将被视为处于WARNING 状态。 |
ll,log-level | 没有 | info | 没有 | disabled,panic,fatal,error,warn,info,debug 。trace | 日志消息优先级过滤器。具有较低级别的日志消息被忽略。 |
t,timeout | 没有 | 10 | 没有 | 正整数秒 | 在放弃与远程认证服务的连接尝试(为了检索证书)并返回错误之前,允许的超时值(秒)。 |
se,sans-entries | 没有 | 没有 | 逗号分隔的数值列表 | 预计远程服务使用的证书的一个或多个主题替代名称(SAN)。如果提供,这个逗号分隔(可选)的值列表是证书通过验证的必要条件。如果提供了不区分大小写的SKIPSANSCHECKS关键字,则验证将被跳过,有效地将该标志的使用变成NOOP。 | |
st,scan-timeout | 没有 | 200 | 没有 | 正整数的毫秒,最小为1 | 在端口扫描过程中的连接尝试被放弃并返回错误之前的毫秒数。这个超时值与检索证书时使用的一般timeout 值分开。这个设置是专门用来快速确定端口状态的,作为速度至关重要的批量操作的一部分。 |
at,app-timeout | 不 | 30 | 没有 | 正整数的秒数,最小为2 | 允许应用程序在自动终止前保持不活动(即 "挂起")的秒数。 |
srl,scan-rate-limit | 没有 | 100 | 没有 | 正整数 | 最大并发端口和证书扫描。剩余的扫描被排队,直到现有的扫描完成。 |
ips,hosts | 没有 | 没有 | 一个或多个有效的、用逗号分隔的 IP 地址(单个或范围)、主机名或 FQDNs | 逗号分隔的单个IP地址、CIDR IP范围、部分(破折号分隔的)范围(如192.168.2.10-15)、主机名或FQDNs的列表,以扫描证书。 | |
p,ports | 没有 | 443 | 没有 | 一个或多个有效的、用逗号隔开的TCP端口 | 逗号分隔的TCP端口列表,用于检查证书。如果不指定,该列表默认为仅有443。 |
spsr,show-port-scan-results | 没有 | false | 没有 | true,false | 切换列出主机端口扫描结果。 |
scp,show-closed-ports | 没有 | false | 不 | true,false | 切换列出所有主机端口扫描结果,即使是没有任何指定端口处于开放状态的主机。 |
shwvc,show-hosts-with-valid-certs | 不 | false | 不 | true,false | 切换为在概览输出中列出所有证书检查结果,即使是有有效证书的主机。 |
svc,show-valid-certs | 没有 | false | 不 | true,false | 切换在输出概要中列出所有证书,即使是已经通过所有有效性检查的证书。 |
so,show-overview | 没有 | false | 没有 | true,false | 将摘要输出视图从详细视图切换到概览。 |
配置文件
目前不支持。如果有
足够的兴趣
,这个功能可能会在以后添加。
例子
check_cert Nagios插件
确定结果
这个例子显示了使用Nagios插件来手动检查
www.google.com 上的
一个远程
认证端口。我们
用一些任意的数字
覆盖了默认的WARNING
和CRITICAL 年龄阈值。
注意:使用--verbose 标志来显示进一步的细节。
$ ./check_cert --server www.google.com --port 443 --age-critical 30 --age-warning 50
OK: leaf cert "www.google.com" expires next with 52d 16h remaining (until 2021-09-20 04:12:57 +0000 UTC) [EXPIRED: 0, EXPIRING: 0, OK: 3]
**ERRORS**
* None
**THRESHOLDS**
* CRITICAL: Expires before 2021-08-28 11:55:42 +0000 UTC (30 days)
* WARNING: Expires before 2021-09-17 11:55:42 +0000 UTC (50 days)
**DETAILED INFO**
Certificate 1 of 3 (leaf):
Name: CN=www.google.com
SANs entries: [www.google.com]
Issuer: CN=GTS CA 1C3,O=Google Trust Services LLC,C=US
Serial: 12:D4:D6:BA:D3:7B:1D:D1:0A:00:00:00:00:EB:61:08
Issued On: 2021-06-28 04:12:58 +0000 UTC
Expiration: 2021-09-20 04:12:57 +0000 UTC
Status: [OK] 52d 16h remaining
Certificate 2 of 3 (intermediate):
Name: CN=GTS CA 1C3,O=Google Trust Services LLC,C=US
SANs entries: []
Issuer: CN=GTS Root R1,O=Google Trust Services LLC,C=US
Serial: 02:03:BC:53:59:6B:34:C7:18:F5:01:50:66
Issued On: 2020-08-13 00:00:42 +0000 UTC
Expiration: 2027-09-30 00:00:42 +0000 UTC
Status: [OK] 2253d 12h remaining
Certificate 3 of 3 (intermediate):
Name: CN=GTS Root R1,O=Google Trust Services LLC,C=US
SANs entries: []
Issuer: CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE
Serial: 77:BD:0D:6C:DB:36:F9:1A:EA:21:0F:C4:F0:58:D3:0D
Issued On: 2020-06-19 00:00:42 +0000 UTC
Expiration: 2028-01-28 00:00:42 +0000 UTC
Status: [OK] 2373d 12h remaining
参见WARNING 示例输出以了解更多细节。
警告结果
这里我们再次做同样的事情,但使用
前面
返回的到期日期值
作为起点,我们故意移动阈值,
以便
触发叶子证书的WARNING 状态:如果叶子
证书的有效期为52天又16小时,我们表示
一旦证书的有效期少于53天,就应该触发
警告
。
注意:使用--verbose 标志来暴露进一步的细节。
$ ./check_c./check_cert --server www.google.com --port 443 --age-critical 30 --age-warning 53
{"level":"error","version":"check-cert v0.4.2-6-g934c303 (https://github.com/atc0005/check-cert)","logging_level":"info","app_type":"plugin","cert_check_timeout":"10s","age_warning":53,"age_critical":30,"expected_sans_entries":"","server":"www.google.com","port":443,"error":"1 certificates expired or expiring","expired_certs":0,"expiring_certs":1,"time":"2021-07-29T06:57:11-05:00","caller":"github.com/atc0005/check-cert/cmd/check_cert/main.go:241","message":"expired or expiring certs present in chain"}
WARNING: leaf cert "www.google.com" expires next with 52d 16h remaining (until 2021-09-20 04:12:57 +0000 UTC) [EXPIRED: 0, EXPIRING: 1, OK: 2]
**ERRORS**
* 1 certificates expired or expiring
**THRESHOLDS**
* CRITICAL: Expires before 2021-08-28 11:57:11 +0000 UTC (30 days)
* WARNING: Expires before 2021-09-20 11:57:11 +0000 UTC (53 days)
**DETAILED INFO**
Certificate 1 of 3 (leaf):
Name: CN=www.google.com
SANs entries: [www.google.com]
Issuer: CN=GTS CA 1C3,O=Google Trust Services LLC,C=US
Serial: 12:D4:D6:BA:D3:7B:1D:D1:0A:00:00:00:00:EB:61:08
Issued On: 2021-06-28 04:12:58 +0000 UTC
Expiration: 2021-09-20 04:12:57 +0000 UTC
Status: [WARNING] 52d 16h remaining
Certificate 2 of 3 (intermediate):
Name: CN=GTS CA 1C3,O=Google Trust Services LLC,C=US
SANs entries: []
Issuer: CN=GTS Root R1,O=Google Trust Services LLC,C=US
Serial: 02:03:BC:53:59:6B:34:C7:18:F5:01:50:66
Issued On: 2020-08-13 00:00:42 +0000 UTC
Expiration: 2027-09-30 00:00:42 +0000 UTC
Status: [OK] 2253d 12h remaining
Certificate 3 of 3 (intermediate):
Name: CN=GTS Root R1,O=Google Trust Services LLC,C=US
SANs entries: []
Issuer: CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE
Serial: 77:BD:0D:6C:DB:36:F9:1A:EA:21:0F:C4:F0:58:D3:0D
Issued On: 2020-06-19 00:00:42 +0000 UTC
Expiration: 2028-01-28 00:00:42 +0000 UTC
Status: [OK] 2373d 12h remaining
一些需要注意的事项(按出现顺序排列)。
-
提供结构化日志信息的JSON输出
- 这被发送到
stderr - Nagios会忽略来自插件的
stderr输出;stdout是给Nagios的,
stderr
是给人类的。
- 这被发送到
-
第二行的单行状态输出
- Nagios用它来显示
一个主机的
所有服务
检查的
概况。 - 这是Nagios用于文本、电子邮件和其他的通知
(如果配置了
)。
- Nagios用它来显示
-
ERRORS部分简要说明了证书的问题所在。 -
CERTIFICATE AGE THRESHOLDS部分记录了用于
确定当前服务检查状态(结果)
的(计算)阈值。 -
DETAILED INFO部分包含证书链的概述-
Nagios用这个来显示详细的服务检查专用
页面(例如,显示最后一次检查时间、频率、当前状态等 -
至于单行输出,它被Nagios用于文本、电子邮件和
其他可能配置的通知
。
-
-
叶子证书的
Status字段从OK变成了WARNING
,这个插件设置了适当的退出代码,让Nagios知道了这个
状态变化。
重要的结果
过期的证书
与WARNING 的例子一样,我们使用
初始检查
返回的到期日期值
作为起点,故意移动阈值,
以便
触发叶子证书的CRITICAL 状态:如果
叶子证书的有效期为 52 天 16 小时以上,我们为
WARNING
阈值指定 90 天
,为CRITICAL 阈值
指定
60 天。这将
触发一个CRITICAL 状态。
注意:使用--verbose 标志来暴露进一步的细节。
$ ./check_c./check_cert --server www.google.com --port 443 --age-critical 60 --age-warning 90
{"level":"error","version":"check-cert v0.4.2-6-g934c303 (https://github.com/atc0005/check-cert)","logging_level":"info","app_type":"plugin","cert_check_timeout":"10s","age_warning":90,"age_critical":60,"expected_sans_entries":"","server":"www.google.com","port":443,"error":"1 certificates expired or expiring","expired_certs":0,"expiring_certs":1,"time":"2021-07-29T06:58:35-05:00","caller":"github.com/atc0005/check-cert/cmd/check_cert/main.go:241","message":"expired or expiring certs present in chain"}
CRITICAL: leaf cert "www.google.com" expires next with 52d 16h remaining (until 2021-09-20 04:12:57 +0000 UTC) [EXPIRED: 0, EXPIRING: 1, OK: 2]
**ERRORS**
* 1 certificates expired or expiring
**THRESHOLDS**
* CRITICAL: Expires before 2021-09-27 11:58:35 +0000 UTC (60 days)
* WARNING: Expires before 2021-10-27 11:58:35 +0000 UTC (90 days)
**DETAILED INFO**
Certificate 1 of 3 (leaf):
Name: CN=www.google.com
SANs entries: [www.google.com]
Issuer: CN=GTS CA 1C3,O=Google Trust Services LLC,C=US
Serial: 12:D4:D6:BA:D3:7B:1D:D1:0A:00:00:00:00:EB:61:08
Issued On: 2021-06-28 04:12:58 +0000 UTC
Expiration: 2021-09-20 04:12:57 +0000 UTC
Status: [CRITICAL] 52d 16h remaining
Certificate 2 of 3 (intermediate):
Name: CN=GTS CA 1C3,O=Google Trust Services LLC,C=US
SANs entries: []
Issuer: CN=GTS Root R1,O=Google Trust Services LLC,C=US
Serial: 02:03:BC:53:59:6B:34:C7:18:F5:01:50:66
Issued On: 2020-08-13 00:00:42 +0000 UTC
Expiration: 2027-09-30 00:00:42 +0000 UTC
Status: [OK] 2253d 12h remaining
Certificate 3 of 3 (intermediate):
Name: CN=GTS Root R1,O=Google Trust Services LLC,C=US
SANs entries: []
Issuer: CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE
Serial: 77:BD:0D:6C:DB:36:F9:1A:EA:21:0F:C4:F0:58:D3:0D
Issued On: 2020-06-19 00:00:42 +0000 UTC
Expiration: 2028-01-28 00:00:42 +0000 UTC
Status: [OK] 2373d 12h remaining
过期证书
这里我们使用expired.badssl.com子域来演示
在一个链中遇到一个或多个(这里是多个)过期证书
的结果
。
除了FQDN之外,所有默认选项(包括端口)都被使用。
注意:使用--verbose 标志来暴露进一步的细节。
$ ./check_cert --server expired.badssl.com
{"level":"error","version":"check-cert v0.4.2-6-g934c303 (https://github.com/atc0005/check-cert)","logging_level":"info","app_type":"plugin","cert_check_timeout":"10s","age_warning":30,"age_critical":15,"expected_sans_entries":"","server":"expired.badssl.com","port":443,"error":"2 certificates expired or expiring","expired_certs":2,"expiring_certs":0,"time":"2021-07-29T07:02:17-05:00","caller":"github.com/atc0005/check-cert/cmd/check_cert/main.go:241","message":"expired or expiring certs present in chain"}
CRITICAL: leaf cert "*.badssl.com" expired 2299d 12h ago (on 2015-04-12 23:59:59 +0000 UTC) [EXPIRED: 2, EXPIRING: 0, OK: 1]
**ERRORS**
* 2 certificates expired or expiring
**THRESHOLDS**
* CRITICAL: Expires before 2021-08-13 12:02:16 +0000 UTC (15 days)
* WARNING: Expires before 2021-08-28 12:02:16 +0000 UTC (30 days)
**DETAILED INFO**
Certificate 1 of 3 (leaf):
Name: CN=*.badssl.com,OU=Domain Control Validated+OU=PositiveSSL Wildcard
SANs entries: [*.badssl.com badssl.com]
Issuer: CN=COMODO RSA Domain Validation Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
Serial: 4A:E7:95:49:FA:9A:BE:3F:10:0F:17:A4:78:E1:69:09
Issued On: 2015-04-09 00:00:00 +0000 UTC
Expiration: 2015-04-12 23:59:59 +0000 UTC
Status: [EXPIRED] 2299d 12h ago
Certificate 2 of 3 (intermediate):
Name: CN=COMODO RSA Domain Validation Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
SANs entries: []
Issuer: CN=COMODO RSA Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
Serial: 2B:2E:6E:EA:D9:75:36:6C:14:8A:6E:DB:A3:7C:8C:07
Issued On: 2014-02-12 00:00:00 +0000 UTC
Expiration: 2029-02-11 23:59:59 +0000 UTC
Status: [OK] 2754d 11h remaining
Certificate 3 of 3 (intermediate):
Name: CN=COMODO RSA Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
SANs entries: []
Issuer: CN=AddTrust External CA Root,OU=AddTrust External TTP Network,O=AddTrust AB,C=SE
Serial: 27:66:EE:56:EB:49:F3:8E:AB:D7:70:A2:FC:84:DE:22
Issued On: 2000-05-30 10:48:38 +0000 UTC
Expiration: 2020-05-30 10:48:38 +0000 UTC
Status: [EXPIRED] 425d 1h ago
lscert CLI工具
确定结果
这个例子显示了使用CLI应用程序来执行与我们
之前使用Nagios插件进行的
相同的初始检查
。
注意:使用--verbose 标志来揭示进一步的细节。
$ ./lscert --server www.google.com --port 443 --age-critical 50 --age-warning 55
Connecting to remote server "www.google.com" at port 443
=============================
CERTIFICATES | AGE THRESHOLDS
=============================
- WARNING: Expires before 2020-08-30 11:12:01 +0000 UTC (55 days)
- CRITICAL: Expires before 2020-08-25 11:12:01 +0000 UTC (50 days)
======================
CERTIFICATES | SUMMARY
======================
- OK: 2 certs found for service running on www.google.com at port 443
- OK: Provided hostname matches discovered certificate
- OK: leaf cert "www.google.com" expires next with 65d 3h remaining (until 2020-09-09 14:31:22 +0000 UTC)
- OK: [EXPIRED: 0, EXPIRING: 0, OK: 2]
============================
CERTIFICATES | CHAIN DETAILS
============================
Certificate 1 of 2 (leaf):
Name: CN=www.google.com,O=Google LLC,L=Mountain View,ST=California,C=US
SANs entries: [www.google.com]
Issuer: CN=GTS CA 1O1,O=Google Trust Services,C=US
Serial: FD:6F:3E:24:98:C2:5B:1D:08:00:00:00:00:47:F0:33
Expiration: 2020-09-09 14:31:22 +0000 UTC
Status: [OK] 65d 3h remaining
Certificate 2 of 2 (intermediate):
Name: CN=GTS CA 1O1,O=Google Trust Services,C=US
SANs entries: []
Issuer: CN=GlobalSign,OU=GlobalSign Root CA - R2,O=GlobalSign
Serial: 01:E3:B4:9A:A1:8D:8A:A9:81:25:69:50:B8
Expiration: 2021-12-15 00:00:42 +0000 UTC
Status: [OK] 526d 12h remaining
警告的结果
注意:使用--verbose 标志来揭示进一步的细节。
$ ./lscert --server www.google.com --port 443 --age-critical 50 --age-warning 66
Connecting to remote server "www.google.com" at port 443
=============================
CERTIFICATES | AGE THRESHOLDS
=============================
- WARNING: Expires before 2020-09-10 11:13:11 +0000 UTC (66 days)
- CRITICAL: Expires before 2020-08-25 11:13:11 +0000 UTC (50 days)
======================
CERTIFICATES | SUMMARY
======================
- OK: 2 certs found for service running on www.google.com at port 443
- OK: Provided hostname matches discovered certificate
- WARNING: leaf cert "www.google.com" expires next with 65d 3h remaining (until 2020-09-09 14:31:22 +0000 UTC)
- WARNING: [EXPIRED: 0, EXPIRING: 1, OK: 1]
============================
CERTIFICATES | CHAIN DETAILS
============================
Certificate 1 of 2 (leaf):
Name: CN=www.google.com,O=Google LLC,L=Mountain View,ST=California,C=US
SANs entries: [www.google.com]
Issuer: CN=GTS CA 1O1,O=Google Trust Services,C=US
Serial: FD:6F:3E:24:98:C2:5B:1D:08:00:00:00:00:47:F0:33
Expiration: 2020-09-09 14:31:22 +0000 UTC
Status: [WARNING] 65d 3h remaining
Certificate 2 of 2 (intermediate):
Name: CN=GTS CA 1O1,O=Google Trust Services,C=US
SANs entries: []
Issuer: CN=GlobalSign,OU=GlobalSign Root CA - R2,O=GlobalSign
Serial: 01:E3:B4:9A:A1:8D:8A:A9:81:25:69:50:B8
Expiration: 2021-12-15 00:00:42 +0000 UTC
Status: [OK] 526d 12h remaining
一般来说,这两个
工具
的OK 和WARNING 输出之间的差异
很小。然而,与check_cert Nagios插件不同的是,我们被
限制在一行摘要输出,lscert CLI工具没有
相同的输出要求,可以有更多的表现力(例如,如摘要
部分,以突出特定的兴趣项目)。与check_cert
Nagios插件一样
,lscert CLI工具也显示用于
确定应用于证书链的检查状态
的
阈值
。
重要的结果
这里我们使用expired.badssl.com子域来演示
在一个链中遇到一个或多个(在本例中是多个)过期证书
的结果
。
除了FQDN外,所有默认选项(包括端口)都被使用。
注意:使用--verbose 标志来显示进一步的细节。
$ ./lscert --server expired.badssl.com
Connecting to remote server "expired.badssl.com" at port 443
=============================
CERTIFICATES | AGE THRESHOLDS
=============================
- WARNING: Expires before 2020-08-05 11:14:32 +0000 UTC (30 days)
- CRITICAL: Expires before 2020-07-21 11:14:32 +0000 UTC (15 days)
======================
CERTIFICATES | SUMMARY
======================
- OK: 3 certs found for service running on expired.badssl.com at port 443
- OK: Provided hostname matches discovered certificate
- CRITICAL: leaf cert "*.badssl.com" expired 1911d 11h ago (on 2015-04-12 23:59:59 +0000 UTC)
- CRITICAL: [EXPIRED: 2, EXPIRING: 0, OK: 1]
============================
CERTIFICATES | CHAIN DETAILS
============================
Certificate 1 of 3 (leaf):
Name: CN=*.badssl.com,OU=Domain Control Validated+OU=PositiveSSL Wildcard
SANs entries: [*.badssl.com badssl.com]
Issuer: CN=COMODO RSA Domain Validation Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
Serial: 4A:E7:95:49:FA:9A:BE:3F:10:0F:17:A4:78:E1:69:09
Expiration: 2015-04-12 23:59:59 +0000 UTC
Status: [EXPIRED] 1911d 11h ago
Certificate 2 of 3 (intermediate):
Name: CN=COMODO RSA Domain Validation Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
SANs entries: []
Issuer: CN=COMODO RSA Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
Serial: 2B:2E:6E:EA:D9:75:36:6C:14:8A:6E:DB:A3:7C:8C:07
Expiration: 2029-02-11 23:59:59 +0000 UTC
Status: [OK] 3142d 12h remaining
Certificate 3 of 3 (intermediate):
Name: CN=COMODO RSA Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
SANs entries: []
Issuer: CN=AddTrust External CA Root,OU=AddTrust External TTP Network,O=AddTrust AB,C=SE
Serial: 27:66:EE:56:EB:49:F3:8E:AB:D7:70:A2:FC:84:DE:22
Expiration: 2020-05-30 10:48:38 +0000 UTC
Status: [EXPIRED] 37d 0h ago
CERTIFICATES | SUMMARY 部分中的一些项目需要注意。
-
列出了首先过期的证书(叶子证书
*.badssl.com)。- 链的位置
- 过期概要
- 过期日期
-
快速统计
EXPIRED,EXPIRING和OK的证书。 -
未来的工作可能会列出所有过期的证书,但假设
列出第一个过期的证书,然后
在下一节列出链的
细节(明确指出过期
状态)就足够了。
fixsn CLI工具
无效输入
$ ./fixsn badinput
Error: Invalid serial number (in base 10 format)
Example expected input: 336872288293767042001244177974291853363
预期的输入
$ ./fixsn 336872288293767042001244177974291853363
FD:6F:3E:24:98:C2:5B:1D:08:00:00:00:00:47:F0:33
certsum CLI工具
该工具处于早期开发阶段,
在未来的版本中,
可用的选项可能会发生变化
(甚至可能是重大变化)。
请参阅本
README
前面记录的可用标志/选项的列表
,以了解更多选项。
证书概述
以下选项为每台
有证书的
主机生成一个单行的高级概述
。没有证书的主机将从结果中省略。
$ ./certsum --hosts 192.168.5.0/24 --show-hosts-with-valid-certs --show-overview
Beginning cert scan against 254 unique hosts using ports: [443]
...................
Completed certificates scan in 2.3670248s
19 certificates (8 issues) found.
Results (all):
IP Address Port Subject or SANs Status Chain Summary Serial
--- --- --- --- --- ---
192.168.5.22 443 VMware ⛔ (!!) [EXPIRED: 1, EXPIRING: 0, OK: 0] 92:4A:AD:38:3C:DC:C1:B6
192.168.5.3 443 VMware ⛔ (!!) [EXPIRED: 1, EXPIRING: 0, OK: 0] DE:FD:50:2B:C5:7F:79:F4
192.168.5.24 443 VMware ✅ (OK) [EXPIRED: 0, EXPIRING: 0, OK: 1] 9A:DF:A1:A6:60:16:4E:C0
192.168.5.11 443 VMware ⛔ (!!) [EXPIRED: 1, EXPIRING: 0, OK: 0] 8D:2C:61:CF:AE:57:58:98
192.168.5.83 443 HP Jetdirect 4639304E ⛔ (!!) [EXPIRED: 1, EXPIRING: 0, OK: 0] 47:F0:56:50
192.168.5.109 443 HP LaserJet M506 F2A68A ⛔ (!!) [EXPIRED: 1, EXPIRING: 0, OK: 0] -29:25:F5:A8:D5:E2:FC:C3:71:77:F4:48:3A:09:2E:24:0F:0E:37:1A
192.168.5.93 443 NPI25BC25 ✅ (OK) [EXPIRED: 0, EXPIRING: 0, OK: 1] -61:CE:BD:13
192.168.5.113 443 NPI253CDE ✅ (OK) [EXPIRED: 0, EXPIRING: 0, OK: 1] 38:BC:BD:21
192.168.5.136 443 HP Jetdirect BAC74492 ✅ (OK) [EXPIRED: 0, EXPIRING: 0, OK: 1] 20:46:94:C0
192.168.5.104 443 HP Jetdirect 7FE7AF22 ⛔ (!!) [EXPIRED: 1, EXPIRING: 0, OK: 0] 02
192.168.5.165 443 192.168.5.165 ⛔ (!!) [EXPIRED: 1, EXPIRING: 0, OK: 0] EF:E5:A3:0E:2F:FA:C1:3A
192.168.5.183 443 192.168.5.183 ⛔ (!!) [EXPIRED: 1, EXPIRING: 0, OK: 0] F7:A2:CD:4A:F2:A0:63:10
192.168.5.182 443 192.168.5.182 ✅ (OK) [EXPIRED: 0, EXPIRING: 0, OK: 1] AC:53:68:BB:38:5E:5A:6C
192.168.5.105 443 192.168.5.105 ✅ (OK) [EXPIRED: 0, EXPIRING: 0, OK: 1] 64:36:33:33:32:36:37:38:30:31:64:66:37:31:31:62:32:62:37:63
值得注意的是。
- 隐含地使用默认端口为
443/tcp - 扫描整个
192.168.5.0/24范围 - 以概览或摘要格式生成输出
- 显示 "OK "的主机和有问题的主机(为简洁起见通常省略)。
CIDR范围
$ ./certsum --ports 443 --hosts 192.168.5.0/24
Total IPs from all ranges before deduping: 254
Total IPs from all ranges after deduping: 254
Beginning scan of ports: [443]
Completed port scan
Beginning certificate analysis
..........................
Completed certificate analysis
Results:
IP Address Port Subject or SANs Status (Type) Summary Serial
--- --- --- --- --- ---
192.168.5.104 443 HP Jetdirect 7FE7AF22 ⛔ (leaf; self-signed) [EXPIRED] 3942d 12h ago 02
192.168.5.3 443 VMware ⛔ (root) [EXPIRED] 571d 23h ago DE:FD:50:2B:C5:7F:79:F4
192.168.5.109 443 HP LaserJet M506 F2A68A ⛔ (leaf; self-signed) [CRITICAL] 1d 7h remaining -29:25:F5:A8:D5:E2:FC:C3:71:77:F4:48:3A:09:2E:24:0F:0E:37:1A
192.168.5.83 443 HP Jetdirect 4639304E ⛔ (leaf; self-signed) [EXPIRED] 2175d 12h ago 47:F0:56:50
192.168.5.165 443 192.168.5.165 ⛔ (leaf; self-signed) [EXPIRED] 1519d 7h ago EF:E5:A3:0E:2F:FA:C1:3A
192.168.5.183 443 192.168.5.183 ⛔ (leaf; self-signed) [EXPIRED] 1034d 19h ago F7:A2:CD:4A:F2:A0:63:10
值得注意的是
- 明确指定端口
443/tcp(默认)。 - 扫描整个
192.168.5.0/24范围 - 只发出 "问题 "条目
部分范围
这里我们指定一个部分范围,使用的语法有意类似于
nmap(一个
了不起的工具)
所接受的基于八位数的寻址语法
。
目前
不
支持
八位数内的逗号(为了排除IP)
。
$ ./certsum --ports 443 --hosts 192.168.5.104-110
Total IPs from all ranges before deduping: 6
Total IPs from all ranges after deduping: 6
Beginning scan of ports: [443]
Completed port scan
Beginning certificate analysis
..........................
Completed certificate analysis
Results:
IP Address Port Subject or SANs Status (Type) Summary Serial
--- --- --- --- --- ---
192.168.5.104 443 HP Jetdirect 7FE7AF22 ⛔ (leaf; self-signed) [EXPIRED] 3942d 12h ago 02
192.168.5.109 443 HP LaserJet M506 F2A68A ⛔ (leaf; self-signed) [CRITICAL] 1d 7h remaining -29:25:F5:A8:D5:E2:FC:C3:71:77:F4:48:3A:09:2E:24:0F:0E:37:1A
部分范围和单一IP地址
$ ./certsum --ports 443 --hosts 192.168.5.3,192.168.5.104-110
Total IPs from all ranges before deduping: 7
Total IPs from all ranges after deduping: 7
Beginning scan of ports: [443]
Completed port scan
Beginning certificate analysis
..........................
Completed certificate analysis
Results:
IP Address Port Subject or SANs Status (Type) Summary Serial
--- --- --- --- --- ---
192.168.5.3 443 VMware ⛔ (root) [EXPIRED] 577d 0h ago DE:FD:50:2B:C5:7F:79:F4
192.168.5.104 443 HP Jetdirect 7FE7AF22 ⛔ (leaf; self-signed) [EXPIRED] 3942d 12h ago 02
192.168.5.109 443 HP LaserJet M506 F2A68A ⛔ (leaf; self-signed) [CRITICAL] 1d 7h remaining -29:25:F5:A8:D5:E2:FC:C3:71:77:F4:48:3A:09:2E:24:0F:0E:37:1A
部分范围、CIDR范围和一个单一的IP地址
$ ./certsum --ports 443 --hosts 192.168.5.3,192.168.5.104-110,192.168.2.0/24
Total IPs from all ranges before deduping: 260
Total IPs from all ranges after deduping: 260
Beginning scan of ports: [443]
Completed port scan
Beginning certificate analysis
...............................................................
由于输出结果与其他
例子
密切相关,因此只包括引言文本。
单个IP地址和一个FQDN
值得注意的是
- 默认的HTTPS端口(因为我们没有指定一个)。
- 我们正在使用一个FQDN
$ ./certsum --hosts 192.168.5.3,expired.badssl.com
Total IPs from all ranges before deduping: 2
Total IPs from all ranges after deduping: 2
Beginning scan of ports: [443]
Completed port scan
Beginning certificate analysis
..
Completed certificate analysis
Results:
IP Address Port Subject or SANs Status (Type) Summary Serial
--- --- --- --- --- ---
192.168.5.3 443 VMware ⛔ (root) [EXPIRED] 577d 0h ago DE:FD:50:2B:C5:7F:79:F4
104.154.89.105 443 badssl-fallback-unknown-subdomain-or-no-sni ⛔ (leaf) [EXPIRED] 865d 13h ago CD:BC:5A:4A:EC:97:67:B1
显示所有的扫描结果
我们包括一个额外的没有证书的扫描目标,以说明
默认扫描结果通常会被静音/隐藏起来。
$ ./certsum --hosts 192.168.5.3,expired.badssl.com,scanme.nmap.org --show-valid-certs --show-port-scan-results --show-hosts-with-valid-certs --show-closed-ports
Total IPs from all ranges before deduping: 4
Total IPs from all ranges after deduping: 4
Beginning scan of ports: [443]
Completed port scan
Beginning certificate analysis
192.168.5.3: [443: true]
104.154.89.105: [443: true]
45.33.32.156: [None]
2600:3c01::f03c:91ff:fe18:bb2f: [None]
Completed certificate analysis
Results:
IP Address Port Subject or SANs Status (Type) Summary Serial
--- --- --- --- --- ---
192.168.5.3 443 VMware ⛔ (root) [EXPIRED] 577d 21h ago DE:FD:50:2B:C5:7F:79:F4
104.154.89.105 443 badssl-fallback-unknown-subdomain-or-no-sni ⛔ (leaf) [EXPIRED] 865d 13h ago CD:BC:5A:4A:EC:97:67:B1
许可证
MIT License
Copyright (c) 2020 Adam Chalkley
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.