diff --git a/dnsworker/bin/ds-schedule b/dnsworker/bin/ds-schedule index 1441709..59053f8 100755 --- a/dnsworker/bin/ds-schedule +++ b/dnsworker/bin/ds-schedule @@ -1,105 +1,105 @@ #!/usr/bin/env ruby require 'uri' require 'rack/utils' require 'net/http' require 'open3' class DSPusher attr_reader :cfg def initialize(cfg) @cfg = cfg end def push_ds(zone=nil, dry_run=false) fetch_dss(zone).each { |d, dss| post_dss(d, dss, dry_run) } end def fetch_dss(zone) dss = Hash.new { |h, k| h[k] = [] } cmd = cfg['get_ds'] cmd += " -z #{zone}" if zone out, err = command(cmd) out.each_line { |line| line.strip! next if line.nil? || line == '' next if line.start_with?(';') domain, _ttl, _f, rtype, rdata = line.split(/\s+/, 5) next unless rtype == 'DS' domain = domain.gsub(/\.+$/, '') # Remove trailing . dss[domain] << rdata } dss end def post_dss(domain, dss, dry_run) query = Rack::Utils.build_nested_query( domain: domain, event: 'push_ds', args: dss, ) uri = URI("#{cfg['webdns_base']}#{cfg['update_state']}" % { query: query }) if dry_run p [:uri, uri] return end - Net::HTTP.start(uri.host, uri.port) do |http| + Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http| resp = http.request Net::HTTP::Put.new(uri.request_uri) fail JobFailed if resp.code != '200' end end private def command(cmd) out, err, status = Open3.capture3(cmd) raise "Command error err='#{err.strip}' out='#{out.strip}'" if !status.success? [out, err] end end require 'yaml' require 'optparse' require 'ostruct' options = OpenStruct.new options.dry_run = false options.extra = nil options.zone = nil OptionParser.new do |opts| opts.banner = 'Usage: push-ds [options]' opts.on('-c', '--config CONFIG', 'Config file') do |c| options[:config] = c end opts.on('-e', '--extra CONFIG', 'Extra config file') do |e| options[:extra] = e end opts.on('-n', '--dry-run', 'Run but not execute anything') do |n| options[:dry_run] = n end opts.on('-z', '--zone ZONE', 'Zone') do |z| options[:zone] = z end end.parse! cfg = YAML.load_file(options.config) cfg.merge!(YAML.load_file(options.extra)) if options.extra w = DSPusher.new(cfg) w.push_ds(options.zone, options.dry_run) diff --git a/dnsworker/lib/dnsworker/pushers/webdns.rb b/dnsworker/lib/dnsworker/pushers/webdns.rb index dbd5cc9..5c80a9e 100644 --- a/dnsworker/lib/dnsworker/pushers/webdns.rb +++ b/dnsworker/lib/dnsworker/pushers/webdns.rb @@ -1,23 +1,23 @@ #!/usr/bin/env ruby require 'json' require 'rack/utils' class DNSWorker::Pushers::Webdns < DNSWorker::Pushers::Base def replace_ds(parent, zone, dss) query = Rack::Utils.build_nested_query( child: zone, parent: parent, ds: dss, ) uri = URI(cfg.values_at('webdns_base', 'webdns_replace_ds').join % { query: query }) - Net::HTTP.start(uri.host, uri.port) do |http| + Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http| resp = http.request Net::HTTP::Put.new(uri.request_uri) return false if resp.code != '200' end true end end diff --git a/dnsworker/lib/dnsworker/worker.rb b/dnsworker/lib/dnsworker/worker.rb index d643f5e..98d3aba 100755 --- a/dnsworker/lib/dnsworker/worker.rb +++ b/dnsworker/lib/dnsworker/worker.rb @@ -1,109 +1,109 @@ require 'json' require 'net/http' require 'uri' require 'pp' require 'rack/utils' require 'dnsworker' require 'dnsworker/base_worker' require 'dnsworker/pushers/base' require 'dnsworker/pushers/papaki' require 'dnsworker/pushers/webdns' class DNSWorker::Worker include DNSWorker::BaseWorker Pushers = Hash[ :papaki, DNSWorker::Pushers::Papaki, :webdns, DNSWorker::Pushers::Webdns, ] def initialize(cfg) @cfg = cfg super(cfg['mysql']) end def add_domain(params) params[:master] = cfg['hidden_master'] cmd(cfg['bind_add'] % params) end def remove_domain(params) cmd(cfg['bind_del'] % params) end def opendnssec_add(params) cmd(cfg['ods_add'] % params) end def opendnssec_remove(params) cmd(cfg['ods_del'] % params) end def bind_convert_to_dnssec(params) fail Retry if !File.exist? File.join(cfg['zone_root'], 'signed', params[:zone]) # Remove zone and re-add it as a master zone remove_domain(params) cmd(cfg['bind_add_dnssec'] % params) end # The zone is signed, waiting for the ksk to become ready def wait_for_ready_to_push_ds(params) out, _err = cmd(cfg['ready_to_push_ds'] % params) fail Retry unless out['ds-seen'] end def publish_ds(params) pub_cls = Pushers[params[:dnssec_parent_authority].to_sym] fail JobFailed unless pub_cls pub = pub_cls.new(cfg) fail JobFailed unless pub.replace_ds(params[:dnssec_parent], params[:zone], params[:dss]) end def wait_for_active(params) keytag = params[:keytag] out, _err = cmd(cfg['key_activated'] % params) key_lines = out.each_line.select { |line| line.start_with?(params[:zone]) } # Check if the key is activated return if key_lines.any? {|kl| # example # KSK active 2016-12-12 18:41:33 (retire) 2048 8 b70042f966e5f01deb2e988607ad67ba SoftHSM 60076 kl.strip! _domain, _type, status, _rest = kl.split(/\s+/, 4) status == 'active' and _rest.end_with?(keytag) } fail Retry end def trigger_event(params) query = Rack::Utils.build_query(domain: params[:zone], event: params[:event]) uri = URI(cfg.values_at('webdns_base', 'update_state').join % { query: query }) - Net::HTTP.start(uri.host, uri.port) do |http| + Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http| resp = http.request Net::HTTP::Put.new(uri.request_uri) fail JobFailed if resp.code != '200' ok = JSON.parse(resp.body)['ok'] fail JobFailed if !ok end end private def cmdline(jtype, jargs) if jargs send(jtype, jargs) else send(jtype) end end end