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 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.