Class: Bullion::ChallengeClients::DNS

Inherits:
Bullion::ChallengeClient show all
Defined in:
lib/bullion/challenge_clients/dns.rb

Overview

ACME DNS01 Challenge Client

Direct Known Subclasses

RSpec::ChallengeClients::DNS

Constant Summary

Constants inherited from Bullion::ChallengeClient

Bullion::ChallengeClient::ChallengeClientMetric

Instance Attribute Summary

Attributes inherited from Bullion::ChallengeClient

#challenge

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Bullion::ChallengeClient

#attempt, #identifier, #initialize

Constructor Details

This class inherits a constructor from Bullion::ChallengeClient

Class Method Details

.acme_typeObject



8
# File 'lib/bullion/challenge_clients/dns.rb', line 8

def self.acme_type = "dns-01"

Instance Method Details

#digest_value(string) ⇒ Object



18
19
20
21
22
23
# File 'lib/bullion/challenge_clients/dns.rb', line 18

def digest_value(string)
  digester = OpenSSL::Digest.new("SHA256")
  digest   = digester.digest(string)
  # clean up the digest output so it can match the provided challenge value
  Base64.urlsafe_encode64(digest).sub(/[\s=]*\z/, "")
end

#dns_nameObject



25
26
27
# File 'lib/bullion/challenge_clients/dns.rb', line 25

def dns_name
  "_acme-challenge.#{identifier}"
end

#dns_valueObject



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/bullion/challenge_clients/dns.rb', line 29

def dns_value
  # Randomly select a nameserver to pull the TXT record
  nameserver = Bullion.config.nameservers.sample

  LOGGER.debug "Looking up #{dns_name}"
  records = records_for(dns_name, nameserver)
  raise "Failed to find records for #{dns_name}" unless records

  record = records.map(&:strings).flatten.first
  LOGGER.debug "Resolved #{dns_name} to value #{record}"
  record
rescue StandardError => e
  msg = ["Resolution error '#{e.message}' for #{dns_name}"]
  msg << "via #{nameserver}" if nameserver
  LOGGER.info msg.join(" ")
  false
end

#performObject



11
12
13
14
15
16
# File 'lib/bullion/challenge_clients/dns.rb', line 11

def perform
  value = dns_value
  expected_value = digest_value("#{challenge.token}.#{challenge.thumbprint}")

  value == expected_value
end

#records_for(name, nameserver = nil) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/bullion/challenge_clients/dns.rb', line 47

def records_for(name, nameserver = nil)
  if nameserver
    Resolv::DNS.open(nameserver:) do |dns|
      dns.getresources(name, Resolv::DNS::Resource::IN::TXT)
    end
  else
    Resolv::DNS.open do |dns|
      dns.getresources(name, Resolv::DNS::Resource::IN::TXT)
    end
  end
end

#typeObject



9
# File 'lib/bullion/challenge_clients/dns.rb', line 9

def type = "DNS01"