From 6802d71072fce8a675cd0e8985777b5e968cc469 Mon Sep 17 00:00:00 2001 From: Hendrik Jäger Date: Sun, 11 Feb 2024 22:12:55 +0100 Subject: cleanup, comments --- macir.rb | 210 ++++++++++----------------------------------------------------- 1 file changed, 33 insertions(+), 177 deletions(-) (limited to 'macir.rb') diff --git a/macir.rb b/macir.rb index a5ea61b..986312c 100644 --- a/macir.rb +++ b/macir.rb @@ -208,7 +208,7 @@ def wait_for_challenge_propagation(domain, challenge) threads.each(&:join) end -def acme_request_with_retries(retries: 5, &block) +def acme_request_with_retries(retries: 10, &block) # p "Retries: #{retries}" block.call(self) rescue Acme::Client::Error::BadNonce @@ -218,6 +218,15 @@ rescue Acme::Client::Error::BadNonce acme_request_with_retries(retries: retries - 1, &block) end +def unvalidated_domains(d_a) + d_a.select do |d, a| + p "#{d} status #{a['auth'].dns01.status}" + p a['auth'].dns01.status + acme_request_with_retries { a['auth'].dns01.reload } + a['auth'].dns01.status != 'valid' + end +end + def wait_for_challenge_validation(challenge, cert_name) p 'Requesting validation of challenge' p challenge.object_id @@ -308,121 +317,17 @@ def handle_apex_authzs(apex, authzs, config) end -# domain_to_apex = {} -# -# domain_apex_threads = [] -# domains_with_apex = domains.map do |domain| -# apex_thread = Thread.new(domain) do |d| -# find_apex_domain(d).to_s -# end -# domain_apex_threads << apex_thread -# domain_to_apex[domain] = apex_thread.value -# { apex_thread.value => [domain] } -# end -# domain_apex_threads.each(&:join) -# -# domains_per_apex = domains_with_apex[0].merge(*domains_with_apex[1..]) do |_key, old, new| -# old + new -# end -# -# p "domains_per_apex" -# pp domains_per_apex - - config = read_config cert_dir = config.dig('global', 'cert_dir') || './certs/' ensure_cert_dir(cert_dir) -# acme_threads = [] -# # iterate over configured certs -# config['certs'].each_pair do |cert_name, cert_opts| -# acme_threads << Thread.new(cert_name, cert_opts) do |cert_name, cert_opts| -# ensure_cert_dir(cert_dir + cert_name) -# -# p "Cert #{cert_name}: Finding CA to use for cert" -# cert_ca = cert_opts['ca'] || config.dig('defaults', 'certs', 'ca') -# cert_ca_name = cert_ca['name'] -# cert_ca_account_name = cert_ca['account'] -# -# p "Cert #{cert_name}: Finding directory URL for CA" -# acme_directory_url = config.dig('CAs', cert_ca_name, 'directory_url') -# -# p "Cert #{cert_name}: Finding account to use for cert #{cert_name} from CA #{cert_ca_name}" -# account = config.dig('ca_accounts', cert_ca_account_name) -# email = account['email'] -# -# private_key = read_account_key(account['keyfile']) -# -# p "Cert #{cert_name}: Creating client object for communication with CA" -# client = Acme::Client.new(private_key: private_key, directory: acme_directory_url) -# -# acme_request_with_retries { client.new_account(contact: "mailto:#{email}", terms_of_service_agreed: true) } -# -# p "Cert #{cert_name}: Creating order object for cert #{cert_name}" -# order = acme_request_with_retries { client.new_order(identifiers: cert_opts['domain_names']) } -# -# p "Cert #{cert_name}: order status" -# p order.status -# -# if order.status != 'ready' -# p "Cert #{cert_name}: Order is not ready, we need to authorize first" -# -# # TODO: collect dns modifications per primary NS, update all at once -# p "Cert #{cert_name}: Iterating over required authorizations" -# auths = acme_request_with_retries { order.authorizations } -# auths.each do |auth| -# p "Cert #{cert_name}: Processing authorization for #{auth.domain}" -# p "Cert #{cert_name}: Finding challenge type for #{auth.domain}" -# # p "Cert #{cert_name}: auth is:" -# # pp auth -# if auth.status == 'valid' -# p "Cert #{cert_name}: Authorization for #{auth.domain} is still valid, skipping" -# next -# end -# -# challenge = auth.dns01 -# primary_ns = config.dig('domains', auth.domain, 'primary_ns') || config.dig('defaults', 'domains', 'primary_ns') -# deploy_dns01_challenge_token(auth.domain, challenge, primary_ns, config) -# wait_for_challenge_propagation(auth.domain, challenge) -# wait_for_challenge_validation(challenge, cert_name) -# end -# else -# p "Cert #{cert_name}: Order is ready, we don’t need to authorize" -# end -# domain_key = read_cert_key(cert_name) -# -# get_cert(order, cert_name, cert_opts['domain_names'], domain_key) -# end -# end -# -# acme_threads.each(&:join) - - -# TODO: restructure process -# DELAY THIS FOR NOW: check all certs’ lifetimes -# DELAY THIS FOR NOW: decide which ones to renew -# collect domain names for certs to be renewed -# group domains in need of validation by apex_domain -# collect ca_accounts that need to be used -# THREAD PER ACCOUNT: create account object -# hash: ca_account => account object -# THREAD PER CA_ACCOUNT: create orders -# THREAD PER DOMAIN: check validation status and collect domains needing validation -# THREAD PER APEX DOMAIN: - # THREAD PER DOMAIN: request challenge - # deploy challenges with one DNS UPDATE per apex_domain - # THREAD PER NS: check propagation - # THREAD PER DOMAIN: - # request validation - # report back to main -# THREAD PER CERT: when all domains for any cert are validated, finalize order - domains = config['certs'].map { |_certname, cert_opts| cert_opts['domain_names'] }.flatten domain_attrs = domains.to_h { |d| [d, {}] } + domain_apex_threads = {} domains.map do |d| domain_apex_threads[d] = Thread.new(d) do |d| @@ -467,24 +372,6 @@ certs.each_pair do |name, opts| opts['ca_account'] || certs[name]['ca_account'] = config.dig('defaults', 'certs', 'ca_account') end -# # iterate over configured certs to find CA and account to use -# cert_to_CA_account = config['certs'].map do |cert_name, cert_opts| -# # ensure_cert_dir(cert_dir + cert_name) -# -# p "Cert #{cert_name}: Finding CA to use for cert" -# find_ca_for_cert(cert_name, cert_opts, config) -# end -# -# # p "cert_to_CA_account" -# # pp cert_to_CA_account -# -# certs_to_CA = cert_to_CA_account[0].merge(*cert_to_CA_account[1..]) -# # p "certs_to_CA" -# # p certs_to_CA - - -# unique_CA_accounts_to_use = certs_to_CA.values.uniq -# p "unique_CA_accounts_to_use: #{unique_CA_accounts_to_use}" ca_accounts = certs.map { |_, opts| opts['ca_account'] }.uniq @@ -507,20 +394,9 @@ account_threads.each(&:join) ca_clients = account_threads.map { |t| t.value } ca_clients = ca_clients[0].merge(*ca_clients[1..]) -# ca_clients = {} -# account_threads.each do |t| -# ca_account_to_client = t.value -# ca_clients[ca_account_to_client['account']] = ca_account_to_client['client'] -# end - -# acme_threads = [] certs.each_pair do |cert_name, cert_opts| - # p cert_opts - # p cert_opts['ca_account'] client = ca_clients[cert_opts['ca_account']] - # p "client" - # p client domains = cert_opts['domain_names'] certs[cert_name]['order_thread'] = Thread.new(cert_name, client, domains) do |cert_name, client, domains| p "Cert #{cert_name}: Creating order object for cert #{cert_name}" @@ -534,41 +410,10 @@ certs.each_pair do |cert_name, cert_opts| certs[cert_name]['order'] = t.value end -# pp certs - -# certs_to_CA.each_pair do |cert_name, ca| -# # p "ca_clients[ca]: #{ca_clients[ca]}" -# acme_threads << Thread.new(cert_name, ca_clients[ca], config) do |cert_name, client, config| -# p "Cert #{cert_name}: Creating order object for cert #{cert_name}" -# cert_opts = config['certs'][cert_name] -# order = acme_request_with_retries { client.new_order(identifiers: cert_opts['domain_names']) } -# { cert_name => order } -# end -# end -# -# acme_threads.each(&:join) -# orders = acme_threads.map(&:value) -# orders = orders[0].merge(*orders[1..]) -# p "orders:" -# pp orders - -# order_threads = [] -# # for each order do -# # if its ready skip to getting cert -# # THREADS: get authorizations -# authorizations = {} -# orders.each_pair do |cert_name, order| -# order_authorizations = acme_request_with_retries { order.authorizations } -# authorizations[cert_name] = order_authorizations -# end certs.each_pair do |cert, opts| order_authorizations = acme_request_with_retries { opts['order'].authorizations } order_authorizations.each do |auth| - # pp auth - # pp auth.domain - # pp auth.challenges - # pp auth.url domain_attrs[auth.domain]['auth'] = auth end end @@ -595,20 +440,31 @@ end propagation_threads.each(&:join) -validation_threads = {} -domain_attrs.each_pair do |d, attrs| - # domain_attrs[d][:auth_thread] = Thread.new(attrs) do |attrs| - # validation_threads[d] = Thread.new(attrs) do |attrs| - # wait_for_challenge_validation(auth.domain, auth.dns01) - # pp auth.dns01 - # pp auth.dns01 - # p attrs['auth'].object_id - wait_for_challenge_validation(attrs['auth'].dns01, attrs['auth'].domain) - # end +# validation_threads = {} +p 'Finding unvalidated domains, initial run' +unvalidated_domains = unvalidated_domains(domain_attrs) +until unvalidated_domains.empty? + unvalidated_domains.each_pair do |_, attrs| + # WARNING: for some reason threading does not really work here! + # domain_attrs.each_pair do |d, attrs| + # domain_attrs[d][:auth_thread] = Thread.new(attrs) do |attrs| + # validation_threads[d] = Thread.new(attrs) do |attrs| + # wait_for_challenge_validation(auth.domain, auth.dns01) + # pp auth.dns01 + # pp auth.dns01 + # p attrs['auth'].object_id + # wait_for_challenge_validation(attrs['auth'].dns01, attrs['auth'].domain) + # acme_request_with_retries { attrs['auth'].dns01.reload } + p 'Requesting validation of challenge' + acme_request_with_retries { attrs['auth'].dns01.request_validation } + end # validation_threads[d] = domain_attrs[d][:auth_thread] + p 'Finding unvalidated domains, next run' + unvalidated_domains = unvalidated_domains(domain_attrs) + sleep(0.2) end -validation_threads.each_pair { |d, t| t.join } +# validation_threads.each_pair { |d, t| t.join } certs.each_pair do |name, opts| cert_key = read_cert_key(name) -- cgit v1.2.3