mirror of
https://github.com/internetee/registry.git
synced 2025-08-06 01:35:10 +02:00
parent 64e3bc885a2cb8b46a1aaa4bf4f121ee7f5d44a6
author Karl Erik Õunapuu <karlerik@kreative.ee> 1591359032 +0300 committer Alex Sherman <yul.golem@gmail.com> 1617029320 +0500 CsyncJob: Don't respect IPv6 if nessecary
This commit is contained in:
parent
e46fdd57af
commit
88e1bc3727
33 changed files with 1475 additions and 119 deletions
|
@ -2,18 +2,78 @@
|
|||
|
||||
class CsyncJob < Que::Job
|
||||
def run(generate: false)
|
||||
@logger = Logger.new(STDOUT)
|
||||
generate ? generate_scanner_input : scanner_results
|
||||
@store = {}
|
||||
@input_store = { secure: {}, insecure: {} }
|
||||
@results = {}
|
||||
@logger = Rails.env.test? ? Rails.logger : Logger.new(STDOUT)
|
||||
generate ? generate_scanner_input : process_scanner_results
|
||||
|
||||
@logger.info 'CsyncJob: Finished.'
|
||||
end
|
||||
|
||||
def qualified_for_monitoring?(domain, data)
|
||||
result_types = data[:ns].map { |ns| ns[:type] }.uniq
|
||||
ns_ok = redundant_data_for?(nameserver: true, input: result_types)
|
||||
key_ok = redundant_data_for?(nameserver: false, input: data)
|
||||
|
||||
return true if ns_ok && key_ok
|
||||
|
||||
@logger.info "CsyncJob: #{domain}: Reseting state. Reason: " +
|
||||
unqualification_reason(ns_ok, key_ok, result_types)
|
||||
|
||||
CsyncRecord.where(domain: Domain.where(name: domain)).delete_all
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def redundant_data_for?(nameserver: false, input:)
|
||||
if nameserver
|
||||
input.size == 1 && (input & %w[secure insecure]).any?
|
||||
else
|
||||
input[:ns].map { |ns| ns[:cdnskey] }.uniq.size == 1
|
||||
end
|
||||
end
|
||||
|
||||
def unqualification_reason(nss, key, result_types)
|
||||
return 'no CDNSKEY / nameservers reported different CDNSKEYs' unless key
|
||||
|
||||
if result_types.include? 'untrustworthy'
|
||||
return 'current DNSSEC config invalid (required for rollover/delete)'
|
||||
end
|
||||
|
||||
"Nameserver(s) not reachable / invalid data (#{result_types.join(', ')})" unless nss
|
||||
end
|
||||
|
||||
def process_scanner_results
|
||||
scanner_results
|
||||
|
||||
@results.keys.each do |domain|
|
||||
next unless qualified_for_monitoring?(domain, @results[domain])
|
||||
|
||||
CsyncRecord.by_domain_name(domain)&.record_new_scan(@results[domain][:ns].first)
|
||||
end
|
||||
end
|
||||
|
||||
def scanner_results
|
||||
scanner_line_results.each do |fetch|
|
||||
domain_name = fetch[:domain]
|
||||
@results[domain_name] = { ns: [] } unless @results[domain_name]
|
||||
@results[domain_name][:ns] << fetch.except(:domain)
|
||||
end
|
||||
end
|
||||
|
||||
def scanner_line_results
|
||||
records = []
|
||||
File.open(ENV['cdns_scanner_output_file'], 'r').each_line do |line|
|
||||
# Input type, NS host, NS IP, Domain name, Key type, Protocol, Algorithm, Public key
|
||||
data = line.strip.split(' ')
|
||||
type, ns, ns_ip, domain, key_bit, proto, alg, pub = data
|
||||
if data[0] == 'secure'
|
||||
type, domain, key_bit, proto, alg, pub, ns, ns_ip = data
|
||||
else
|
||||
type, ns, ns_ip, domain, key_bit, proto, alg, pub = data
|
||||
end
|
||||
cdnskey = key_bit && proto && alg && pub ? "#{key_bit} #{proto} #{alg} #{pub}" : nil
|
||||
record = { domain: domain, type: type, ns: ns, ns_ip: ns_ip, key_bit: key_bit, proto: proto,
|
||||
record = { domain: domain, type: type, ns: ns, ns_ip: ns_ip, flags: key_bit, proto: proto,
|
||||
alg: alg, pub: pub, cdnskey: cdnskey }
|
||||
records << record
|
||||
end
|
||||
|
@ -23,38 +83,39 @@ class CsyncJob < Que::Job
|
|||
# From this point we're working on generating input for cdnskey-scanner
|
||||
def gather_pollable_domains
|
||||
@logger.info 'CsyncJob Generate: Gathering current domain(s) data'
|
||||
@store = { secure: {}, insecure: {} }
|
||||
Nameserver.select(:hostname, :domain_id).all.each do |ns|
|
||||
@store[:secure][ns.hostname] = [] unless @store[:secure].key? ns.hostname
|
||||
@store[:insecure][ns.hostname] = [] unless @store[:insecure].key? ns.hostname
|
||||
|
||||
Domain.where(id: ns.domain_id).all.each do |domain|
|
||||
state = domain.dnskeys.any? ? :secure : :insecure
|
||||
@store[state][ns.hostname].push domain.name
|
||||
%i[secure insecure].each do |i|
|
||||
@input_store[i][ns.hostname] = [] unless @input_store[i].key? ns.hostname
|
||||
end
|
||||
|
||||
append_domains_to_list(ns)
|
||||
end
|
||||
end
|
||||
|
||||
def append_domains_to_list(nameserver)
|
||||
Domain.where(id: nameserver.domain_id).all.each do |domain|
|
||||
@input_store[domain.dnskeys.any? ? :secure : :insecure][nameserver.hostname].push domain.name
|
||||
end
|
||||
end
|
||||
|
||||
def generate_scanner_input
|
||||
@logger.info 'CsyncJob Generate: Gathering current domain(s) data'
|
||||
gather_pollable_domains
|
||||
|
||||
@logger.info 'CsyncJob Generate: Writing input for cdnskey-scanner to ' \
|
||||
"#{ENV['cdns_scanner_input_file']}"
|
||||
out_file = File.new(ENV['cdns_scanner_input_file'], 'w+')
|
||||
|
||||
out_file.puts '[secure]'
|
||||
create_input_lines(out_file, secure: true)
|
||||
out_file.puts '[insecure]'
|
||||
create_input_lines(out_file, secure: false)
|
||||
%i[secure insecure].each do |state|
|
||||
out_file.puts "[#{state}]"
|
||||
create_input_lines(out_file, state)
|
||||
end
|
||||
|
||||
out_file.close
|
||||
@logger.info 'CsyncJob Generate: Finished writing output.'
|
||||
@logger.info 'CsyncJob Generate: Finished writing output to ' + ENV['cdns_scanner_input_file']
|
||||
end
|
||||
|
||||
def create_input_lines(out_file, secure: false)
|
||||
state = secure ? :secure : :insecure
|
||||
@store[state].keys.each do |nameserver|
|
||||
domains = @store[state][nameserver].join(' ')
|
||||
def create_input_lines(out_file, state)
|
||||
@input_store[state].keys.each do |nameserver|
|
||||
domains = @input_store[state][nameserver].join(' ')
|
||||
next unless domains.length.positive?
|
||||
|
||||
out_file.puts "#{nameserver} #{domains}"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue