tls-checker 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/.travis.yml +1 -0
- data/CHANGELOG.md +16 -0
- data/lib/tls-checker.rb +2 -0
- data/lib/tls-checker/certificate_checker.rb +10 -12
- data/lib/tls-checker/certificate_checker_factory.rb +21 -1
- data/lib/tls-checker/tlsa_checker.rb +24 -0
- data/lib/tls-checker/tlsa_checker_factory.rb +52 -0
- data/lib/tls-checker/version.rb +1 -1
- data/tls-checker.gemspec +1 -1
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cdde3a84021818453f8783a575370df091b421bc8ec46b9f37eea6afea7c68d
|
4
|
+
data.tar.gz: f197dbf9cf67fccb5e6f5d757929ea6f145d5fbff77f0ed6adb311b362154e11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59c569e106f22433b88cfd2480a8aad515b6cecedc1e50eaa533b907bb09711e7e90f58f4ed8ec7ecdb6781e17910eee527a72f903a187bb0f125ec1788314be
|
7
|
+
data.tar.gz: 4771ef041e39cb1da7aaae82f5508fc528dd3980a3f4fab0fa8907e89395f0c788e951d15fb8c0bb9d38b2108760b635661a9dfb4c393da2ea233614089f71be
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [1.1.0]
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- Make it possible to test services using an IP address;
|
13
|
+
- Report validity of certificates when a TLSA record is found in the DNS.
|
14
|
+
|
15
|
+
[Unreleased]: https://github.com/smortex/tls-checker/compare/v1.1.0...HEAD
|
16
|
+
[1.1.0]: https://github.com/smortex/tls-checker/compare/v1.0.0...v1.1.0
|
data/lib/tls-checker.rb
CHANGED
@@ -6,8 +6,6 @@ require 'internet_security_event'
|
|
6
6
|
|
7
7
|
module TLSChecker
|
8
8
|
class CertificateChecker
|
9
|
-
include ActionView::Helpers::DateHelper
|
10
|
-
|
11
9
|
def initialize(hostname, address, port, starttls)
|
12
10
|
@hostname = hostname
|
13
11
|
@address = address
|
@@ -31,7 +29,7 @@ module TLSChecker
|
|
31
29
|
}
|
32
30
|
end.merge(
|
33
31
|
service: service,
|
34
|
-
ttl:
|
32
|
+
ttl: 12.hours,
|
35
33
|
tags: ['tls-checker'],
|
36
34
|
)
|
37
35
|
end
|
@@ -40,10 +38,16 @@ module TLSChecker
|
|
40
38
|
description
|
41
39
|
end
|
42
40
|
|
43
|
-
|
41
|
+
def certificate
|
42
|
+
@certificate = OpenSSL::X509::Certificate.new(tls_socket.peer_cert) if @certificate.nil?
|
43
|
+
@certificate
|
44
|
+
rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT, SocketRecvTimeout => e
|
45
|
+
@certificate_failure = e.message
|
46
|
+
@certificate = false
|
47
|
+
end
|
44
48
|
|
45
49
|
def service
|
46
|
-
|
50
|
+
"X.509/#{hostname}/#{humanized_address}:#{port}"
|
47
51
|
end
|
48
52
|
|
49
53
|
def humanized_address
|
@@ -54,13 +58,7 @@ module TLSChecker
|
|
54
58
|
end
|
55
59
|
end
|
56
60
|
|
57
|
-
|
58
|
-
@certificate = OpenSSL::X509::Certificate.new(tls_socket.peer_cert) if @certificate.nil?
|
59
|
-
@certificate
|
60
|
-
rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT, SocketRecvTimeout => e
|
61
|
-
@certificate_failure = e.message
|
62
|
-
@certificate = false
|
63
|
-
end
|
61
|
+
private
|
64
62
|
|
65
63
|
def tls_socket
|
66
64
|
@tls_socket ||= case starttls
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'ipaddr'
|
4
|
+
|
3
5
|
module TLSChecker
|
4
6
|
class CertificateCheckerFactory
|
5
7
|
def initialize
|
@@ -14,7 +16,25 @@ module TLSChecker
|
|
14
16
|
|
15
17
|
port ||= port_for(hostname)
|
16
18
|
starttls ||= starttls_for(port)
|
17
|
-
|
19
|
+
|
20
|
+
begin
|
21
|
+
ip_in_hostname = IPAddr.new(hostname)
|
22
|
+
|
23
|
+
[
|
24
|
+
CertificateChecker.new(nil, ip_in_hostname, port, starttls),
|
25
|
+
]
|
26
|
+
rescue IPAddr::InvalidAddressError
|
27
|
+
certificate_checkers = @resolver.getaddresses(hostname).map { |ip| CertificateChecker.new(hostname, ip, port, starttls) }
|
28
|
+
|
29
|
+
factory = TLSACheckerFactory.new
|
30
|
+
|
31
|
+
tlsa_checkers = []
|
32
|
+
certificate_checkers.each do |certificate_checker|
|
33
|
+
tlsa_checkers += factory.tlsa_checkers_for(certificate_checker)
|
34
|
+
end
|
35
|
+
|
36
|
+
certificate_checkers + tlsa_checkers
|
37
|
+
end
|
18
38
|
end
|
19
39
|
|
20
40
|
private
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TLSChecker
|
4
|
+
class TLSAChecker < InternetSecurityEvent::TLSAStatus
|
5
|
+
def initialize(record, certificate_checker)
|
6
|
+
super(record, certificate_checker.certificate)
|
7
|
+
|
8
|
+
@certificate_checker = certificate_checker
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_e
|
12
|
+
super.merge(
|
13
|
+
service: service,
|
14
|
+
ttl: 12.hours,
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def service
|
21
|
+
"#{@certificate_checker.service}/TLSA"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TLSChecker
|
4
|
+
class TLSACheckerFactory
|
5
|
+
def initialize
|
6
|
+
@resolver = Resolv::DNS.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def tlsa_checkers_for(certificate_checker)
|
10
|
+
res = []
|
11
|
+
|
12
|
+
each_tlsa_end_entity_record(certificate_checker) do |record|
|
13
|
+
checker = TLSAChecker.new(record, certificate_checker)
|
14
|
+
# Since a single domain may have different certificates on different
|
15
|
+
# addresses, we are not interested in reporting failures here: a server
|
16
|
+
# with 3 certificates on 3 IP addresses is expected to have 3 TLSA
|
17
|
+
# records in the DNS, each one being valid for a different certificate.
|
18
|
+
#
|
19
|
+
# By adding only valid certificates, we can still detect problems when
|
20
|
+
# events expire.
|
21
|
+
next unless checker.certificate_match_tlsa_record?
|
22
|
+
|
23
|
+
res << checker
|
24
|
+
end
|
25
|
+
|
26
|
+
res
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def each_tlsa_end_entity_record(certificate_checker)
|
32
|
+
each_tlsa_record(certificate_checker) do |record|
|
33
|
+
next unless record.end_entity?
|
34
|
+
|
35
|
+
yield(record)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def each_tlsa_record(certificate_checker)
|
40
|
+
resource = "_#{certificate_checker.port}._tcp.#{certificate_checker.hostname}."
|
41
|
+
|
42
|
+
@resolver.getresources(resource, Resolv::DNS::Resource::IN::ANY).each do |rr|
|
43
|
+
# XXX: Should we check the RRSIG here, or can we assume that the resolver
|
44
|
+
# should have failed if it could not verify the response?
|
45
|
+
next unless rr.class.name == 'Resolv::DNS::Resource::Generic::Type52_Class1'
|
46
|
+
|
47
|
+
record = Resolv::DNS::Resource::IN::TLSA.new(rr.data)
|
48
|
+
yield(record)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/tls-checker/version.rb
CHANGED
data/tls-checker.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
24
|
spec.require_paths = ['lib']
|
25
25
|
|
26
|
-
spec.add_dependency 'internet_security_event', '~> 1.
|
26
|
+
spec.add_dependency 'internet_security_event', '~> 1.1'
|
27
27
|
|
28
28
|
spec.add_development_dependency 'bundler'
|
29
29
|
spec.add_development_dependency 'midi-smtp-server'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tls-checker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Romain Tartière
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: internet_security_event
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -105,6 +105,7 @@ files:
|
|
105
105
|
- ".gitignore"
|
106
106
|
- ".rspec"
|
107
107
|
- ".travis.yml"
|
108
|
+
- CHANGELOG.md
|
108
109
|
- CODE_OF_CONDUCT.md
|
109
110
|
- Gemfile
|
110
111
|
- LICENSE.txt
|
@@ -117,6 +118,8 @@ files:
|
|
117
118
|
- lib/tls-checker/certificate_checker.rb
|
118
119
|
- lib/tls-checker/certificate_checker_factory.rb
|
119
120
|
- lib/tls-checker/line_oriented_socket.rb
|
121
|
+
- lib/tls-checker/tlsa_checker.rb
|
122
|
+
- lib/tls-checker/tlsa_checker_factory.rb
|
120
123
|
- lib/tls-checker/version.rb
|
121
124
|
- tls-checker.gemspec
|
122
125
|
homepage: https://github.com/smortex/tls-checker
|
@@ -138,8 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
141
|
- !ruby/object:Gem::Version
|
139
142
|
version: '0'
|
140
143
|
requirements: []
|
141
|
-
|
142
|
-
rubygems_version: 2.7.8
|
144
|
+
rubygems_version: 3.0.2
|
143
145
|
signing_key:
|
144
146
|
specification_version: 4
|
145
147
|
summary: Report expired/about to expires certificates used in TLS connexions
|