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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 32a1bde5ca74c8eaf4a6f1aa2ede91a30dda38e1
4
- data.tar.gz: 44e2a5ecd61941bf5e467fcbb1fe42bb6a4cebb8
2
+ SHA256:
3
+ metadata.gz: bc260ec101b559b2dfd436b9e0b5966b2311c37b32094b868df7bb334aee9312
4
+ data.tar.gz: 0a0de9a4ba9e2b098216ad042ff7be40c58c92e10695bf40996f8f7a4354e688
5
5
  SHA512:
6
- metadata.gz: 28a1ce36f68802da49560a58817b5c8948ca3c558dc9ff77594a323d0e560dde0e148c5cb8cb96a7c82ab15bc881386f0f581d0b6ae1e0f55875f3493d733d01
7
- data.tar.gz: fa53966b1dd97027a6676bca98436ad1dcbce484cfaa997a51f8f278eea948a9aeb2a74614d2d8d6ab4007ec2a688d132051daa7acd2594f0b9f165fe08fdf43
6
+ metadata.gz: f443e2e27948180e54b17af0a4b3f71829544ff6f4ff2407bf8c2245812dd0cda7554b140047f8adfbbc303dcefcc93ee68ebf3f3b22a488f85eea59e28120dd
7
+ data.tar.gz: 294fe014df4df6dd2800d7ddae0bdfcd4b944d0bb77753d77edc5cc04704bf4f7441d68d4f5e2978c2464c8eaf0739816ad405c093b8a17d905b7331f52efec9
@@ -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-v01.api.letsencrypt.org", default: "https://acme-v01.api.letsencrypt.org"
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
@@ -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 = client.new_certificate csr
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.x509
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
- registration = client.register contact: "mailto:#{@options[:contact]}"
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, endpoint: @options[:endpoint]).tap do |client|
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.fullchain_to_pem
136
+ path.join("fullchain.pem").write certificate
132
137
  end
133
138
 
134
- def publish_tlsa_records certificate
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, "cert.pem").exist? }
187
+ .select {|dir| dir.join(domain, "fullchain.pem").exist? }
181
188
  .sort_by(&:basename)
182
- .map {|path| OpenSSL::X509::Certificate.new path.join(domain, "cert.pem").read }
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
- publish_challenges.tap do |challenges|
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
- challenges = @client.options[:domains].map {|domain|
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(&:request_verification)
50
+ challenges.each_value(&:request_validation)
50
51
  @client.logger.debug("Waiting for verification")
51
- challenges.map {|_, challenge| Thread.new { sleep(5) while challenge.verify_status == "pending" } }.each(&:join)
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
@@ -1,3 +1,3 @@
1
1
  module AcmeNsupdate
2
- VERSION = "0.3.2"
2
+ VERSION = "0.4.0"
3
3
  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.3.2
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: 2017-02-09 00:00:00.000000000 Z
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.5.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.5.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: '1.10'
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: '1.10'
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
- rubyforge_project:
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.