From 87e8258572877f23b620fd7f76d4d35fe8da904c Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Mon, 28 Feb 2022 12:03:45 +0200 Subject: [PATCH] dnssec ans ns validation message --- app/jobs/nameserver_record_validation_job.rb | 29 +++++++++++------- app/jobs/validate_dnssec_job.rb | 30 +++++++++++-------- app/services/nameserver_validator.rb | 8 ++++- ...add_failed_validation_reasong_to_dnskey.rb | 5 ++++ db/structure.sql | 9 ++++++ .../nameserver_record_validation_job_test.rb | 15 +++++++--- 6 files changed, 69 insertions(+), 27 deletions(-) create mode 100644 db/migrate/20220228093211_add_failed_validation_reasong_to_dnskey.rb diff --git a/app/jobs/nameserver_record_validation_job.rb b/app/jobs/nameserver_record_validation_job.rb index 7dd2211a4..f737c0f36 100644 --- a/app/jobs/nameserver_record_validation_job.rb +++ b/app/jobs/nameserver_record_validation_job.rb @@ -64,12 +64,11 @@ class NameserverRecordValidationJob < ApplicationJob nameserver.save end - def add_nameserver_to_failed(nameserver:, reason:) - if nameserver.validation_counter.nil? - nameserver.validation_counter = 1 - else - nameserver.validation_counter = nameserver.validation_counter + 1 - end + def add_nameserver_to_failed(nameserver:, reason:, result_reason:) + return cname_case_handle(nameserver: nameserver, reason: reason) if result_reason == 'cname' + + nameserver.validation_counter = 1 if nameserver.validation_counter.nil? + nameserver.validation_counter = nameserver.validation_counter + 1 nameserver.failed_validation_reason = reason nameserver.save @@ -77,15 +76,25 @@ class NameserverRecordValidationJob < ApplicationJob failed_log(text: reason, nameserver: nameserver, domain: nameserver.domain) if nameserver.failed_validation? end + def cname_case_handle(nameserver:, reason:) + nameserver.validation_datetime = Time.zone.now + nameserver.failed_validation_reason = reason + nameserver.save + + failed_log(text: reason, nameserver: nameserver, domain: nameserver.domain) + end + def parse_result(result, nameserver) domain = Domain.find(nameserver.domain_id) - text = "" + text = '' case result[:reason] when 'answer' - text = "No any answer comes from **#{nameserver.hostname}**. Nameserver not exist" + text = "DNS Server **#{nameserver.hostname}** not responding" when 'serial' - text = "Serial number for nameserver hostname **#{nameserver.hostname}** doesn't present. SOA validation failed." + text = "Serial number for nameserver hostname **#{nameserver.hostname}** of #{nameserver.domain.name} doesn't present in zone. SOA validation failed." + when 'cname' + text = "Warning: SOA record expected but CNAME found instead. This setup can lead to unexpected errors when using the domain: hostname - **#{nameserver.hostname}** of #{nameserver.domain.name}" when 'not found' text = "Seems nameserver hostname **#{nameserver.hostname}** doesn't exist" when 'exception' @@ -97,7 +106,7 @@ class NameserverRecordValidationJob < ApplicationJob end logger.info text - add_nameserver_to_failed(nameserver: nameserver, reason: text) + add_nameserver_to_failed(nameserver: nameserver, reason: text, result_reason: result[:reason]) false end diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index 623513768..69168efbb 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -36,7 +36,7 @@ class ValidateDnssecJob < ApplicationJob domain.nameservers.each do |n| next unless n.validated? - validate(hostname: n.hostname, domain: domain) + validate(nameserver: n, domain: domain) notify_contacts(domain) logger.info "----------------------------" @@ -54,25 +54,26 @@ class ValidateDnssecJob < ApplicationJob # ContactNotification.notify_tech_contact(domain: domain, reason: 'dnssec') end - def validate(hostname:, domain:, type: 'DNSKEY', klass: 'IN') - resolver = prepare_validator(hostname) + def validate(nameserver:, domain:, type: 'DNSKEY', klass: 'IN') + resolver = prepare_validator(nameserver.hostname) answer = resolver.query(domain.name, type, klass) - return logger.info "no any data for #{domain.name} | hostname - #{hostname}" if answer.nil? + return logger.info "no any data for #{domain.name} | hostname - #{nameserver.hostname}" if answer.nil? logger.info "-----------" - logger.info "data for domain name - #{domain.name} | hostname - #{hostname}" + logger.info "data for domain name - #{domain.name} | hostname - #{nameserver.hostname}" logger.info "-----------" response_container = parse_response(answer) - compare_dnssec_data(response_container: response_container, domain: domain) + compare_dnssec_data(response_container: response_container, domain: domain, nameserver: nameserver) rescue Exception => e - logger.error "#{e.message} - domain name: #{domain.name} - hostname: #{hostname}" + logger.error "#{e.message} - domain name: #{domain.name} - hostname: #{nameserver.hostname}" + nameserver.update(failed_validation_reason: "#{e.message} - domain name: #{domain.name} - hostname: #{nameserver.hostname}") nil end - def compare_dnssec_data(response_container:, domain:) + def compare_dnssec_data(response_container:, domain:, nameserver:) domain.dnskeys.each do |key| next unless key.flags.to_s == '257' next if key.validation_datetime.present? @@ -82,11 +83,15 @@ class ValidateDnssecJob < ApplicationJob if flag key.validation_datetime = Time.zone.now + key.failed_validation_reason = nil key.save + nameserver.failed_validation_reason = nil + nameserver.save logger.info text + " ------->> succesfully!" else - logger.info text + " ------->> not found in zone!" + key.update!(failed_validation_reason: text + " not found in zone! Domain name - #{domain.name}. Hostname - #{nameserver.hostname}") + logger.info text + " ------->> not found in zone! Domain name - #{domain.name}. Hostname - #{nameserver.hostname}" end end end @@ -133,10 +138,11 @@ class ValidateDnssecJob < ApplicationJob inner_resolver.nameserver = nameserver inner_resolver.packet_timeout = timeouts.to_i inner_resolver.query_timeout = timeouts.to_i - resolver = Dnsruby::Recursor.new(inner_resolver) - resolver.dnssec = true + # resolver = Dnsruby::Recursor.new(inner_resolver) + # resolver.dnssec = true - resolver + # resolver + inner_resolver end def logger diff --git a/app/services/nameserver_validator.rb b/app/services/nameserver_validator.rb index c45003cd3..6436ba363 100644 --- a/app/services/nameserver_validator.rb +++ b/app/services/nameserver_validator.rb @@ -35,8 +35,14 @@ module NameserverValidator return { result: false, reason: 'answer' } if result.answer.empty? + decision = result.answer.any? do |a| + a.type == 'CNAME' + end + + return { result: false, reason: 'cname' } if decision + decision = result.answer.all? do |a| - a.serial.present? + a.instance_variable_defined? '@serial' end return { result: false, reason: 'serial' } unless decision diff --git a/db/migrate/20220228093211_add_failed_validation_reasong_to_dnskey.rb b/db/migrate/20220228093211_add_failed_validation_reasong_to_dnskey.rb new file mode 100644 index 000000000..6d61f385f --- /dev/null +++ b/db/migrate/20220228093211_add_failed_validation_reasong_to_dnskey.rb @@ -0,0 +1,5 @@ +class AddFailedValidationReasongToDnskey < ActiveRecord::Migration[6.1] + def change + add_column :dnskeys, :failed_validation_reason, :string + end +end diff --git a/db/structure.sql b/db/structure.sql index 2697c3147..5711ced26 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -814,8 +814,17 @@ CREATE TABLE public.dnskeys ( updator_str character varying, legacy_domain_id integer, updated_at timestamp without time zone, +<<<<<<< HEAD validation_datetime timestamp without time zone, failed_validation_reason character varying +======= +<<<<<<< HEAD + validation_datetime timestamp without time zone +======= + validation_datetime timestamp without time zone, + failed_validation_reason character varying +>>>>>>> dnssec ans ns validation message +>>>>>>> dnssec ans ns validation message ); diff --git a/test/jobs/nameserver_record_validation_job_test.rb b/test/jobs/nameserver_record_validation_job_test.rb index 1f39c6d33..19d1a2c9e 100644 --- a/test/jobs/nameserver_record_validation_job_test.rb +++ b/test/jobs/nameserver_record_validation_job_test.rb @@ -13,7 +13,8 @@ class NameserverRecordValidationJobTest < ActiveSupport::TestCase def test_nameserver_should_validate_succesfully_and_set_validation_datetime mock_dns_response = OpenStruct.new answer = OpenStruct.new - answer.serial = '12343' + answer.instance_variable_set(:@serial, '12345') + mock_dns_response.answer = [ answer ] Spy.on_instance_method(NameserverValidator, :setup_resolver).and_return(Dnsruby::Resolver.new) @@ -26,6 +27,8 @@ class NameserverRecordValidationJobTest < ActiveSupport::TestCase NameserverRecordValidationJob.perform_now(domain_name: @domain.name) @nameserver.reload + p @nameserver + assert_not_nil @nameserver.validation_datetime assert_nil @nameserver.validation_counter assert_nil @nameserver.failed_validation_reason @@ -47,7 +50,7 @@ class NameserverRecordValidationJobTest < ActiveSupport::TestCase assert_nil @nameserver.validation_datetime assert @nameserver.validation_counter, 1 - assert @nameserver.failed_validation_reason.include? "No any answer comes from **#{@nameserver.hostname}**" + assert @nameserver.failed_validation_reason.include? "DNS Server **#{@nameserver.hostname}**" end def test_should_return_failed_validation_with_serial_reason @@ -68,13 +71,14 @@ class NameserverRecordValidationJobTest < ActiveSupport::TestCase assert_nil @nameserver.validation_datetime assert @nameserver.validation_counter, 1 - assert @nameserver.failed_validation_reason.include? "Serial number for nameserver hostname **#{@nameserver.hostname}** doesn't present. SOA validation failed." + assert @nameserver.failed_validation_reason.include? "Serial number for nameserver hostname **#{@nameserver.hostname}** of #{@nameserver.domain.name} doesn't present in zone. SOA validation failed." end def test_after_third_invalid_times_nameserver_should_be_invalid mock_dns_response = OpenStruct.new answer = OpenStruct.new answer.some_field = '12343' + answer.type = 'SOA' mock_dns_response.answer = [ answer ] Spy.on_instance_method(NameserverValidator, :setup_resolver).and_return(Dnsruby::Resolver.new) @@ -89,9 +93,12 @@ class NameserverRecordValidationJobTest < ActiveSupport::TestCase end @nameserver.reload + + p @nameserver.failed_validation_reason + assert_nil @nameserver.validation_datetime assert @nameserver.validation_counter, 1 - assert @nameserver.failed_validation_reason.include? "Serial number for nameserver hostname **#{@nameserver.hostname}** doesn't present. SOA validation failed." + assert @nameserver.failed_validation_reason.include? "Serial number for nameserver hostname **#{@nameserver.hostname}** of #{@nameserver.domain.name} doesn't present in zone. SOA validation failed." assert @nameserver.failed_validation? end