sensu-plugins-ssl-boutetnico 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 16378e5222efd774d58d33c47dfa46facac0b2cd
4
+ data.tar.gz: 55dd9684c413e0b36ed44e6a89e83a571a0742d3
5
+ SHA512:
6
+ metadata.gz: cebae6d1239bcae312147ce8f4df7acc5bb01698c39da3a4f5ff351031fde0ab2e0fe16f54a49d980db5d80731f8a1020a64a74ce0a230b8283a17323ac5f53a
7
+ data.tar.gz: f1f9c483b7dc9e4769651de62277b2abaa9d6b1571cdf6f5cf2469acab557746bd344832ad8c2aaecdc654ae9082265304738ad312f8f8da216567c24595b0e5
@@ -0,0 +1 @@
1
+ Can be found at [https://github.com/boutetnico/sensu-plugins-ssl/releases](https://github.com/boutetnico/sensu-plugins-ssl/releases).
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Sensu-Plugins
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,78 @@
1
+ ## Sensu-Plugins-SSL
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/sensu-plugins-ssl-boutetnico.svg)](https://badge.fury.io/rb/sensu-plugins-ssl-boutetnico.svg)
4
+ [![Sensu Bonsai Asset](https://img.shields.io/badge/Bonsai-Download%20Me-brightgreen.svg?colorB=89C967&logo=sensu)](https://bonsai.sensu.io/assets/boutetnico/sensu-plugins-ssl)
5
+
6
+ ## This is an unofficial fork
7
+
8
+ This fork is automatically tested, built and published to [RubyGems](https://rubygems.org/gems/sensu-plugins-ssl-boutetnico/) and [Bonsai](https://bonsai.sensu.io/assets/boutetnico/sensu-plugins-ssl).
9
+
10
+ ## Files
11
+ * bin/check-java-keystore-cert.rb
12
+ * bin/check-ssl-anchor.rb
13
+ * bin/check-ssl-crl.rb
14
+ * bin/check-ssl-cert.rb
15
+ * bin/check-ssl-host.rb
16
+ * bin/check-ssl-hsts-preload.rb
17
+ * bin/check-ssl-hsts-preloadable.rb
18
+ * bin/check-ssl-qualys.rb
19
+ * bin/check-ssl-root-issuer.rb
20
+
21
+ ## Usage
22
+
23
+ ### `bin/check-ssl-anchor.rb`
24
+
25
+ Check that a specific website is chained to a specific root certificate (Let's Encrypt for instance). Requires the `openssl` commandline tool to be available on the system.
26
+
27
+ ```
28
+ ./bin/check-ssl-anchor.rb -u example.com -a "i:/O=Digital Signature Trust Co./CN=DST Root CA X3"
29
+ ```
30
+
31
+ ### `bin/check-ssl-crl.rb`
32
+
33
+ Checks a CRL has not or is not expiring by inspecting it's next update value.
34
+
35
+ You can check against a CRL file on disk:
36
+
37
+ ```
38
+ ./bin/check-ssl-crl -c 300 -w 600 -u /path/to/crl
39
+ ```
40
+
41
+ or an online CRL:
42
+
43
+ ```
44
+ ./bin/check-ssl-crl -c 300 -w 600 -u http://www.website.com/file.crl
45
+ ```
46
+
47
+ Critical and Warning thresholds are specified in minutes.
48
+
49
+ ### `bin/check-ssl-qualys.rb`
50
+
51
+ Checks the ssllabs qualysis api for grade of your server, this check can be quite long so it should not be scheduled with a low interval and will probably need to adjust the check `timeout` options per the [check attributes spec](https://docs.sensu.io/sensu-core/1.2/reference/checks/#check-attributes) based on my tests you should expect this to take around 3 minutes.
52
+ ```
53
+ ./bin/check-ssl-qualys.rb -d google.com
54
+ ```
55
+
56
+ ### `bin/check-ssl-root-issuer.rb`
57
+
58
+ Check that a specific website is chained to a specific root certificate issuer. This is a pure Ruby implementation, does not require the openssl cmdline client tool to be installed.
59
+
60
+ ```
61
+ ./bin/check-ssl-root-issuer.rb -u example.com -a "CN=DST Root CA X3,O=Digital Signature Trust Co."
62
+ ```
63
+
64
+ ## Installation
65
+
66
+ [Installation and Setup](http://sensu-plugins.io/docs/installation_instructions.html)
67
+
68
+ ## Testing
69
+
70
+ To run the testing suite, you'll need to have a working `ruby` environment, `gem`, and `bundler` installed. We use `rake` to run the `rspec` tests automatically.
71
+
72
+ bundle install
73
+ bundle update
74
+ bundle exec rake
75
+
76
+ ## Notes
77
+
78
+ `bin/check-ssl-anchor.rb` and `bin/check-ssl-host.rb` would be good to run in combination with each other to test that the chain is anchored to a specific certificate and each certificate in the chain is correctly signed.
@@ -0,0 +1,88 @@
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 'shellwords'
26
+ require 'sensu-plugin/check/cli'
27
+
28
+ class CheckJavaKeystoreCert < Sensu::Plugin::Check::CLI
29
+ option :path,
30
+ long: '--path PATH',
31
+ description: '',
32
+ required: true
33
+
34
+ option :alias,
35
+ long: '--alias ALIAS',
36
+ description: '',
37
+ required: true
38
+
39
+ option :password,
40
+ long: '--password PASSWORD',
41
+ description: '',
42
+ required: true
43
+
44
+ option :warning,
45
+ long: '--warning DAYS',
46
+ description: '',
47
+ proc: proc { |v| v.to_i },
48
+ required: true
49
+
50
+ option :critical,
51
+ long: '--critical DAYS',
52
+ description: '',
53
+ proc: proc { |v| v.to_i },
54
+ required: true
55
+
56
+ def certificate_expiration_date
57
+ result = `keytool -keystore #{Shellwords.escape(config[:path])} \
58
+ -export -alias #{Shellwords.escape(config[:alias])} \
59
+ -storepass #{Shellwords.escape(config[:password])} -rfc 2>&1 | \
60
+ openssl x509 -enddate -noout 2>&1`
61
+
62
+ # rubocop:disable Style/SpecialGlobalVars
63
+ unknown 'could not get certificate from keystore' unless $?.success?
64
+ # rubocop:enable Style/SpecialGlobalVars
65
+
66
+ Date.parse(result.split('=').last)
67
+ end
68
+
69
+ def validate_opts
70
+ unknown 'warning cannot be less than critical' if config[:warning] < config[:critical]
71
+ end
72
+
73
+ def run
74
+ validate_opts
75
+
76
+ days_until = (certificate_expiration_date - Date.today).to_i
77
+
78
+ if days_until.negative?
79
+ critical "Expired #{days_until.abs} days ago"
80
+ elsif days_until < config[:critical]
81
+ critical "#{days_until} days left"
82
+ elsif days_until < config[:warning]
83
+ warning "#{days_until} days left"
84
+ end
85
+
86
+ ok "#{days_until} days left"
87
+ end
88
+ end
@@ -0,0 +1,120 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # check-ssl-anchor
4
+ #
5
+ # DESCRIPTION:
6
+ # Check that a certificate is chained to a specific root certificate
7
+ #
8
+ # OUTPUT:
9
+ # plain text
10
+ #
11
+ # PLATFORMS:
12
+ # Linux
13
+ #
14
+ # DEPENDENCIES:
15
+ # gem: sensu-plugin
16
+ #
17
+ # USAGE:
18
+ #
19
+ # Check that a specific website is chained to a specific root certificate (Let's Encrypt for instance)
20
+ # ./check-ssl-anchor.rb \
21
+ # -u example.com \
22
+ # -a "i:/O=Digital Signature Trust Co./CN=DST Root CA X3"
23
+ #
24
+ # NOTES:
25
+ # This is basically a ruby wrapper around the following openssl command.
26
+ #
27
+ # openssl s_client -connect example.com:443 -servername example.com
28
+ #
29
+ #
30
+ #
31
+ # Use the -s flag if you need to override SNI (Server Name Indication). If you
32
+ # are seeing discrepencies between `openssl s_client` and browser, that's a good
33
+ # indication to use this flag.
34
+ #
35
+ # LICENSE:
36
+ # Copyright 2017 Phil Porada <philporada@gmail.com>
37
+ #
38
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
39
+ # for details.
40
+ #
41
+
42
+ require 'sensu-plugin/check/cli'
43
+
44
+ #
45
+ # Check certificate is anchored to a specific root
46
+ #
47
+ class CheckSSLAnchor < Sensu::Plugin::Check::CLI
48
+ option :host,
49
+ description: 'Host to check',
50
+ short: '-h',
51
+ long: '--host HOST',
52
+ required: true
53
+
54
+ option :anchor,
55
+ description: 'An anchor looks something like /O=Digital Signature Trust Co./CN=DST Root CA X3',
56
+ short: '-a',
57
+ long: '--anchor ANCHOR_VAL',
58
+ required: true
59
+
60
+ option :regexp,
61
+ description: 'Treat the anchor as a regexp',
62
+ short: '-r',
63
+ long: '--regexp',
64
+ default: false,
65
+ boolean: true,
66
+ required: false
67
+
68
+ option :servername,
69
+ description: 'Set the TLS SNI (Server Name Indication) extension',
70
+ short: '-s',
71
+ long: '--servername SERVER'
72
+
73
+ option :port,
74
+ description: 'Port on server to check',
75
+ short: '-p',
76
+ long: '--port PORT',
77
+ default: 443
78
+
79
+ def validate_opts
80
+ config[:servername] = config[:host] unless config[:servername]
81
+ end
82
+
83
+ # Do the actual work and massage some data
84
+ def anchor_information
85
+ data = `openssl s_client \
86
+ -connect #{config[:host]}:#{config[:port]} \
87
+ -servername #{config[:servername]} < /dev/null 2>&1`.match(/Certificate chain(.*)---\nServer certificate/m)[1].split(/$/).map(&:strip)
88
+ data = data.reject(&:empty?)
89
+
90
+ unless data[0] =~ /0 s:\/?CN ?=.*/m
91
+ data = 'NOTOK'
92
+ end
93
+ data
94
+ end
95
+
96
+ def run
97
+ validate_opts
98
+ data = anchor_information
99
+ if data == 'NOTOK'
100
+ critical 'An error was encountered while trying to retrieve the certificate chain.'
101
+ end
102
+ puts config[:regexp]
103
+ # rubocop:disable Style/IfInsideElse
104
+ if config[:regexp]
105
+ anchor_regexp = Regexp.new(config[:anchor].to_s)
106
+ if data[-1] =~ anchor_regexp
107
+ ok 'Root anchor has been found.'
108
+ else
109
+ critical 'Root anchor did not match regexp /' + config[:anchor].to_s + "/\nFound \"" + data[-1] + '" instead.'
110
+ end
111
+ else
112
+ if data[-1] == config[:anchor].to_s
113
+ ok 'Root anchor has been found.'
114
+ else
115
+ critical 'Root anchor did not match string "' + config[:anchor].to_s + "\"\nFound \"" + data[-1] + '" instead.'
116
+ end
117
+ end
118
+ # rubocop:enable Style/IfInsideElse
119
+ end
120
+ end
@@ -0,0 +1,130 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # check-ssl-cert
4
+ #
5
+ # DESCRIPTION:
6
+ # Check when a SSL certificate 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
+ # LICENSE:
24
+ # Jean-Francois Theroux <me@failshell.io>
25
+ # Nathan Williams <nath.e.will@gmail.com>
26
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
27
+ # for details.
28
+ #
29
+
30
+ require 'date'
31
+ require 'openssl'
32
+ require 'sensu-plugin/check/cli'
33
+
34
+ #
35
+ # Check SSL Cert
36
+ #
37
+ class CheckSSLCert < Sensu::Plugin::Check::CLI
38
+ option :critical,
39
+ description: 'Numbers of days left',
40
+ short: '-c',
41
+ long: '--critical DAYS',
42
+ required: true
43
+
44
+ option :warning,
45
+ description: 'Numbers of days left',
46
+ short: '-w',
47
+ long: '--warning DAYS',
48
+ required: true
49
+
50
+ option :pem,
51
+ description: 'Path to PEM file',
52
+ short: '-P',
53
+ long: '--pem PEM'
54
+
55
+ option :host,
56
+ description: 'Host to validate',
57
+ short: '-h',
58
+ long: '--host HOST'
59
+
60
+ option :port,
61
+ description: 'Port to validate',
62
+ short: '-p',
63
+ long: '--port PORT'
64
+
65
+ option :servername,
66
+ description: 'Set the TLS SNI (Server Name Indication) extension',
67
+ short: '-s',
68
+ long: '--servername SERVER'
69
+
70
+ option :pkcs12,
71
+ description: 'Path to PKCS#12 certificate',
72
+ short: '-C',
73
+ long: '--cert P12'
74
+
75
+ option :pass,
76
+ description: 'Pass phrase for the private key in PKCS#12 certificate',
77
+ short: '-S',
78
+ long: '--pass '
79
+
80
+ def ssl_cert_expiry
81
+ `openssl s_client -servername #{config[:servername]} -connect #{config[:host]}:#{config[:port]} < /dev/null 2>&1 | openssl x509 -enddate -noout`.split('=').last
82
+ end
83
+
84
+ def ssl_pem_expiry
85
+ OpenSSL::X509::Certificate.new(File.read config[:pem]).not_after # rubocop:disable Style/NestedParenthesizedCalls
86
+ end
87
+
88
+ def ssl_pkcs12_expiry
89
+ `openssl pkcs12 -in #{config[:pkcs12]} -nokeys -nomacver -passin pass:"#{config[:pass]}" | openssl x509 -noout -enddate | grep -v MAC`.split('=').last
90
+ end
91
+
92
+ def validate_opts
93
+ if !config[:pem] && !config[:pkcs12]
94
+ unknown 'Host and port required' unless config[:host] && config[:port]
95
+ elsif config[:pem]
96
+ unknown 'No such cert' unless File.exist? config[:pem]
97
+ elsif config[:pkcs12]
98
+ if !config[:pass]
99
+ unknown 'No pass phrase specified for PKCS#12 certificate'
100
+ else
101
+ unknown 'No such cert' unless File.exist? config[:pkcs12]
102
+ end
103
+ end
104
+ config[:servername] = config[:host] unless config[:servername]
105
+ end
106
+
107
+ def run
108
+ validate_opts
109
+
110
+ expiry = if config[:pem]
111
+ ssl_pem_expiry
112
+ elsif config[:pkcs12]
113
+ ssl_pkcs12_expiry
114
+ else
115
+ ssl_cert_expiry
116
+ end
117
+
118
+ days_until = (Date.parse(expiry.to_s) - Date.today).to_i
119
+
120
+ if days_until.negative?
121
+ critical "Expired #{days_until.abs} days ago"
122
+ elsif days_until < config[:critical].to_i
123
+ critical "#{days_until} days left"
124
+ elsif days_until < config[:warning].to_i
125
+ warning "#{days_until} days left"
126
+ else
127
+ ok "#{days_until} days left"
128
+ end
129
+ end
130
+ end