sensu-plugins-ssl 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -1
- data/README.md +22 -2
- data/bin/check-java-keystore-cert.rb +87 -0
- data/bin/check-ssl-crl.rb +76 -0
- data/bin/check-ssl-host.rb +40 -6
- data/bin/check-ssl-qualys.rb +10 -2
- data/lib/sensu-plugins-ssl/version.rb +1 -1
- metadata +22 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad7f900ae9946ad4bb040d4e7968761847ca38f6
|
4
|
+
data.tar.gz: f7485dfc07f15d1789ef4000455a60e3b32c78d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c2a81176f56ca91455c54ffa18e62f34e26d9fb1cc29cbdd53e9fa421aa5e7552f251e799fd4191ff806dbe228e3b29b9261d7a3bd4f76b449b89f4a544d405
|
7
|
+
data.tar.gz: 17e6353a089229402fb90abc4a2729a0221e43f4fd820aa3b402d32da60318e1c9e8207a18cdaf870c170ddc1258b432c0f7aefd114a6de607adc0a203dc962f
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,20 @@ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachang
|
|
5
5
|
|
6
6
|
## [Unreleased]
|
7
7
|
|
8
|
+
## [1.1.0] - 2017-02-28
|
9
|
+
### Added
|
10
|
+
- `check-ssl-host.rb`: Add optional `address` command line parameter for specifying the address of the server to
|
11
|
+
connect to, to override the `hostname` parameter (which is still used for verification/SNI) (@advance512)
|
12
|
+
- `check-ssl-host.rb`: Better error message when unable to connect to target host (@johntdyer)
|
13
|
+
- `check-ssl-host.rb`: Add support for client certificates (@modax)
|
14
|
+
- `check-ssl-host.rb`: Add basic IMAP STARTTLS negotiation (@lobeck)
|
15
|
+
- `check-java-keystore-cert.rb`: Add new check to verify a certificate in a Java Keystore has not expired. (@joerayme)
|
16
|
+
- `check-ssl-crl.rb`: Add check for expiring CRL (@shoekstra)
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
- `check-ssl-qualys.rb`: Handle API errors with status unknown instead of unhandled "Check failed to run". (@11mariom)
|
20
|
+
- `check-ssl-qualys.rb`: Handle nil grade_rank as critical not rated (@11mariom)
|
21
|
+
|
8
22
|
## [1.0.0]
|
9
23
|
### Changed
|
10
24
|
- Updated Rubocop to 0.40, applied auto-correct
|
@@ -47,7 +61,8 @@ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachang
|
|
47
61
|
### Added
|
48
62
|
- initial release
|
49
63
|
|
50
|
-
[unreleased]: https://github.com/sensu-plugins/sensu-plugins-ssl/compare/1.
|
64
|
+
[unreleased]: https://github.com/sensu-plugins/sensu-plugins-ssl/compare/1.1.0...HEAD
|
65
|
+
[1.1.0]: https://github.com/sensu-plugins/sensu-plugins-ssl/compare/1.0.0...1.1.0
|
51
66
|
[1.0.0]: https://github.com/sensu-plugins/sensu-plugins-ssl/compare/0.0.6...1.0.0
|
52
67
|
[0.0.6]: https://github.com/sensu-plugins/sensu-plugins-ssl/compare/0.0.5...0.0.6
|
53
68
|
[0.0.5]: https://github.com/sensu-plugins/sensu-plugins-ssl/compare/0.0.4...0.0.5
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
## Sensu-Plugins-
|
1
|
+
## Sensu-Plugins-SSL
|
2
2
|
|
3
|
-
[
|
3
|
+
[](https://travis-ci.org/sensu-plugins/sensu-plugins-ssl)
|
4
4
|
[](http://badge.fury.io/rb/sensu-plugins-ssl)
|
5
5
|
[](https://codeclimate.com/github/sensu-plugins/sensu-plugins-ssl)
|
6
6
|
[](https://codeclimate.com/github/sensu-plugins/sensu-plugins-ssl)
|
@@ -9,12 +9,32 @@
|
|
9
9
|
## Functionality
|
10
10
|
|
11
11
|
## Files
|
12
|
+
* bin/check-java-keystore-cert.rb
|
13
|
+
* bin/check-ssl-crl.rb
|
12
14
|
* bin/check-ssl-cert.rb
|
13
15
|
* bin/check-ssl-host.rb
|
14
16
|
* bin/check-ssl-qualys.rb
|
15
17
|
|
16
18
|
## Usage
|
17
19
|
|
20
|
+
### `bin/check-ssl-crl.rb`
|
21
|
+
|
22
|
+
Checks a CRL has not or is not expiring by inspecting it's next update value.
|
23
|
+
|
24
|
+
You can check against a CRL file on disk:
|
25
|
+
|
26
|
+
```
|
27
|
+
./bin/check-ssl-crl -c 300 -w 600 -u /path/to/crl
|
28
|
+
```
|
29
|
+
|
30
|
+
or an online CRL:
|
31
|
+
|
32
|
+
```
|
33
|
+
./bin/check-ssl-crl -c 300 -w 600 -u http://www.website.com/file.crl
|
34
|
+
```
|
35
|
+
|
36
|
+
Critical and Warning thresholds are specified in minutes.
|
37
|
+
|
18
38
|
## Installation
|
19
39
|
|
20
40
|
[Installation and Setup](http://sensu-plugins.io/docs/installation_instructions.html)
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-java-keystore-cert
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# Check when a certificate stored in a Java Keystore will expire
|
7
|
+
#
|
8
|
+
# OUTPUT:
|
9
|
+
# plain text
|
10
|
+
#
|
11
|
+
# PLATFORMS:
|
12
|
+
# Linux
|
13
|
+
#
|
14
|
+
# DEPENDENCIES:
|
15
|
+
# gem: sensu-plugin
|
16
|
+
#
|
17
|
+
# USAGE:
|
18
|
+
# example commands
|
19
|
+
#
|
20
|
+
# NOTES:
|
21
|
+
# Does it behave differently on specific platforms, specific use cases, etc
|
22
|
+
#
|
23
|
+
|
24
|
+
require 'date'
|
25
|
+
require 'sensu-plugin/check/cli'
|
26
|
+
|
27
|
+
class CheckJavaKeystoreCert < Sensu::Plugin::Check::CLI
|
28
|
+
option :path,
|
29
|
+
long: '--path PATH',
|
30
|
+
description: '',
|
31
|
+
required: true
|
32
|
+
|
33
|
+
option :alias,
|
34
|
+
long: '--alias ALIAS',
|
35
|
+
description: '',
|
36
|
+
required: true
|
37
|
+
|
38
|
+
option :password,
|
39
|
+
long: '--password PASSWORD',
|
40
|
+
description: '',
|
41
|
+
required: true
|
42
|
+
|
43
|
+
option :warning,
|
44
|
+
long: '--warning DAYS',
|
45
|
+
description: '',
|
46
|
+
proc: proc { |v| v.to_i },
|
47
|
+
required: true
|
48
|
+
|
49
|
+
option :critical,
|
50
|
+
long: '--critical DAYS',
|
51
|
+
description: '',
|
52
|
+
proc: proc { |v| v.to_i },
|
53
|
+
required: true
|
54
|
+
|
55
|
+
def certificate_expiration_date
|
56
|
+
result = `keytool -keystore #{config[:path]} \
|
57
|
+
-export -alias #{config[:alias]} \
|
58
|
+
-storepass #{config[:password]} 2>&1 | \
|
59
|
+
openssl x509 -enddate -inform der -noout 2>&1`
|
60
|
+
|
61
|
+
# rubocop:disable Style/SpecialGlobalVars
|
62
|
+
unknown 'could not get certificate from keystore' unless $?.success?
|
63
|
+
# rubocop:enable Style/SpecialGlobalVars
|
64
|
+
|
65
|
+
Date.parse(result.split('=').last)
|
66
|
+
end
|
67
|
+
|
68
|
+
def validate_opts
|
69
|
+
unknown 'warning cannot be less than critical' if config[:warning] < config[:critical]
|
70
|
+
end
|
71
|
+
|
72
|
+
def run
|
73
|
+
validate_opts
|
74
|
+
|
75
|
+
days_until = (certificate_expiration_date - Date.today).to_i
|
76
|
+
|
77
|
+
if days_until < 0
|
78
|
+
critical "Expired #{days_until.abs} days ago"
|
79
|
+
elsif days_until < config[:critical]
|
80
|
+
critical "#{days_until} days left"
|
81
|
+
elsif days_until < config[:warning]
|
82
|
+
warning "#{days_until} days left"
|
83
|
+
end
|
84
|
+
|
85
|
+
ok "#{days_until} days left"
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-ssl-crl
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# Check in minutes when a certificate revocation list will expire.
|
7
|
+
#
|
8
|
+
# OUTPUT:
|
9
|
+
# plain text
|
10
|
+
#
|
11
|
+
# PLATFORMS:
|
12
|
+
# Linux
|
13
|
+
#
|
14
|
+
# DEPENDENCIES:
|
15
|
+
# gem: sensu-plugin
|
16
|
+
#
|
17
|
+
# USAGE:
|
18
|
+
# ./check-ssl-crl -c 300 -w 600 -u /path/to/crl
|
19
|
+
# ./check-ssl-crl -c 300 -w 600 -u http://www.website.com/file.crl
|
20
|
+
#
|
21
|
+
# LICENSE:
|
22
|
+
# Stephen Hoekstra <shoekstra@schubergphilis.com>
|
23
|
+
#
|
24
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
25
|
+
# for details.
|
26
|
+
#
|
27
|
+
|
28
|
+
require 'open-uri'
|
29
|
+
require 'openssl'
|
30
|
+
require 'sensu-plugin/check/cli'
|
31
|
+
require 'time'
|
32
|
+
|
33
|
+
#
|
34
|
+
# Check SSL Cert
|
35
|
+
#
|
36
|
+
class CheckSSLCRL < Sensu::Plugin::Check::CLI
|
37
|
+
option :critical,
|
38
|
+
description: 'Numbers of minutes left',
|
39
|
+
short: '-c',
|
40
|
+
long: '--critical MINUTES',
|
41
|
+
proc: proc { |v| v.to_i },
|
42
|
+
required: true
|
43
|
+
|
44
|
+
option :url,
|
45
|
+
description: 'URL (or path) to CRL file',
|
46
|
+
short: '-u',
|
47
|
+
long: '--url URL',
|
48
|
+
required: true
|
49
|
+
|
50
|
+
option :warning,
|
51
|
+
description: 'Numbers of minutes left',
|
52
|
+
short: '-w',
|
53
|
+
long: '--warning MINUTES',
|
54
|
+
proc: proc { |v| v.to_i },
|
55
|
+
required: true
|
56
|
+
|
57
|
+
def seconds_to_minutes(seconds)
|
58
|
+
(seconds / 60).to_i
|
59
|
+
end
|
60
|
+
|
61
|
+
def validate_opts
|
62
|
+
unknown 'warning cannot be less than critical' if config[:warning] < config[:critical]
|
63
|
+
end
|
64
|
+
|
65
|
+
def run
|
66
|
+
validate_opts
|
67
|
+
|
68
|
+
next_update = OpenSSL::X509::CRL.new(open(config[:url]).read).next_update
|
69
|
+
minutes_until = seconds_to_minutes(Time.parse(next_update.to_s) - Time.now)
|
70
|
+
|
71
|
+
critical "#{config[:url]} - Expired #{minutes_until.abs} minutes ago" if minutes_until < 0
|
72
|
+
critical "#{config[:url]} - #{minutes_until} minutes left, next update at #{next_update}" if minutes_until < config[:critical].to_i
|
73
|
+
warning "#{config[:url]} - #{minutes_until} minutes left, next update at #{next_update}" if minutes_until < config[:warning].to_i
|
74
|
+
ok "#{config[:url]} - #{minutes_until} minutes left, next update at #{next_update}"
|
75
|
+
end
|
76
|
+
end
|
data/bin/check-ssl-host.rb
CHANGED
@@ -42,7 +42,7 @@ require 'socket'
|
|
42
42
|
# Check SSL Host
|
43
43
|
#
|
44
44
|
class CheckSSLHost < Sensu::Plugin::Check::CLI
|
45
|
-
STARTTLS_PROTOS = %w(smtp).freeze
|
45
|
+
STARTTLS_PROTOS = %w(smtp imap).freeze
|
46
46
|
|
47
47
|
check_name 'check_ssl_host'
|
48
48
|
|
@@ -62,7 +62,8 @@ class CheckSSLHost < Sensu::Plugin::Check::CLI
|
|
62
62
|
default: 14
|
63
63
|
|
64
64
|
option :host,
|
65
|
-
description: 'Hostname of server to check'
|
65
|
+
description: 'Hostname of the server certificate to check, by default used as the server address if none ' \
|
66
|
+
'is given',
|
66
67
|
short: '-h',
|
67
68
|
long: '--host HOST',
|
68
69
|
required: true
|
@@ -73,6 +74,20 @@ class CheckSSLHost < Sensu::Plugin::Check::CLI
|
|
73
74
|
long: '--port PORT',
|
74
75
|
default: 443
|
75
76
|
|
77
|
+
option :address,
|
78
|
+
description: 'Address of server to check. This is used instead of the host argument for the TCP connection, ' \
|
79
|
+
'however the server hostname is still used for the TLS/SSL context.',
|
80
|
+
short: '-a',
|
81
|
+
long: '--address ADDRESS'
|
82
|
+
|
83
|
+
option :client_cert,
|
84
|
+
description: 'Path to the client certificate in DER/PEM format',
|
85
|
+
long: '--client-cert CERT'
|
86
|
+
|
87
|
+
option :client_key,
|
88
|
+
description: 'Path to the client RSA key in DER/PEM format',
|
89
|
+
long: '--client-key KEY'
|
90
|
+
|
76
91
|
option :skip_hostname_verification,
|
77
92
|
description: 'Disables hostname verification',
|
78
93
|
long: '--skip-hostname-verification',
|
@@ -88,13 +103,18 @@ class CheckSSLHost < Sensu::Plugin::Check::CLI
|
|
88
103
|
"(#{STARTTLS_PROTOS.join(', ')})",
|
89
104
|
long: '--starttls PROTO'
|
90
105
|
|
91
|
-
def get_cert_chain(host, port)
|
92
|
-
tcp_client = TCPSocket.new(host, port)
|
106
|
+
def get_cert_chain(host, port, address, client_cert, client_key)
|
107
|
+
tcp_client = TCPSocket.new(address ? address : host, port)
|
93
108
|
handle_starttls(config[:starttls], tcp_client) if config[:starttls]
|
94
109
|
ssl_context = OpenSSL::SSL::SSLContext.new
|
110
|
+
ssl_context.cert = OpenSSL::X509::Certificate.new File.read(client_cert) if client_cert
|
111
|
+
ssl_context.key = OpenSSL::PKey::RSA.new File.read(client_key) if client_key
|
95
112
|
ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_client, ssl_context)
|
96
|
-
|
113
|
+
|
114
|
+
# If the OpenSSL version in use supports Server Name Indication (SNI, RFC 3546), then we set the hostname we
|
115
|
+
# received to request that certificate.
|
97
116
|
ssl_client.hostname = host if ssl_client.respond_to? :hostname=
|
117
|
+
|
98
118
|
ssl_client.connect
|
99
119
|
certs = ssl_client.peer_cert_chain
|
100
120
|
ssl_client.close
|
@@ -122,6 +142,18 @@ class CheckSSLHost < Sensu::Plugin::Check::CLI
|
|
122
142
|
critical "#{config[:host]} - did not receive SMTP 220 in response to STARTTLS"
|
123
143
|
end
|
124
144
|
|
145
|
+
def starttls_imap(socket)
|
146
|
+
status = socket.readline
|
147
|
+
unless /^* OK / =~ status
|
148
|
+
critical "#{config[:host]} - did not receive initial * OK"
|
149
|
+
end
|
150
|
+
socket.puts 'a001 STARTTLS'
|
151
|
+
|
152
|
+
status = socket.readline
|
153
|
+
return if /^a001 OK Begin TLS negotiation now/ =~ status
|
154
|
+
critical "#{config[:host]} - did not receive OK Begin TLS negotiation now"
|
155
|
+
end
|
156
|
+
|
125
157
|
def verify_expiry(cert)
|
126
158
|
# Expiry check
|
127
159
|
days = (cert.not_after.to_date - Date.today).to_i
|
@@ -154,9 +186,11 @@ class CheckSSLHost < Sensu::Plugin::Check::CLI
|
|
154
186
|
end
|
155
187
|
|
156
188
|
def run
|
157
|
-
chain = get_cert_chain(config[:host], config[:port])
|
189
|
+
chain = get_cert_chain(config[:host], config[:port], config[:address], config[:client_cert], config[:client_key])
|
158
190
|
verify_hostname(chain[0]) unless config[:skip_hostname_verification]
|
159
191
|
verify_certificate_chain(chain) unless config[:skip_chain_verification]
|
160
192
|
verify_expiry(chain[0])
|
193
|
+
rescue Errno::ECONNRESET => e
|
194
|
+
critical "#{e.class} - #{e.message}"
|
161
195
|
end
|
162
196
|
end
|
data/bin/check-ssl-qualys.rb
CHANGED
@@ -90,8 +90,12 @@ class CheckSSLQualys < Sensu::Plugin::Check::CLI
|
|
90
90
|
def ssl_api_request(from_cache)
|
91
91
|
params = { host: config[:domain] }
|
92
92
|
params[:startNew] = 'on' unless from_cache
|
93
|
-
|
94
|
-
|
93
|
+
begin
|
94
|
+
r = RestClient.get("#{config[:api_url]}analyze", params: params)
|
95
|
+
warning "HTTP#{r.code} recieved from API" unless r.code == 200
|
96
|
+
rescue RestClient::ExceptionWithResponse => e
|
97
|
+
unknown e.response
|
98
|
+
end
|
95
99
|
JSON.parse(r.body)
|
96
100
|
end
|
97
101
|
|
@@ -122,6 +126,10 @@ class CheckSSLQualys < Sensu::Plugin::Check::CLI
|
|
122
126
|
|
123
127
|
def run
|
124
128
|
grade = lowest_grade
|
129
|
+
unless grade
|
130
|
+
message "#{config[:domain]} not rated"
|
131
|
+
critical
|
132
|
+
end
|
125
133
|
message "#{config[:domain]} rated #{grade}"
|
126
134
|
grade_rank = GRADE_OPTIONS.index(grade)
|
127
135
|
if grade_rank > config[:critical]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu-plugins-ssl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sensu-Plugins and contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sensu-plugin
|
@@ -164,13 +164,29 @@ dependencies:
|
|
164
164
|
- - "~>"
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0.8'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: timecop
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 0.8.0
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 0.8.0
|
167
181
|
description: |-
|
168
182
|
This plugin provides native SSL instrumentation
|
169
183
|
for monitoring, including: hostname and chain
|
170
|
-
verification, cert expiry, and Qualys SSL Labs reporting
|
184
|
+
verification, cert and crl expiry, and Qualys SSL Labs reporting
|
171
185
|
email: "<sensu-users@googlegroups.com>"
|
172
186
|
executables:
|
187
|
+
- check-java-keystore-cert.rb
|
173
188
|
- check-ssl-cert.rb
|
189
|
+
- check-ssl-crl.rb
|
174
190
|
- check-ssl-host.rb
|
175
191
|
- check-ssl-qualys.rb
|
176
192
|
extensions: []
|
@@ -179,7 +195,9 @@ files:
|
|
179
195
|
- CHANGELOG.md
|
180
196
|
- LICENSE
|
181
197
|
- README.md
|
198
|
+
- bin/check-java-keystore-cert.rb
|
182
199
|
- bin/check-ssl-cert.rb
|
200
|
+
- bin/check-ssl-crl.rb
|
183
201
|
- bin/check-ssl-host.rb
|
184
202
|
- bin/check-ssl-qualys.rb
|
185
203
|
- lib/sensu-plugins-ssl.rb
|
@@ -210,9 +228,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
210
228
|
version: '0'
|
211
229
|
requirements: []
|
212
230
|
rubyforge_project:
|
213
|
-
rubygems_version: 2.5
|
231
|
+
rubygems_version: 2.4.5
|
214
232
|
signing_key:
|
215
233
|
specification_version: 4
|
216
234
|
summary: Sensu plugins for SSL
|
217
235
|
test_files: []
|
218
|
-
has_rdoc:
|