acme_nsupdate 0.3.2 → 0.4.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 +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.
|