acme_nsupdate 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/acme_nsupdate/cli.rb +1 -1
- data/lib/acme_nsupdate/client.rb +21 -14
- data/lib/acme_nsupdate/strategies/dns01.rb +2 -2
- data/lib/acme_nsupdate/strategies/http01.rb +2 -2
- data/lib/acme_nsupdate/strategy.rb +11 -10
- data/lib/acme_nsupdate/version.rb +1 -1
- metadata +7 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bc260ec101b559b2dfd436b9e0b5966b2311c37b32094b868df7bb334aee9312
|
4
|
+
data.tar.gz: 0a0de9a4ba9e2b098216ad042ff7be40c58c92e10695bf40996f8f7a4354e688
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f443e2e27948180e54b17af0a4b3f71829544ff6f4ff2407bf8c2245812dd0cda7554b140047f8adfbbc303dcefcc93ee68ebf3f3b22a488f85eea59e28120dd
|
7
|
+
data.tar.gz: 294fe014df4df6dd2800d7ddae0bdfcd4b944d0bb77753d77edc5cc04704bf4f7441d68d4f5e2978c2464c8eaf0739816ad405c093b8a17d905b7331f52efec9
|
data/lib/acme_nsupdate/cli.rb
CHANGED
@@ -12,7 +12,7 @@ module AcmeNsupdate
|
|
12
12
|
o.string "-t", "--ttl", "The TTLs of the TXT and TLSA records created, separated by a comma. Defaults to 60,43200", default: "60,43200"
|
13
13
|
o.bool "-k", "--keep", "Skip removing any kind of temporary data after successfully obtaining the certificate."
|
14
14
|
o.string "-K", "--tsig", "TSIG key to use for DNS updates. Expected format is name:key."
|
15
|
-
o.string "-e", "--endpoint", "ACME API endpoint. Defaults to: https://acme-
|
15
|
+
o.string "-e", "--endpoint", "ACME API endpoint directory. Defaults to: https://acme-v02.api.letsencrypt.org/directory", default: "https://acme-v02.api.letsencrypt.org/directory"
|
16
16
|
o.string "-D", "--datadir", "Base directory for certificates and account keys. Defaults to: /etc/letsencrypt", default: "/etc/letsencrypt"
|
17
17
|
o.string "-c", "--contact", "Contact mail address."
|
18
18
|
o.integer "-l", "--keylength", "Length of the generated RSA keys. Defaults to 2048.", default: 2048
|
data/lib/acme_nsupdate/client.rb
CHANGED
@@ -34,13 +34,13 @@ module AcmeNsupdate
|
|
34
34
|
end
|
35
35
|
|
36
36
|
register_account
|
37
|
-
challenges = @verification_strategy.verify_domains
|
37
|
+
order, challenges = @verification_strategy.verify_domains
|
38
38
|
logger.info "Requesting certificate"
|
39
|
-
certificate =
|
39
|
+
certificate = fetch_certificate order
|
40
40
|
write_files live_path, certificate, private_key
|
41
41
|
write_files archive_path, certificate, private_key
|
42
42
|
@verification_strategy.cleanup challenges unless @options[:keep]
|
43
|
-
publish_tlsa_records certificate
|
43
|
+
publish_tlsa_records certificate
|
44
44
|
rescue Nsupdate::Error
|
45
45
|
abort "nsupdate failed." # detail logged in Nsupdate
|
46
46
|
end
|
@@ -49,12 +49,11 @@ module AcmeNsupdate
|
|
49
49
|
return if account_key_path.exist?
|
50
50
|
|
51
51
|
logger.debug "No key found at #{account_key_path}, registering"
|
52
|
-
|
53
|
-
registration.agree_terms
|
52
|
+
client.new_account contact: "mailto:#{@options[:contact]}", terms_of_service_agreed: true
|
54
53
|
end
|
55
54
|
|
56
55
|
def client
|
57
|
-
@client ||= Acme::Client.new(private_key: account_key,
|
56
|
+
@client ||= Acme::Client.new(private_key: account_key, directory: @options[:endpoint]).tap do |client|
|
58
57
|
client.connection.response :detailed_logger, @logger if @options[:verbose]
|
59
58
|
end
|
60
59
|
end
|
@@ -94,6 +93,16 @@ module AcmeNsupdate
|
|
94
93
|
end
|
95
94
|
end
|
96
95
|
|
96
|
+
def fetch_certificate order
|
97
|
+
order.finalize csr
|
98
|
+
while order.status == 'processing'
|
99
|
+
sleep 3
|
100
|
+
order.reload
|
101
|
+
end
|
102
|
+
raise "Failed to fetch certificate, order failed." unless order.status == 'valid'
|
103
|
+
order.certificate
|
104
|
+
end
|
105
|
+
|
97
106
|
def csr
|
98
107
|
logger.debug "Generating CSR"
|
99
108
|
Acme::Client::CertificateRequest.new(names: @options[:domains], private_key: private_key)
|
@@ -123,17 +132,15 @@ module AcmeNsupdate
|
|
123
132
|
logger.debug "Writing #{path.join("key.pem")}"
|
124
133
|
path.join("privkey.pem").write key.to_pem
|
125
134
|
path.join("privkey.pem").chmod(0600)
|
126
|
-
logger.debug "Writing #{path.join("cert.pem")}"
|
127
|
-
path.join("cert.pem").write certificate.to_pem
|
128
|
-
logger.debug "Writing #{path.join("chain.pem")}"
|
129
|
-
path.join("chain.pem").write certificate.chain_to_pem
|
130
135
|
logger.debug "Writing #{path.join("fullchain.pem")}"
|
131
|
-
path.join("fullchain.pem").write certificate
|
136
|
+
path.join("fullchain.pem").write certificate
|
132
137
|
end
|
133
138
|
|
134
|
-
def publish_tlsa_records
|
139
|
+
def publish_tlsa_records certificate_pem
|
135
140
|
return if @options[:notlsa]
|
136
141
|
|
142
|
+
certificate = OpenSSL::X509::Certificate.new certificate_pem
|
143
|
+
|
137
144
|
logger.info "Publishing TLSA records"
|
138
145
|
old_contents = outdated_certificates.map {|certificate|
|
139
146
|
"3 1 1 #{OpenSSL::Digest::SHA256.hexdigest(certificate.public_key.to_der)}"
|
@@ -177,9 +184,9 @@ module AcmeNsupdate
|
|
177
184
|
@outdated_certificates ||= datadir
|
178
185
|
.join("archive")
|
179
186
|
.children
|
180
|
-
.select {|dir| dir.join(domain, "
|
187
|
+
.select {|dir| dir.join(domain, "fullchain.pem").exist? }
|
181
188
|
.sort_by(&:basename)
|
182
|
-
.map {|path| OpenSSL::X509::Certificate.new path.join(domain, "
|
189
|
+
.map {|path| OpenSSL::X509::Certificate.new path.join(domain, "fullchain.pem").read }
|
183
190
|
.tap(&:pop) # keep current
|
184
191
|
.tap(&:pop) # keep previous
|
185
192
|
end
|
@@ -13,8 +13,8 @@ module AcmeNsupdate
|
|
13
13
|
@client = client
|
14
14
|
end
|
15
15
|
|
16
|
-
def publish_challenges
|
17
|
-
challenges = map_authorizations {|domain, authorization|
|
16
|
+
def publish_challenges(order)
|
17
|
+
challenges = map_authorizations(order) {|domain, authorization|
|
18
18
|
challenge = authorization.dns01
|
19
19
|
abort "Challenge dns-01 not supported by the given ACME server" unless challenge
|
20
20
|
|
@@ -13,8 +13,8 @@ module AcmeNsupdate
|
|
13
13
|
@client = client
|
14
14
|
end
|
15
15
|
|
16
|
-
def publish_challenges
|
17
|
-
map_authorizations {|domain, authorization|
|
16
|
+
def publish_challenges(order)
|
17
|
+
map_authorizations(order) {|domain, authorization|
|
18
18
|
challenge = authorization.http01
|
19
19
|
abort "Challenge http-01 not supported by this ACME server" unless challenge
|
20
20
|
|
@@ -16,39 +16,40 @@ module AcmeNsupdate
|
|
16
16
|
|
17
17
|
def verify_domains
|
18
18
|
@client.logger.info("Validating domains")
|
19
|
-
|
19
|
+
order = @client.client.new_order identifiers: @client.options[:domains]
|
20
|
+
challenges = publish_challenges(order).tap do |challenges|
|
20
21
|
wait_for_verification challenges
|
21
22
|
end
|
23
|
+
[order, challenges]
|
22
24
|
end
|
23
25
|
|
24
26
|
|
25
27
|
private
|
26
28
|
|
27
|
-
def map_authorizations
|
29
|
+
def map_authorizations(order)
|
28
30
|
@client.logger.debug "Publishing challenges for #{@client.options[:domains].join(", ")}"
|
29
31
|
|
30
|
-
|
31
|
-
authorization = @client.client.authorize domain: domain
|
32
|
+
order.authorizations.map {|authorization|
|
32
33
|
if authorization.status == "valid"
|
33
|
-
@client.logger.debug("Skipping challenge for #{domain}, already valid.")
|
34
|
+
@client.logger.debug("Skipping challenge for #{authorization.domain}, already valid.")
|
34
35
|
next
|
35
36
|
end
|
36
37
|
|
37
|
-
challenge = yield domain, authorization
|
38
|
+
challenge = yield authorization.domain, authorization
|
38
39
|
unless challenge
|
39
|
-
@client.logger.debug("Skipping challenge for #{domain}, not solvable.")
|
40
|
+
@client.logger.debug("Skipping challenge for #{authorization.domain}, not solvable.")
|
40
41
|
next
|
41
42
|
end
|
42
43
|
|
43
|
-
[domain, challenge]
|
44
|
+
[authorization.domain, challenge]
|
44
45
|
}.compact.to_h
|
45
46
|
end
|
46
47
|
|
47
48
|
def wait_for_verification challenges
|
48
49
|
@client.logger.debug("Requesting verification")
|
49
|
-
challenges.each_value(&:
|
50
|
+
challenges.each_value(&:request_validation)
|
50
51
|
@client.logger.debug("Waiting for verification")
|
51
|
-
challenges.map {|_, challenge| Thread.new { sleep(5) while challenge.
|
52
|
+
challenges.map {|_, challenge| Thread.new { sleep(5) while challenge.status == "pending" } }.each(&:join)
|
52
53
|
challenges.each do |domain, challenge|
|
53
54
|
raise "Verification of #{domain} failed: #{challenge.error}" unless challenge.status == "valid"
|
54
55
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acme_nsupdate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonne Haß
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: slop
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 2.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 2.0.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: faraday-detailed_logger
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '2.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '2.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,8 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
120
|
- !ruby/object:Gem::Version
|
121
121
|
version: '0'
|
122
122
|
requirements: []
|
123
|
-
|
124
|
-
rubygems_version: 2.6.8
|
123
|
+
rubygems_version: 3.1.2
|
125
124
|
signing_key:
|
126
125
|
specification_version: 4
|
127
126
|
summary: ACME (Let's Encrypt) client with nsupdate (DDNS) integration.
|