From f637b94dbbfb15ff2092189c521313adcd29c211 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Thu, 4 Nov 2021 13:52:00 +0200 Subject: [PATCH 01/33] added validation before update --- app/interactions/actions/domain_update.rb | 45 +++++++++++++++++++++++ config/locales/en.yml | 1 + 2 files changed, 46 insertions(+) diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index 40b7876f6..3178de8c5 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -14,11 +14,56 @@ module Actions assign_new_registrant if params[:registrant] assign_relational_modifications assign_requested_statuses + validate_dnskey unless Rails.env.test? ::Actions::BaseAction.maybe_attach_legal_doc(domain, params[:legal_document]) commit end + def validate_dnskey + domain = Domain.find_by(name: @params[:domain]) + dns = prepare_resolver + update_params_info = parse_data_from_update_request(@params[:dns_keys][0]) + + domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) if domain.nameservers.empty? + + domain.nameservers.each do |n| + zone_info = parse_data_from_zonefile(dns_resolver: dns, hostname: n.hostname) + + domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) unless zone_info == update_params_info + end + + true + end + + def parse_data_from_update_request(data) + { + flags: data[:flags], + algorithm: data[:alg], + protocol: data[:protocol], + } + end + + def parse_data_from_zonefile(dns_resolver:, hostname:) + alg = dns_resolver.query(hostname, 'DS').answer[0].rdata[1] + result = dns_resolver.query(hostname, 'DNSKEY').answer[0] + + { + flags: result.flags.to_s, + algorithm: alg.to_s, + protocol: result.protocol.to_s, + } + end + + def prepare_resolver + dns = Dnsruby::Resolver.new(nameserver: ['8.8.8.8', '8.8.4.4']) + dns.do_validation = true + dns.do_caching = true + dns.dnssec = true + + dns + end + def assign_relational_modifications assign_nameserver_modifications if params[:nameservers] assign_dnssec_modifications if params[:dns_keys] diff --git a/config/locales/en.yml b/config/locales/en.yml index 31947350d..2f7e8a0aa 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -666,6 +666,7 @@ en: user_not_authenticated: "user not authenticated" actions: Actions contact_has_been_archived: 'Contact with code %{contact_code} has been archieved because it has been orphaned for longer than %{orphan_months} months.' + dns_policy_violation: "Data management policy violation: DNSKEY does not match or not found in the authoritative nameservers" number: currency: From 46042020e4bfb42e60abc134466a15323d444d9b Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Fri, 5 Nov 2021 08:35:21 +0200 Subject: [PATCH 02/33] add condition if zoen return nil answer --- app/interactions/actions/domain_update.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index 3178de8c5..ae671da70 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -14,7 +14,7 @@ module Actions assign_new_registrant if params[:registrant] assign_relational_modifications assign_requested_statuses - validate_dnskey unless Rails.env.test? + validate_dnskey unless Rails.env.test? || Rails.env.development? ::Actions::BaseAction.maybe_attach_legal_doc(domain, params[:legal_document]) commit @@ -27,10 +27,10 @@ module Actions domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) if domain.nameservers.empty? - domain.nameservers.each do |n| - zone_info = parse_data_from_zonefile(dns_resolver: dns, hostname: n.hostname) + zone_info = parse_data_from_zonefile(dns_resolver: dns, hostname: domain.name) - domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) unless zone_info == update_params_info + unless zone_info == update_params_info || zone_info.nil? + domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) end true @@ -46,12 +46,14 @@ module Actions def parse_data_from_zonefile(dns_resolver:, hostname:) alg = dns_resolver.query(hostname, 'DS').answer[0].rdata[1] - result = dns_resolver.query(hostname, 'DNSKEY').answer[0] + result = dns_resolver.query(hostname, 'DNSKEY').answer + + return nil if answer.empty? { - flags: result.flags.to_s, + flags: result[0].flags.to_s, algorithm: alg.to_s, - protocol: result.protocol.to_s, + protocol: result[0].protocol.to_s, } end From ff2531ac1f2f76171660a6b48b748e857ae51e1b Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Tue, 16 Nov 2021 12:53:43 +0200 Subject: [PATCH 03/33] added dns_servers_keys in application.yml.sample --- app/interactions/actions/domain_update.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index ae671da70..aa310f052 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -58,7 +58,8 @@ module Actions end def prepare_resolver - dns = Dnsruby::Resolver.new(nameserver: ['8.8.8.8', '8.8.4.4']) + dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) + dns = Dnsruby::Resolver.new(nameserver: dns_servers || ['8.8.8.8, 8.8.4.4']) dns.do_validation = true dns.do_caching = true dns.dnssec = true From 9e023354520bc05d5078aec2376de3653e61ac73 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Tue, 16 Nov 2021 15:36:40 +0200 Subject: [PATCH 04/33] hardcoded ip_resolver for test purpose --- app/interactions/actions/domain_update.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index aa310f052..86d6a43f1 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -14,7 +14,7 @@ module Actions assign_new_registrant if params[:registrant] assign_relational_modifications assign_requested_statuses - validate_dnskey unless Rails.env.test? || Rails.env.development? + validate_dnskey unless Rails.env.test? ::Actions::BaseAction.maybe_attach_legal_doc(domain, params[:legal_document]) commit @@ -59,7 +59,7 @@ module Actions def prepare_resolver dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) - dns = Dnsruby::Resolver.new(nameserver: dns_servers || ['8.8.8.8, 8.8.4.4']) + dns = Dnsruby::Resolver.new({nameserver: ['192.168.99.97']}) dns.do_validation = true dns.do_caching = true dns.dnssec = true From 1c1c28a55c9f51075bbdedbbc0b63f42e30895c1 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Tue, 16 Nov 2021 16:32:29 +0200 Subject: [PATCH 05/33] updated error handler --- app/interactions/actions/domain_update.rb | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index 86d6a43f1..91c41fcde 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -21,7 +21,7 @@ module Actions end def validate_dnskey - domain = Domain.find_by(name: @params[:domain]) + # domain = Domain.find_by(name: @params[:domain]) dns = prepare_resolver update_params_info = parse_data_from_update_request(@params[:dns_keys][0]) @@ -45,16 +45,20 @@ module Actions end def parse_data_from_zonefile(dns_resolver:, hostname:) - alg = dns_resolver.query(hostname, 'DS').answer[0].rdata[1] - result = dns_resolver.query(hostname, 'DNSKEY').answer + begin + alg = dns_resolver.query(hostname, 'DS').answer[0].rdata[1] + result = dns_resolver.query(hostname, 'DNSKEY').answer - return nil if answer.empty? + return nil if answer.empty? - { - flags: result[0].flags.to_s, - algorithm: alg.to_s, - protocol: result[0].protocol.to_s, - } + { + flags: result[0].flags.to_s, + algorithm: alg.to_s, + protocol: result[0].protocol.to_s, + } + rescue Dnsruby::NXDomain + domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) + end end def prepare_resolver From e34d84103ca82bdf2a013e9e93a6f8a1a7bbd9b3 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Tue, 23 Nov 2021 10:28:39 +0200 Subject: [PATCH 06/33] tests --- app/interactions/actions/domain_update.rb | 161 +++++++++++++++------- 1 file changed, 109 insertions(+), 52 deletions(-) diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index 91c41fcde..81c9953aa 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -14,63 +14,12 @@ module Actions assign_new_registrant if params[:registrant] assign_relational_modifications assign_requested_statuses - validate_dnskey unless Rails.env.test? + validate_dnssec unless Rails.env.test? ::Actions::BaseAction.maybe_attach_legal_doc(domain, params[:legal_document]) commit end - def validate_dnskey - # domain = Domain.find_by(name: @params[:domain]) - dns = prepare_resolver - update_params_info = parse_data_from_update_request(@params[:dns_keys][0]) - - domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) if domain.nameservers.empty? - - zone_info = parse_data_from_zonefile(dns_resolver: dns, hostname: domain.name) - - unless zone_info == update_params_info || zone_info.nil? - domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) - end - - true - end - - def parse_data_from_update_request(data) - { - flags: data[:flags], - algorithm: data[:alg], - protocol: data[:protocol], - } - end - - def parse_data_from_zonefile(dns_resolver:, hostname:) - begin - alg = dns_resolver.query(hostname, 'DS').answer[0].rdata[1] - result = dns_resolver.query(hostname, 'DNSKEY').answer - - return nil if answer.empty? - - { - flags: result[0].flags.to_s, - algorithm: alg.to_s, - protocol: result[0].protocol.to_s, - } - rescue Dnsruby::NXDomain - domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) - end - end - - def prepare_resolver - dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) - dns = Dnsruby::Resolver.new({nameserver: ['192.168.99.97']}) - dns.do_validation = true - dns.do_caching = true - dns.dnssec = true - - dns - end - def assign_relational_modifications assign_nameserver_modifications if params[:nameservers] assign_dnssec_modifications if params[:dns_keys] @@ -165,6 +114,114 @@ module Actions end end + # ============================ + # str.unpack("H*").first + # irb(main):111:0> res.answer[0].public_key.to_jwk + # => {"kty"=>:EC, "crv"=>:"P-256", "x"=>"Qib532jY06DaPgJQP9k4B8hjYGMKxgICf_QxsIxLp_A", "y"=>"A67HVgWBrj1mEkIT7OJxXAY263DFf5t7gu7a1hNUzw4", "kid"=>"rzgBwFog0-1Eopl1J9kBm0YU8lEsws_jJnh-Se8UcAg"} + # вот этат x и есть public key + # irb(main):122:0> res.answer[0].public_key.export + # => "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQib532jY06DaPgJQP9k4B8hjYGMK\nxgICf/QxsIxLp/ADrsdWBYGuPWYSQhPs4nFcBjbrcMV/m3uC7trWE1TPDg==\n-----END PUBLIC KEY-----\n" + + def prepare_resolver + dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) + dns = Dnsruby::Resolver.new({nameserver: ['192.168.99.97']}) + dns.do_validation = true + dns.do_caching = true + dns.dnssec = true + + dns + end + + def validate_dnssec + dns = prepare_resolver + ds_record = dns.query(@params[:domain], 'DS').answer[0].rdata + ds_digest = dns.query(@params[:domain], 'DS').answer[0].digest + + p "++++++++++++++" + p ds_digest.upcase! + # @params[:dns_keys][0] + p generate_ds_digest(@params[:dns_keys][0]) + p "++++++++++++++" + end + + def generate_ds_digest(data) + flags_hex = int_to_hex(data[:flags].to_i) + protocol_hex = int_to_hex(data[:protocol].to_i) + alg_hex = int_to_hex(data[:alg].to_i) + public_key_hex = bin_to_hex(Base64.decode64(data[:public_key])) + + domain = Domain.find_by(name: @params[:domain]) + + hex = [domain.name_in_wire_format, flags_hex, protocol_hex, alg_hex, public_key_hex].join + bin = hex_to_bin(hex) + + ds_digest_type = Setting.ds_digest_type if ds_digest_type.blank? || !DS_DIGEST_TYPE.include?(ds_digest_type) + + case ds_digest_type + when 1 + ds_digest = Digest::SHA1.hexdigest(bin).upcase + when 2 + ds_digest = Digest::SHA256.hexdigest(bin).upcase + end + + ds_digest + end + + def int_to_hex(num) + num = num.to_s(16) + num.prepend('0') if num.length.odd? + end + + def hex_to_bin(num) + num.scan(/../).map(&:hex).pack('c*') + end + + def bin_to_hex(num) + num.each_byte.map { |b| format('%02X', b) }.join + end + + # + # def validate_dnskey + # # domain = Domain.find_by(name: @params[:domain]) + # dns = prepare_resolver + # update_params_info = parse_data_from_update_request(@params[:dns_keys][0]) + # + # domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) if domain.nameservers.empty? + # + # zone_info = parse_data_from_zonefile(dns_resolver: dns, hostname: domain.name) + # + # unless zone_info == update_params_info || zone_info.nil? + # domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) + # end + # + # true + # end + # + # def parse_data_from_update_request(data) + # { + # flags: data[:flags], + # algorithm: data[:alg], + # protocol: data[:protocol], + # } + # end + # + # def parse_data_from_zonefile(dns_resolver:, hostname:) + # begin + # alg = dns_resolver.query(hostname, 'DS').answer[0].rdata[1] + # result = dns_resolver.query(hostname, 'DNSKEY').answer + # + # return nil if answer.empty? + # + # { + # flags: result[0].flags.to_s, + # algorithm: alg.to_s, + # protocol: result[0].protocol.to_s, + # } + # rescue Dnsruby::NXDomain + # domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) + # end + # end + def assign_removable_dnskey(key) dnkey = domain.dnskeys.find_by(key.except(:action)) domain.add_epp_error(2303, nil, nil, %i[dnskeys not_found]) unless dnkey From 6527ef6e607dc8f805f8f12d7ab596d989752dd4 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 24 Nov 2021 16:40:00 +0200 Subject: [PATCH 07/33] updated dns check of dubzone --- app/interactions/actions/domain_update.rb | 140 ++++++++++------------ 1 file changed, 60 insertions(+), 80 deletions(-) diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index 81c9953aa..da74a538e 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -114,14 +114,6 @@ module Actions end end - # ============================ - # str.unpack("H*").first - # irb(main):111:0> res.answer[0].public_key.to_jwk - # => {"kty"=>:EC, "crv"=>:"P-256", "x"=>"Qib532jY06DaPgJQP9k4B8hjYGMKxgICf_QxsIxLp_A", "y"=>"A67HVgWBrj1mEkIT7OJxXAY263DFf5t7gu7a1hNUzw4", "kid"=>"rzgBwFog0-1Eopl1J9kBm0YU8lEsws_jJnh-Se8UcAg"} - # вот этат x и есть public key - # irb(main):122:0> res.answer[0].public_key.export - # => "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQib532jY06DaPgJQP9k4B8hjYGMK\nxgICf/QxsIxLp/ADrsdWBYGuPWYSQhPs4nFcBjbrcMV/m3uC7trWE1TPDg==\n-----END PUBLIC KEY-----\n" - def prepare_resolver dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) dns = Dnsruby::Resolver.new({nameserver: ['192.168.99.97']}) @@ -134,93 +126,81 @@ module Actions def validate_dnssec dns = prepare_resolver - ds_record = dns.query(@params[:domain], 'DS').answer[0].rdata - ds_digest = dns.query(@params[:domain], 'DS').answer[0].digest + subzone_records = get_dnskey_records_from_subzone(resolver: dns, hostname: @params[:domain]) + form_extension_records = extensional_dnskeys_data - p "++++++++++++++" - p ds_digest.upcase! - # @params[:dns_keys][0] - p generate_ds_digest(@params[:dns_keys][0]) - p "++++++++++++++" + validate_data(subzone_records: subzone_records, form_extension_records: form_extension_records) end - def generate_ds_digest(data) - flags_hex = int_to_hex(data[:flags].to_i) - protocol_hex = int_to_hex(data[:protocol].to_i) - alg_hex = int_to_hex(data[:alg].to_i) - public_key_hex = bin_to_hex(Base64.decode64(data[:public_key])) + def make_magic(subzone_records:, form_data:) + subzone_records.any? do |subzone_data| + subzone_data[:basic] == form_data[:basic] && + subzone_data[:public_key].include?(form_data[:public_key]) + end + end - domain = Domain.find_by(name: @params[:domain]) + def validate_data(subzone_records:, form_extension_records:) - hex = [domain.name_in_wire_format, flags_hex, protocol_hex, alg_hex, public_key_hex].join - bin = hex_to_bin(hex) + flag = false + form_extension_records.each do |form_data| + flag = make_magic(subzone_records: subzone_records, form_data: form_data) - ds_digest_type = Setting.ds_digest_type if ds_digest_type.blank? || !DS_DIGEST_TYPE.include?(ds_digest_type) - - case ds_digest_type - when 1 - ds_digest = Digest::SHA1.hexdigest(bin).upcase - when 2 - ds_digest = Digest::SHA256.hexdigest(bin).upcase + break if flag end - ds_digest + return validation_dns_key_error unless flag + + flag end - def int_to_hex(num) - num = num.to_s(16) - num.prepend('0') if num.length.odd? + def get_dnskey_records_from_subzone(resolver:, hostname:) + begin + ds_records_answers = resolver.query(hostname, 'DNSKEY').answer + + result_container = [] + + ds_records_answers.each do |ds| + next unless ds.type == Dnsruby::Types.DNSKEY + + result_container << { + basic: { + flags: ds.flags.to_s, + algorithm: ds.algorithm.code.to_s, + protocol: ds.protocol.to_s + }, + public_key: ds.public_key.export.gsub!(/\s+/, '') + } + end + + return result_container + + rescue Dnsruby::NXDomain + domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) + end end - def hex_to_bin(num) - num.scan(/../).map(&:hex).pack('c*') + def validation_dns_key_error + domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) end - def bin_to_hex(num) - num.each_byte.map { |b| format('%02X', b) }.join - end + def extensional_dnskeys_data + dnskeys_data = @params[:dns_keys] - # - # def validate_dnskey - # # domain = Domain.find_by(name: @params[:domain]) - # dns = prepare_resolver - # update_params_info = parse_data_from_update_request(@params[:dns_keys][0]) - # - # domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) if domain.nameservers.empty? - # - # zone_info = parse_data_from_zonefile(dns_resolver: dns, hostname: domain.name) - # - # unless zone_info == update_params_info || zone_info.nil? - # domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) - # end - # - # true - # end - # - # def parse_data_from_update_request(data) - # { - # flags: data[:flags], - # algorithm: data[:alg], - # protocol: data[:protocol], - # } - # end - # - # def parse_data_from_zonefile(dns_resolver:, hostname:) - # begin - # alg = dns_resolver.query(hostname, 'DS').answer[0].rdata[1] - # result = dns_resolver.query(hostname, 'DNSKEY').answer - # - # return nil if answer.empty? - # - # { - # flags: result[0].flags.to_s, - # algorithm: alg.to_s, - # protocol: result[0].protocol.to_s, - # } - # rescue Dnsruby::NXDomain - # domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) - # end - # end + result_container = [] + + dnskeys_data.each do |ds| + result_container << { + basic: { + flags: ds[:flags].to_s, + algorithm: ds[:alg].to_s, + protocol: ds[:protocol].to_s, + }, + public_key: ds[:public_key] + } + end + + result_container + end def assign_removable_dnskey(key) dnkey = domain.dnskeys.find_by(key.except(:action)) From a49da009663dab95436ac608c666c912c1830e21 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Thu, 25 Nov 2021 12:57:13 +0200 Subject: [PATCH 08/33] dnskey can be removed --- app/interactions/actions/domain_update.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index da74a538e..7bea60ccb 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -124,11 +124,17 @@ module Actions dns end + # {:domain=>"dnssec.ee", :registrar_id=>2, :dns_keys=>[{:flags=>"256", :protocol=>"3", :alg=>"13", :public_key=>"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6JSqRM8bzEhp7jJbpor44JjEXPfsLBEEFviJ1fnRl85XrT9QiLtmkWk8/YcQggenUxWPvbkmFGbP17wsrbrKyg==", :action=>"rem"}]} + def validate_dnssec + return if @params[:action] == 'rem' + dns = prepare_resolver subzone_records = get_dnskey_records_from_subzone(resolver: dns, hostname: @params[:domain]) form_extension_records = extensional_dnskeys_data + return true if form_extension_records.empty? + validate_data(subzone_records: subzone_records, form_extension_records: form_extension_records) end @@ -143,6 +149,7 @@ module Actions flag = false form_extension_records.each do |form_data| + flag = make_magic(subzone_records: subzone_records, form_data: form_data) break if flag @@ -189,6 +196,8 @@ module Actions result_container = [] dnskeys_data.each do |ds| + next if ds[:action] == 'rem' + result_container << { basic: { flags: ds[:flags].to_s, From 6dc552536e19d279dc2a7c022991b3a16f93a11d Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Thu, 25 Nov 2021 13:20:01 +0200 Subject: [PATCH 09/33] added conditions if form data is empty --- app/interactions/actions/domain_update.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index 7bea60ccb..bf197f296 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -193,6 +193,8 @@ module Actions def extensional_dnskeys_data dnskeys_data = @params[:dns_keys] + return [] if dnskeys_data.nil? + result_container = [] dnskeys_data.each do |ds| From 9b07b5ff0f75023e915628c88b155744f0de7852 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Fri, 31 Dec 2021 11:18:06 +0200 Subject: [PATCH 10/33] refactored --- app/interactions/actions/domain_update.rb | 31 +++++++++-------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index bf197f296..efd63e96f 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -116,7 +116,7 @@ module Actions def prepare_resolver dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) - dns = Dnsruby::Resolver.new({nameserver: ['192.168.99.97']}) + dns = Dnsruby::Resolver.new({ nameserver: dns_servers }) dns.do_validation = true dns.do_caching = true dns.dnssec = true @@ -124,8 +124,6 @@ module Actions dns end - # {:domain=>"dnssec.ee", :registrar_id=>2, :dns_keys=>[{:flags=>"256", :protocol=>"3", :alg=>"13", :public_key=>"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6JSqRM8bzEhp7jJbpor44JjEXPfsLBEEFviJ1fnRl85XrT9QiLtmkWk8/YcQggenUxWPvbkmFGbP17wsrbrKyg==", :action=>"rem"}]} - def validate_dnssec return if @params[:action] == 'rem' @@ -146,10 +144,8 @@ module Actions end def validate_data(subzone_records:, form_extension_records:) - flag = false form_extension_records.each do |form_data| - flag = make_magic(subzone_records: subzone_records, form_data: form_data) break if flag @@ -161,7 +157,6 @@ module Actions end def get_dnskey_records_from_subzone(resolver:, hostname:) - begin ds_records_answers = resolver.query(hostname, 'DNSKEY').answer result_container = [] @@ -173,17 +168,15 @@ module Actions basic: { flags: ds.flags.to_s, algorithm: ds.algorithm.code.to_s, - protocol: ds.protocol.to_s + protocol: ds.protocol.to_s, }, - public_key: ds.public_key.export.gsub!(/\s+/, '') + public_key: ds.public_key.export.gsub!(/\s+/, ''), } end - return result_container - - rescue Dnsruby::NXDomain - domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) - end + result_container + rescue Dnsruby::NXDomain + domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) end def validation_dns_key_error @@ -201,12 +194,12 @@ module Actions next if ds[:action] == 'rem' result_container << { - basic: { - flags: ds[:flags].to_s, - algorithm: ds[:alg].to_s, - protocol: ds[:protocol].to_s, - }, - public_key: ds[:public_key] + basic: { + flags: ds[:flags].to_s, + algorithm: ds[:alg].to_s, + protocol: ds[:protocol].to_s, + }, + public_key: ds[:public_key], } end From ae269c6772caafce1fe363ee6bc3645b5bbd4da8 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Fri, 31 Dec 2021 13:03:17 +0200 Subject: [PATCH 11/33] move on functionality for separate service object and updated tests --- app/interactions/actions/domain_update.rb | 94 +----------------- app/services/validate_dnssec.rb | 97 +++++++++++++++++++ .../registrant_api_verifications_test.rb | 2 +- .../epp/domain/update/base_test.rb | 1 + .../epp/domain/update/rem_dns_test.rb | 1 + .../repp/v1/domains/contacts_test.rb | 1 + .../repp/v1/domains/dnssec_test.rb | 1 + .../repp/v1/domains/nameservers_test.rb | 1 + .../repp/v1/domains/update_test.rb | 1 + test/jobs/domain_update_confirm_job_test.rb | 1 + 10 files changed, 106 insertions(+), 94 deletions(-) create mode 100644 app/services/validate_dnssec.rb diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index efd63e96f..505989c06 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -14,7 +14,7 @@ module Actions assign_new_registrant if params[:registrant] assign_relational_modifications assign_requested_statuses - validate_dnssec unless Rails.env.test? + ValidateDnssec.validate_dnssec(params: params, domain: domain) ::Actions::BaseAction.maybe_attach_legal_doc(domain, params[:legal_document]) commit @@ -114,98 +114,6 @@ module Actions end end - def prepare_resolver - dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) - dns = Dnsruby::Resolver.new({ nameserver: dns_servers }) - dns.do_validation = true - dns.do_caching = true - dns.dnssec = true - - dns - end - - def validate_dnssec - return if @params[:action] == 'rem' - - dns = prepare_resolver - subzone_records = get_dnskey_records_from_subzone(resolver: dns, hostname: @params[:domain]) - form_extension_records = extensional_dnskeys_data - - return true if form_extension_records.empty? - - validate_data(subzone_records: subzone_records, form_extension_records: form_extension_records) - end - - def make_magic(subzone_records:, form_data:) - subzone_records.any? do |subzone_data| - subzone_data[:basic] == form_data[:basic] && - subzone_data[:public_key].include?(form_data[:public_key]) - end - end - - def validate_data(subzone_records:, form_extension_records:) - flag = false - form_extension_records.each do |form_data| - flag = make_magic(subzone_records: subzone_records, form_data: form_data) - - break if flag - end - - return validation_dns_key_error unless flag - - flag - end - - def get_dnskey_records_from_subzone(resolver:, hostname:) - ds_records_answers = resolver.query(hostname, 'DNSKEY').answer - - result_container = [] - - ds_records_answers.each do |ds| - next unless ds.type == Dnsruby::Types.DNSKEY - - result_container << { - basic: { - flags: ds.flags.to_s, - algorithm: ds.algorithm.code.to_s, - protocol: ds.protocol.to_s, - }, - public_key: ds.public_key.export.gsub!(/\s+/, ''), - } - end - - result_container - rescue Dnsruby::NXDomain - domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) - end - - def validation_dns_key_error - domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) - end - - def extensional_dnskeys_data - dnskeys_data = @params[:dns_keys] - - return [] if dnskeys_data.nil? - - result_container = [] - - dnskeys_data.each do |ds| - next if ds[:action] == 'rem' - - result_container << { - basic: { - flags: ds[:flags].to_s, - algorithm: ds[:alg].to_s, - protocol: ds[:protocol].to_s, - }, - public_key: ds[:public_key], - } - end - - result_container - end - def assign_removable_dnskey(key) dnkey = domain.dnskeys.find_by(key.except(:action)) domain.add_epp_error(2303, nil, nil, %i[dnskeys not_found]) unless dnkey diff --git a/app/services/validate_dnssec.rb b/app/services/validate_dnssec.rb new file mode 100644 index 000000000..1cc2a9422 --- /dev/null +++ b/app/services/validate_dnssec.rb @@ -0,0 +1,97 @@ +module ValidateDnssec + include Dnsruby + + extend self + + def prepare_resolver + dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) + dns = Dnsruby::Resolver.new({ nameserver: dns_servers }) + dns.do_validation = false + dns.do_caching = false + dns.dnssec = true + + dns + end + + def validate_dnssec(params:, domain:) + return if params[:action] == 'rem' + + dns = prepare_resolver + subzone_records = get_dnskey_records_from_subzone(resolver: dns, hostname: params[:domain], domain: domain) + form_extension_records = extensional_dnskeys_data(params) + + return true if form_extension_records.empty? + + validate_data(subzone_records: subzone_records, form_extension_records: form_extension_records, domain: domain) + end + + def make_magic(subzone_records:, form_data:) + subzone_records.any? do |subzone_data| + subzone_data[:basic] == form_data[:basic] && + subzone_data[:public_key].include?(form_data[:public_key]) + end + end + + def validate_data(subzone_records:, form_extension_records:, domain:) + flag = false + form_extension_records.each do |form_data| + flag = make_magic(subzone_records: subzone_records, form_data: form_data) + + break if flag + end + + return validation_dns_key_error(domain) unless flag + + flag + end + + def get_dnskey_records_from_subzone(resolver:, hostname:, domain:) + ds_records_answers = resolver.query(hostname, 'DNSKEY').answer + + result_container = [] + + ds_records_answers.each do |ds| + next unless ds.type == Dnsruby::Types.DNSKEY + + result_container << { + basic: { + flags: ds.flags.to_s, + algorithm: ds.algorithm.code.to_s, + protocol: ds.protocol.to_s, + }, + public_key: ds.public_key.export.gsub!(/\s+/, ''), + } + end + + result_container + rescue Dnsruby::NXDomain + domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) + end + + def validation_dns_key_error(domain) + domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) + end + + def extensional_dnskeys_data(params) + dnskeys_data = params[:dns_keys] + + return [] if dnskeys_data.nil? + + result_container = [] + + dnskeys_data.each do |ds| + next if ds[:action] == 'rem' + + result_container << { + basic: { + flags: ds[:flags].to_s, + algorithm: ds[:alg].to_s, + protocol: ds[:protocol].to_s, + }, + public_key: ds[:public_key], + } + end + + result_container + end +end diff --git a/test/integration/api/registrant/registrant_api_verifications_test.rb b/test/integration/api/registrant/registrant_api_verifications_test.rb index 821d0dee0..8db49410f 100644 --- a/test/integration/api/registrant/registrant_api_verifications_test.rb +++ b/test/integration/api/registrant/registrant_api_verifications_test.rb @@ -15,7 +15,7 @@ class RegistrantApiVerificationsTest < ApplicationIntegrationTest @domain.update!(statuses: [DomainStatus::PENDING_UPDATE], registrant_verification_asked_at: Time.zone.now - 1.day, registrant_verification_token: @token) - + Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end def test_fetches_registrant_change_request diff --git a/test/integration/epp/domain/update/base_test.rb b/test/integration/epp/domain/update/base_test.rb index d021b496d..aaa7e1767 100644 --- a/test/integration/epp/domain/update/base_test.rb +++ b/test/integration/epp/domain/update/base_test.rb @@ -10,6 +10,7 @@ class EppDomainUpdateBaseTest < EppTestCase @original_registrant_change_verification = Setting.request_confirmation_on_registrant_change_enabled ActionMailer::Base.deliveries.clear + Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end teardown do diff --git a/test/integration/epp/domain/update/rem_dns_test.rb b/test/integration/epp/domain/update/rem_dns_test.rb index 6e079b126..ecd660fa6 100644 --- a/test/integration/epp/domain/update/rem_dns_test.rb +++ b/test/integration/epp/domain/update/rem_dns_test.rb @@ -12,6 +12,7 @@ class EppDomainUpdateRemDnsTest < EppTestCase @original_registrant_change_verification = Setting.request_confirmation_on_registrant_change_enabled ActionMailer::Base.deliveries.clear + Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end teardown do diff --git a/test/integration/repp/v1/domains/contacts_test.rb b/test/integration/repp/v1/domains/contacts_test.rb index b9b26a745..540514853 100644 --- a/test/integration/repp/v1/domains/contacts_test.rb +++ b/test/integration/repp/v1/domains/contacts_test.rb @@ -8,6 +8,7 @@ class ReppV1DomainsContactsTest < ActionDispatch::IntegrationTest token = "Basic #{token}" @auth_headers = { 'Authorization' => token } + Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end def test_shows_existing_domain_contacts diff --git a/test/integration/repp/v1/domains/dnssec_test.rb b/test/integration/repp/v1/domains/dnssec_test.rb index 6835e2600..79480c3b8 100644 --- a/test/integration/repp/v1/domains/dnssec_test.rb +++ b/test/integration/repp/v1/domains/dnssec_test.rb @@ -8,6 +8,7 @@ class ReppV1DomainsDnssecTest < ActionDispatch::IntegrationTest token = "Basic #{token}" @auth_headers = { 'Authorization' => token } + Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end def test_shows_dnssec_keys_associated_with_domain diff --git a/test/integration/repp/v1/domains/nameservers_test.rb b/test/integration/repp/v1/domains/nameservers_test.rb index 780e889c1..4c7a1dcc5 100644 --- a/test/integration/repp/v1/domains/nameservers_test.rb +++ b/test/integration/repp/v1/domains/nameservers_test.rb @@ -8,6 +8,7 @@ class ReppV1DomainsNameserversTest < ActionDispatch::IntegrationTest token = "Basic #{token}" @auth_headers = { 'Authorization' => token } + Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end def test_can_add_new_nameserver diff --git a/test/integration/repp/v1/domains/update_test.rb b/test/integration/repp/v1/domains/update_test.rb index d924fe7a3..595d094fe 100644 --- a/test/integration/repp/v1/domains/update_test.rb +++ b/test/integration/repp/v1/domains/update_test.rb @@ -8,6 +8,7 @@ class ReppV1DomainsUpdateTest < ActionDispatch::IntegrationTest token = "Basic #{token}" @auth_headers = { 'Authorization' => token } + Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end def test_updates_transfer_code_for_domain diff --git a/test/jobs/domain_update_confirm_job_test.rb b/test/jobs/domain_update_confirm_job_test.rb index 158729ae3..a5999cd36 100644 --- a/test/jobs/domain_update_confirm_job_test.rb +++ b/test/jobs/domain_update_confirm_job_test.rb @@ -14,6 +14,7 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase new_registrant_name: @new_registrant.name, new_registrant_email: @new_registrant.email, current_user_id: @user.id }) + Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end def teardown From b2519b86a423eccb72d8a84a20a35a51f25a0d7d Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Fri, 31 Dec 2021 13:34:58 +0200 Subject: [PATCH 12/33] added test for service dnssec validate object --- test/services/validate_dnssec_test.rb | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 test/services/validate_dnssec_test.rb diff --git a/test/services/validate_dnssec_test.rb b/test/services/validate_dnssec_test.rb new file mode 100644 index 000000000..b3e939ee4 --- /dev/null +++ b/test/services/validate_dnssec_test.rb @@ -0,0 +1,48 @@ +require 'test_helper' + +class ValidateDnssecTest < ActiveSupport::TestCase + setup do + @dnskey = dnskeys(:one) + @domain = domains(:shop) + + @result_container = [{ + basic: { + flags: @dnskey.flags.to_s, + algorithm: @dnskey.alg.to_s, + protocol: @dnskey.protocol.to_s, + }, + public_key: @dnskey.public_key.to_s + }] + + Spy.on_instance_method(ValidateDnssec, :validation_dns_key_error).and_return(false) + end + + def test_should_return_true_if_dnssec_data_are_matches + Spy.on_instance_method(ValidateDnssec, :get_dnskey_records_from_subzone).and_return(@result_container) + match_params = build_params(@dnskey.flags) + validate_result = ValidateDnssec.validate_dnssec(params: match_params, domain: @domain) + + assert validate_result + end + + def test_should_return_false_if_dnssec_data_does_not_matcher + Spy.on_instance_method(ValidateDnssec, :get_dnskey_records_from_subzone).and_return(@result_container) + match_params = build_params(256) + validate_result = ValidateDnssec.validate_dnssec(params: match_params, domain: @domain) + + refute validate_result + end + + def build_params(flag) + { + action: "add", + domain: @domain, + dns_keys: [{ + flags: flag, + alg: @dnskey.alg, + protocol: @dnskey.protocol, + public_key: @dnskey.public_key + }] + } + end +end From 8a6ea167c251b2f5183653aa5c123d8cd8e5f92d Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Mon, 3 Jan 2022 13:52:25 +0200 Subject: [PATCH 13/33] added new field to nameserver and job --- app/interactions/actions/domain_update.rb | 2 +- app/jobs/validate_dnssec.rb | 25 +++++++++++++++++++ ...13934_add_validation_datetime_to_dnskey.rb | 5 ++++ db/structure.sql | 1 + 4 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 app/jobs/validate_dnssec.rb create mode 100644 db/migrate/20211231113934_add_validation_datetime_to_dnskey.rb diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index 505989c06..2e44a015c 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -14,7 +14,7 @@ module Actions assign_new_registrant if params[:registrant] assign_relational_modifications assign_requested_statuses - ValidateDnssec.validate_dnssec(params: params, domain: domain) + # ValidateDnssec.validate_dnssec(params: params, domain: domain) ::Actions::BaseAction.maybe_attach_legal_doc(domain, params[:legal_document]) commit diff --git a/app/jobs/validate_dnssec.rb b/app/jobs/validate_dnssec.rb new file mode 100644 index 000000000..286495f23 --- /dev/null +++ b/app/jobs/validate_dnssec.rb @@ -0,0 +1,25 @@ +class ValidateDnssecJob < ApplicationJob + discard_on StandardError + + def perform(domain_name:) + + rescue StandardError => e + logger.error e.message + raise e + end + + private + + def prepare_resolver + dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) + dns = Dnsruby::Resolver.new({ nameserver: dns_servers }) + dns.do_validation = false + dns.do_caching = false + dns.dnssec = true + + dns + end + + + +end diff --git a/db/migrate/20211231113934_add_validation_datetime_to_dnskey.rb b/db/migrate/20211231113934_add_validation_datetime_to_dnskey.rb new file mode 100644 index 000000000..a0ad82332 --- /dev/null +++ b/db/migrate/20211231113934_add_validation_datetime_to_dnskey.rb @@ -0,0 +1,5 @@ +class AddValidationDatetimeToDnskey < ActiveRecord::Migration[6.1] + def change + add_column :dnskeys, :validation_datetime, :datetime + end +end diff --git a/db/structure.sql b/db/structure.sql index 9afc1742f..4403facfb 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -5398,3 +5398,4 @@ INSERT INTO "schema_migrations" (version) VALUES ('20220106123143'); + From dd59fc76e21c7b40c1afdced1f162c597335fbbc Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Mon, 3 Jan 2022 14:58:26 +0200 Subject: [PATCH 14/33] added job --- app/jobs/validate_dnssec.rb | 25 --------- app/jobs/validate_dnssec_job.rb | 93 +++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 25 deletions(-) delete mode 100644 app/jobs/validate_dnssec.rb create mode 100644 app/jobs/validate_dnssec_job.rb diff --git a/app/jobs/validate_dnssec.rb b/app/jobs/validate_dnssec.rb deleted file mode 100644 index 286495f23..000000000 --- a/app/jobs/validate_dnssec.rb +++ /dev/null @@ -1,25 +0,0 @@ -class ValidateDnssecJob < ApplicationJob - discard_on StandardError - - def perform(domain_name:) - - rescue StandardError => e - logger.error e.message - raise e - end - - private - - def prepare_resolver - dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) - dns = Dnsruby::Resolver.new({ nameserver: dns_servers }) - dns.do_validation = false - dns.do_caching = false - dns.dnssec = true - - dns - end - - - -end diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb new file mode 100644 index 000000000..de818280f --- /dev/null +++ b/app/jobs/validate_dnssec_job.rb @@ -0,0 +1,93 @@ +class ValidateDnssecJob < ApplicationJob + discard_on StandardError + + def perform(domain_name: nil) + unless domain_name.nil? + domain = Domain.find_by(name: domain_name) + + return logger.info "No domain found" if domain.nil? + + return logger.info "No related dnskeys for this domain" if domain.dnskeys.empty? + + flag = iterate_domain_data(domain: domain) + logger.info "#{domain_name} " + log_templates[flag.to_s] + else + Dnskey.all.each do |key| + domain = Domain.find(key.domain_id) + + flag = iterate_domain_data(domain: domain) + logger.info "#{domain.name} " + log_templates[flag.to_s] + end + end + rescue StandardError => e + logger.error e.message + raise e + end + + private + + def iterate_domain_data(domain:) + zone_datas = get_data_from_zone(domain: domain) + flag = domain.dnskeys.all? { |key| validate(zone_datas: zone_datas, domain_dnskey: key) } + + flag + end + + def get_data_from_zone(domain:) + resolver = prepare_resolver + ds_records_answers = resolver.query(domain.name, 'DNSKEY').answer + + result_container = [] + + ds_records_answers.each do |ds| + next unless ds.type == Dnsruby::Types.DNSKEY + + result_container << { + flags: ds.flags.to_s, + algorithm: ds.algorithm.code.to_s, + protocol: ds.protocol.to_s, + public_key: ds.public_key.export.gsub!(/\s+/, ''), + } + end + + result_container + rescue Dnsruby::NXDomain + domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) + end + + def validate(zone_datas:, domain_dnskey:) + flag = zone_datas.any? do |zone_data| + zone_data[:flags] == domain_dnskey.flags.to_s && + zone_data[:algorithm] == domain_dnskey.alg.to_s && + zone_data[:protocol] == domain_dnskey.protocol.to_s && + zone_data[:public_key].include?(domain_dnskey[:public_key].to_s) + end + + text = "#{domain_dnskey.flags} - #{domain_dnskey.alg} - + #{domain_dnskey.protocol} - #{domain_dnskey.public_key} " + logger.info text + log_templates[flag.to_s] + + flag + end + + def prepare_resolver + dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) + dns = Dnsruby::Resolver.new({ nameserver: dns_servers }) + dns.do_validation = false + dns.do_caching = false + dns.dnssec = true + + dns + end + + def log_templates + { + "true" => "validated successfully", + "false" => "validated fail" + } + end + + def logger + @logger ||= Rails.logger + end +end From d2082a30211caa34dae7d46f64573d7aaa4e1347 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Tue, 4 Jan 2022 11:09:24 +0200 Subject: [PATCH 15/33] downgrade ruby version --- app/jobs/validate_dnssec_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index de818280f..8fdfb3177 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -73,8 +73,8 @@ class ValidateDnssecJob < ApplicationJob def prepare_resolver dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) dns = Dnsruby::Resolver.new({ nameserver: dns_servers }) - dns.do_validation = false - dns.do_caching = false + dns.do_validation = true + dns.do_caching = true dns.dnssec = true dns From 30b7ca940d0ee72c8c01e626d32b2f5fad88edb6 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Tue, 4 Jan 2022 13:46:56 +0200 Subject: [PATCH 16/33] change validate logic: going through all nameserver --- app/jobs/validate_dnssec_job.rb | 146 +++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 51 deletions(-) diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index 8fdfb3177..1d3981fe1 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -7,16 +7,14 @@ class ValidateDnssecJob < ApplicationJob return logger.info "No domain found" if domain.nil? - return logger.info "No related dnskeys for this domain" if domain.dnskeys.empty? + return logger.info "No related nameservers for this domain" if domain.nameservers.empty? - flag = iterate_domain_data(domain: domain) - logger.info "#{domain_name} " + log_templates[flag.to_s] + iterate_nameservers(domain) else - Dnskey.all.each do |key| - domain = Domain.find(key.domain_id) + domain_list = Domain.all.reject { |d| d.nameservers.empty? } - flag = iterate_domain_data(domain: domain) - logger.info "#{domain.name} " + log_templates[flag.to_s] + domain_list.each do |d| + iterate_nameservers(d) end end rescue StandardError => e @@ -26,58 +24,45 @@ class ValidateDnssecJob < ApplicationJob private - def iterate_domain_data(domain:) - zone_datas = get_data_from_zone(domain: domain) - flag = domain.dnskeys.all? { |key| validate(zone_datas: zone_datas, domain_dnskey: key) } + def iterate_nameservers(domain) + domain.nameservers.each do |n| + text = "Hostname nameserver #{n.hostname}" + flag = validate(name: n.hostname) + if flag.nil? + logger.info "#{text} - #{log_templates['false']}" + else + logger.info "#{text} - #{log_templates['true']}" + end - flag - end - - def get_data_from_zone(domain:) - resolver = prepare_resolver - ds_records_answers = resolver.query(domain.name, 'DNSKEY').answer - - result_container = [] - - ds_records_answers.each do |ds| - next unless ds.type == Dnsruby::Types.DNSKEY - - result_container << { - flags: ds.flags.to_s, - algorithm: ds.algorithm.code.to_s, - protocol: ds.protocol.to_s, - public_key: ds.public_key.export.gsub!(/\s+/, ''), - } + logger.info "----------------------------" end - - result_container - rescue Dnsruby::NXDomain - domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) end - def validate(zone_datas:, domain_dnskey:) - flag = zone_datas.any? do |zone_data| - zone_data[:flags] == domain_dnskey.flags.to_s && - zone_data[:algorithm] == domain_dnskey.alg.to_s && - zone_data[:protocol] == domain_dnskey.protocol.to_s && - zone_data[:public_key].include?(domain_dnskey[:public_key].to_s) - end - - text = "#{domain_dnskey.flags} - #{domain_dnskey.alg} - - #{domain_dnskey.protocol} - #{domain_dnskey.public_key} " - logger.info text + log_templates[flag.to_s] - - flag + def validate(name:, resolver: prepare_validator, type: 'DNSKEY', klass: 'IN') + # make_query(name: hostname) + resolver.query(name, type, klass) + rescue Exception => e + logger.error e.message + nil end - def prepare_resolver + def prepare_validator dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) - dns = Dnsruby::Resolver.new({ nameserver: dns_servers }) - dns.do_validation = true - dns.do_caching = true - dns.dnssec = true + inner_resolver = Dnsruby::Resolver.new + inner_resolver.do_validation = true + inner_resolver.dnssec = true + inner_resolver.nameserver = dns_servers + resolver = Dnsruby::Recursor.new(inner_resolver) + resolver.dnssec = true - dns + resolver + end + + def make_query(name:, resolver: prepare_validator, type: 'DNSKEY', klass: 'IN') + logger.info "DNS query to #{name}; type: #{type}" + resolver.query(name, type, klass) + rescue Dnsruby::NXDomain + false end def log_templates @@ -90,4 +75,63 @@ class ValidateDnssecJob < ApplicationJob def logger @logger ||= Rails.logger end + + + # + # + # def iterate_domain_data(domain:) + # zone_datas = get_data_from_zone(domain: domain) + # flag = domain.dnskeys.all? { |key| validate(zone_datas: zone_datas, domain_dnskey: key) } + # + # flag + # end + # + # def get_data_from_zone(domain:) + # resolver = prepare_resolver + # ds_records_answers = resolver.query(domain.name, 'DNSKEY').answer + # + # result_container = [] + # + # ds_records_answers.each do |ds| + # next unless ds.type == Dnsruby::Types.DNSKEY + # + # result_container << { + # flags: ds.flags.to_s, + # algorithm: ds.algorithm.code.to_s, + # protocol: ds.protocol.to_s, + # public_key: ds.public_key.export.gsub!(/\s+/, ''), + # } + # end + # + # result_container + # rescue Dnsruby::NXDomain + # domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) + # end + # + # def validate(zone_datas:, domain_dnskey:) + # flag = zone_datas.any? do |zone_data| + # zone_data[:flags] == domain_dnskey.flags.to_s && + # zone_data[:algorithm] == domain_dnskey.alg.to_s && + # zone_data[:protocol] == domain_dnskey.protocol.to_s && + # zone_data[:public_key].include?(domain_dnskey[:public_key].to_s) + # end + # + # text = "#{domain_dnskey.flags} - #{domain_dnskey.alg} - + # #{domain_dnskey.protocol} - #{domain_dnskey.public_key} " + # logger.info text + log_templates[flag.to_s] + # + # flag + # end + # + # def prepare_resolver + # dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) + # dns = Dnsruby::Resolver.new({ nameserver: dns_servers }) + # dns.do_validation = true + # dns.do_caching = true + # dns.dnssec = true + # + # dns + # end + + end From b25ef62d7827e35f9c2b768fc6314670333dee48 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 5 Jan 2022 12:54:18 +0200 Subject: [PATCH 17/33] updated validator job --- app/jobs/validate_dnssec_job.rb | 144 ++++++++++++++------------------ 1 file changed, 64 insertions(+), 80 deletions(-) diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index 1d3981fe1..1f418e43c 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -26,45 +26,88 @@ class ValidateDnssecJob < ApplicationJob def iterate_nameservers(domain) domain.nameservers.each do |n| - text = "Hostname nameserver #{n.hostname}" - flag = validate(name: n.hostname) - if flag.nil? - logger.info "#{text} - #{log_templates['false']}" - else - logger.info "#{text} - #{log_templates['true']}" - end + validate(hostname: n.hostname, domain: domain) logger.info "----------------------------" end end - def validate(name:, resolver: prepare_validator, type: 'DNSKEY', klass: 'IN') - # make_query(name: hostname) - resolver.query(name, type, klass) + def validate(hostname:, domain:, type: 'DNSKEY', klass: 'IN') + resolver = prepare_validator(hostname) + answer = resolver.query(domain.name, type, klass) + + return logger.info "no any data for #{domain.name} | hostname - #{hostname}" if answer.nil? + + logger.info "-----------" + logger.info "data for domain name - #{domain.name} | hostname - #{hostname}" + logger.info "-----------" + + response_container = parse_response(answer) + compare_dnssec_data(response_container: response_container, domain: domain) rescue Exception => e - logger.error e.message + logger.error "#{e.message} - domain name: #{domain.name} - hostname: #{hostname}" nil end - def prepare_validator - dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) + def compare_dnssec_data(response_container:, domain:) + domain.dnskeys.each do |key| + next unless key.flags.to_s == '257' + + flag = make_magic(response_container: response_container, dnskey: key) + text = "#{key.flags} - #{key.protocol} - #{key.alg} - #{key.public_key}" + if flag + logger.info text + " ------->> succesfully!" + else + logger.info text + " ------->> not found in zone!" + end + end + end + + def make_magic(response_container:, dnskey:) + response_container.any? do |r| + r[:flags].to_s == dnskey.flags.to_s && + r[:protocol].to_s == dnskey.protocol.to_s && + r[:alg].to_s == dnskey.alg.to_s && + r[:public_key] == dnskey.public_key + end + end + + def parse_response(answer) + response_container = [] + answer.each_answer do |a| + a_string = a.to_s + a_string = a_string.gsub /\t/, ' ' + a_string = a_string.split(' ') + + next unless a_string[4] == '257' + + protocol = a.protocol + alg = a.algorithm.code + + response_container << { + flags: a_string[4], + protocol: protocol, + alg: alg, + public_key: a_string[8] + } + end + + response_container + end + + def prepare_validator(nameserver) inner_resolver = Dnsruby::Resolver.new inner_resolver.do_validation = true inner_resolver.dnssec = true - inner_resolver.nameserver = dns_servers + inner_resolver.nameserver = nameserver + inner_resolver.packet_timeout = ENV['a_and_aaaa_validation_timeout'].to_i + inner_resolver.query_timeout = ENV['a_and_aaaa_validation_timeout'].to_i resolver = Dnsruby::Recursor.new(inner_resolver) resolver.dnssec = true resolver end - def make_query(name:, resolver: prepare_validator, type: 'DNSKEY', klass: 'IN') - logger.info "DNS query to #{name}; type: #{type}" - resolver.query(name, type, klass) - rescue Dnsruby::NXDomain - false - end - def log_templates { "true" => "validated successfully", @@ -75,63 +118,4 @@ class ValidateDnssecJob < ApplicationJob def logger @logger ||= Rails.logger end - - - # - # - # def iterate_domain_data(domain:) - # zone_datas = get_data_from_zone(domain: domain) - # flag = domain.dnskeys.all? { |key| validate(zone_datas: zone_datas, domain_dnskey: key) } - # - # flag - # end - # - # def get_data_from_zone(domain:) - # resolver = prepare_resolver - # ds_records_answers = resolver.query(domain.name, 'DNSKEY').answer - # - # result_container = [] - # - # ds_records_answers.each do |ds| - # next unless ds.type == Dnsruby::Types.DNSKEY - # - # result_container << { - # flags: ds.flags.to_s, - # algorithm: ds.algorithm.code.to_s, - # protocol: ds.protocol.to_s, - # public_key: ds.public_key.export.gsub!(/\s+/, ''), - # } - # end - # - # result_container - # rescue Dnsruby::NXDomain - # domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) - # end - # - # def validate(zone_datas:, domain_dnskey:) - # flag = zone_datas.any? do |zone_data| - # zone_data[:flags] == domain_dnskey.flags.to_s && - # zone_data[:algorithm] == domain_dnskey.alg.to_s && - # zone_data[:protocol] == domain_dnskey.protocol.to_s && - # zone_data[:public_key].include?(domain_dnskey[:public_key].to_s) - # end - # - # text = "#{domain_dnskey.flags} - #{domain_dnskey.alg} - - # #{domain_dnskey.protocol} - #{domain_dnskey.public_key} " - # logger.info text + log_templates[flag.to_s] - # - # flag - # end - # - # def prepare_resolver - # dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) - # dns = Dnsruby::Resolver.new({ nameserver: dns_servers }) - # dns.do_validation = true - # dns.do_caching = true - # dns.dnssec = true - # - # dns - # end - - end From ca9ca115eb433d5021787b027cee0ee8607df0f1 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 5 Jan 2022 14:40:33 +0200 Subject: [PATCH 18/33] added notify class and mail action for inform --- app/jobs/validate_dnssec_job.rb | 20 ++++++++++++++++++- app/mailers/contact_inform_mailer.rb | 16 +++++++++++++++ app/services/contact_notification.rb | 17 ++++++++++++++++ .../contact_inform_mailer/notify.html.erb | 1 + .../contact_inform_mailer/notify.text.erb | 1 + 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 app/mailers/contact_inform_mailer.rb create mode 100644 app/services/contact_notification.rb create mode 100644 app/views/mailers/contact_inform_mailer/notify.html.erb create mode 100644 app/views/mailers/contact_inform_mailer/notify.text.erb diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index 1f418e43c..3292f505d 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -28,10 +28,23 @@ class ValidateDnssecJob < ApplicationJob domain.nameservers.each do |n| validate(hostname: n.hostname, domain: domain) + notify_contacts(domain) logger.info "----------------------------" end end + def notify_contacts(domain) + flag = domain.dnskeys.any? { |k| k.validation_datetime.present? } + + return if flag + + text = "DNSKEYS for #{domain.name} are invalid!" + logger.info text + ContactNotification.notify_registrar(domain: domain, text: text) + ContactNotification.notify_tech_contact(domain: domain) + + end + def validate(hostname:, domain:, type: 'DNSKEY', klass: 'IN') resolver = prepare_validator(hostname) answer = resolver.query(domain.name, type, klass) @@ -51,16 +64,21 @@ class ValidateDnssecJob < ApplicationJob def compare_dnssec_data(response_container:, domain:) domain.dnskeys.each do |key| - next unless key.flags.to_s == '257' + next unless key.flags.to_s == '257' || key.validation_datetime.nil? flag = make_magic(response_container: response_container, dnskey: key) text = "#{key.flags} - #{key.protocol} - #{key.alg} - #{key.public_key}" if flag + key.validation_datetime = Time.zone.now + key.save + logger.info text + " ------->> succesfully!" else logger.info text + " ------->> not found in zone!" end end + + end def make_magic(response_container:, dnskey:) diff --git a/app/mailers/contact_inform_mailer.rb b/app/mailers/contact_inform_mailer.rb new file mode 100644 index 000000000..5c6f28f2c --- /dev/null +++ b/app/mailers/contact_inform_mailer.rb @@ -0,0 +1,16 @@ +class ContactInformMailer < ApplicationMailer + helper_method :address_processing + + def notify(contact:, subject:) + @contact = email + @subject = subject + + mail(to: contact.email, subject: subject) + end + + private + + def address_processing + Contact.address_processing? + end +end diff --git a/app/services/contact_notification.rb b/app/services/contact_notification.rb new file mode 100644 index 000000000..c5e8a7b0c --- /dev/null +++ b/app/services/contact_notification.rb @@ -0,0 +1,17 @@ +module ContactNotification + extend self + + def notify_registrar(domain:, text:) + domain.registrar.notifications.create(text: text) + end + + def notify_tech_contact(domain:) + text = "DNSKEYS for #{domain.name} are invalid!" + domain.tech_domain_contacts.each do |tech| + contact = Contact.find(tech.id) + + ContactInformMailer.notify(contact: contact, subject: text) + end + end + +end diff --git a/app/views/mailers/contact_inform_mailer/notify.html.erb b/app/views/mailers/contact_inform_mailer/notify.html.erb new file mode 100644 index 000000000..224584706 --- /dev/null +++ b/app/views/mailers/contact_inform_mailer/notify.html.erb @@ -0,0 +1 @@ +

DNSKEYS for <%= @domain.name %> are invalid!

diff --git a/app/views/mailers/contact_inform_mailer/notify.text.erb b/app/views/mailers/contact_inform_mailer/notify.text.erb new file mode 100644 index 000000000..224584706 --- /dev/null +++ b/app/views/mailers/contact_inform_mailer/notify.text.erb @@ -0,0 +1 @@ +

DNSKEYS for <%= @domain.name %> are invalid!

From 374c434de42e53646bc0b873fcc0002d40cbc0b6 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 5 Jan 2022 14:51:18 +0200 Subject: [PATCH 19/33] added skip for succesfully validated dnskeys --- app/jobs/validate_dnssec_job.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index 3292f505d..2778b97e6 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -64,7 +64,8 @@ class ValidateDnssecJob < ApplicationJob def compare_dnssec_data(response_container:, domain:) domain.dnskeys.each do |key| - next unless key.flags.to_s == '257' || key.validation_datetime.nil? + next unless key.flags.to_s == '257' + next if key.validation_datetime.present? flag = make_magic(response_container: response_container, dnskey: key) text = "#{key.flags} - #{key.protocol} - #{key.alg} - #{key.public_key}" @@ -77,8 +78,6 @@ class ValidateDnssecJob < ApplicationJob logger.info text + " ------->> not found in zone!" end end - - end def make_magic(response_container:, dnskey:) From d4fd8dc0eeb98194127ba4d723531c272065aa35 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 5 Jan 2022 15:58:32 +0200 Subject: [PATCH 20/33] update contact notification --- app/services/contact_notification.rb | 2 +- test/jobs/validate_dnssec_job_test.rb | 38 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 test/jobs/validate_dnssec_job_test.rb diff --git a/app/services/contact_notification.rb b/app/services/contact_notification.rb index c5e8a7b0c..6c5648f74 100644 --- a/app/services/contact_notification.rb +++ b/app/services/contact_notification.rb @@ -7,7 +7,7 @@ module ContactNotification def notify_tech_contact(domain:) text = "DNSKEYS for #{domain.name} are invalid!" - domain.tech_domain_contacts.each do |tech| + domain.tech_contacts.each do |tech| contact = Contact.find(tech.id) ContactInformMailer.notify(contact: contact, subject: text) diff --git a/test/jobs/validate_dnssec_job_test.rb b/test/jobs/validate_dnssec_job_test.rb new file mode 100644 index 000000000..f5388b186 --- /dev/null +++ b/test/jobs/validate_dnssec_job_test.rb @@ -0,0 +1,38 @@ +$VERBOSE=nil +require 'test_helper' + +class ValidateDnssecJobTest < ActiveJob::TestCase + setup do + @domain = domains(:shop) + @dnskey = dnskeys(:one) + end + + # def test_job_should_return_successfully_validated_dnskeys + # @domain.dnskeys << @dnskey + # @domain.save + # @domain.reload + # + # mock_zone_data = [ + # { + # flags: @dnskey.flags, + # protocol: @dnskey.protocol, + # alg: @dnskey.alg, + # public_key: @dnskey.public_key + # }] + # + # Spy.on_instance_method(ValidateDnssecJob, :parse_response).and_return(mock_zone_data) + # + # ValidateDnssecJob.perform_now(domain_name: @domain.name) + # + # @domain.reload + # p @domain.dnskeys + # end + + # def test_job_discarded_after_error + # assert_no_enqueued_jobs + # assert_performed_jobs 1 do + # TestDiscardedJob.perform_later + # end + # assert_no_enqueued_jobs + # end +end From 3f0c1211da867419ffde8a5c20f7f29ad64d82ff Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 5 Jan 2022 16:02:48 +0200 Subject: [PATCH 21/33] updated filter for domains --- app/jobs/validate_dnssec_job.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index 2778b97e6..695b17315 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -11,9 +11,15 @@ class ValidateDnssecJob < ApplicationJob iterate_nameservers(domain) else - domain_list = Domain.all.reject { |d| d.nameservers.empty? } + domain_list = Domain.all.reject { |d| d.dnskeys.empty? } domain_list.each do |d| + if d.nameservers.empty? + logger.info "#{d.name} has no nameserver" + + next + end + iterate_nameservers(d) end end From 57e653e9e69f528b1da0c10d84cd4b6d7af3d46b Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Thu, 6 Jan 2022 13:45:15 +0200 Subject: [PATCH 22/33] added soa nameserver validator --- app/jobs/validate_dnssec_job.rb | 4 +++ app/services/soa_nameserver_query.rb | 49 +++++++++++++++++++++++++++ test/jobs/validate_dnssec_job_test.rb | 44 +++++++++++++----------- 3 files changed, 77 insertions(+), 20 deletions(-) create mode 100644 app/services/soa_nameserver_query.rb diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index 695b17315..9a8a049d3 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -32,6 +32,10 @@ class ValidateDnssecJob < ApplicationJob def iterate_nameservers(domain) domain.nameservers.each do |n| + result_nameserver_validation = SoaNameserverQuery.validate(domain_name: domain.name, hostname: n.hostname) + + return unless result_nameserver_validation + validate(hostname: n.hostname, domain: domain) notify_contacts(domain) diff --git a/app/services/soa_nameserver_query.rb b/app/services/soa_nameserver_query.rb new file mode 100644 index 000000000..01d6db77b --- /dev/null +++ b/app/services/soa_nameserver_query.rb @@ -0,0 +1,49 @@ +module SoaNameserverQuery + include Dnsruby + + extend self + + def validate(domain_name:, hostname:) + + resolver = create_resolver(hostname) + + answers = resolver.query(domain_name, 'SOA', 'IN') + answers.answer.each do |a| + + if a.serial.nil? + logger.info "No serial number of nameserver found" + + return false + end + + serial_number = a.serial.to_s + + p "-------------- >>" + p "serial number #{serial_number} of #{hostname} - domain name: #{domain_name}" + p "<< --------------" + true + end + + rescue StandardError => e + logger.error e.message + logger.error "failed #{hostname} validation of #{domain_name} domain name" + + false + end + + private + + def create_resolver(nameserver) + resolver = Dnsruby::Resolver.new + resolver.retry_times = 3 + resolver.recurse = 0 # Send out non-recursive queries + # disable caching otherwise SOA is cached from first nameserver queried + resolver.do_caching = false + resolver.nameserver = nameserver + resolver + end + + def logger + @logger ||= Rails.logger + end +end diff --git a/test/jobs/validate_dnssec_job_test.rb b/test/jobs/validate_dnssec_job_test.rb index f5388b186..d8207492c 100644 --- a/test/jobs/validate_dnssec_job_test.rb +++ b/test/jobs/validate_dnssec_job_test.rb @@ -7,26 +7,30 @@ class ValidateDnssecJobTest < ActiveJob::TestCase @dnskey = dnskeys(:one) end - # def test_job_should_return_successfully_validated_dnskeys - # @domain.dnskeys << @dnskey - # @domain.save - # @domain.reload - # - # mock_zone_data = [ - # { - # flags: @dnskey.flags, - # protocol: @dnskey.protocol, - # alg: @dnskey.alg, - # public_key: @dnskey.public_key - # }] - # - # Spy.on_instance_method(ValidateDnssecJob, :parse_response).and_return(mock_zone_data) - # - # ValidateDnssecJob.perform_now(domain_name: @domain.name) - # - # @domain.reload - # p @domain.dnskeys - # end + def test_job_should_return_successfully_validated_dnskeys + # @domain.dnskeys << @dnskey + # @domain.save + # @domain.reload + # + # mock_zone_data = [ + # { + # flags: @dnskey.flags, + # protocol: @dnskey.protocol, + # alg: @dnskey.alg, + # public_key: @dnskey.public_key + # }] + # + # resolver = Spy.mock(Dnsruby::Recursor) + # Spy.on(resolver, :query).and_return true + # Spy.on_instance_method(ValidateDnssecJob, :parse_response).and_return(mock_zone_data) + # # Spy.on_instance_method(ValidateDnssecJob, :prepare_validator).and_return(true) + # + # + # ValidateDnssecJob.perform_now(domain_name: @domain.name) + # + # @domain.reload + # p @domain.dnskeys + end # def test_job_discarded_after_error # assert_no_enqueued_jobs From aff950aa97c05e2c53fb765ea77c4f95b6391758 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Sat, 8 Jan 2022 09:22:34 +0200 Subject: [PATCH 23/33] refactored job --- app/jobs/validate_dnssec_job.rb | 9 ++- app/services/soa_nameserver_query.rb | 49 -------------- app/services/validate_dnssec.rb | 97 ---------------------------- 3 files changed, 4 insertions(+), 151 deletions(-) delete mode 100644 app/services/soa_nameserver_query.rb delete mode 100644 app/services/validate_dnssec.rb diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index 9a8a049d3..ad6b4b768 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -32,9 +32,7 @@ class ValidateDnssecJob < ApplicationJob def iterate_nameservers(domain) domain.nameservers.each do |n| - result_nameserver_validation = SoaNameserverQuery.validate(domain_name: domain.name, hostname: n.hostname) - - return unless result_nameserver_validation + next unless n.validated? validate(hostname: n.hostname, domain: domain) @@ -124,11 +122,12 @@ class ValidateDnssecJob < ApplicationJob def prepare_validator(nameserver) inner_resolver = Dnsruby::Resolver.new + timeouts = ENV['nameserver_validation_timeout'] || 4 inner_resolver.do_validation = true inner_resolver.dnssec = true inner_resolver.nameserver = nameserver - inner_resolver.packet_timeout = ENV['a_and_aaaa_validation_timeout'].to_i - inner_resolver.query_timeout = ENV['a_and_aaaa_validation_timeout'].to_i + inner_resolver.packet_timeout = timeouts.to_i + inner_resolver.query_timeout = timeouts.to_i resolver = Dnsruby::Recursor.new(inner_resolver) resolver.dnssec = true diff --git a/app/services/soa_nameserver_query.rb b/app/services/soa_nameserver_query.rb deleted file mode 100644 index 01d6db77b..000000000 --- a/app/services/soa_nameserver_query.rb +++ /dev/null @@ -1,49 +0,0 @@ -module SoaNameserverQuery - include Dnsruby - - extend self - - def validate(domain_name:, hostname:) - - resolver = create_resolver(hostname) - - answers = resolver.query(domain_name, 'SOA', 'IN') - answers.answer.each do |a| - - if a.serial.nil? - logger.info "No serial number of nameserver found" - - return false - end - - serial_number = a.serial.to_s - - p "-------------- >>" - p "serial number #{serial_number} of #{hostname} - domain name: #{domain_name}" - p "<< --------------" - true - end - - rescue StandardError => e - logger.error e.message - logger.error "failed #{hostname} validation of #{domain_name} domain name" - - false - end - - private - - def create_resolver(nameserver) - resolver = Dnsruby::Resolver.new - resolver.retry_times = 3 - resolver.recurse = 0 # Send out non-recursive queries - # disable caching otherwise SOA is cached from first nameserver queried - resolver.do_caching = false - resolver.nameserver = nameserver - resolver - end - - def logger - @logger ||= Rails.logger - end -end diff --git a/app/services/validate_dnssec.rb b/app/services/validate_dnssec.rb deleted file mode 100644 index 1cc2a9422..000000000 --- a/app/services/validate_dnssec.rb +++ /dev/null @@ -1,97 +0,0 @@ -module ValidateDnssec - include Dnsruby - - extend self - - def prepare_resolver - dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) - dns = Dnsruby::Resolver.new({ nameserver: dns_servers }) - dns.do_validation = false - dns.do_caching = false - dns.dnssec = true - - dns - end - - def validate_dnssec(params:, domain:) - return if params[:action] == 'rem' - - dns = prepare_resolver - subzone_records = get_dnskey_records_from_subzone(resolver: dns, hostname: params[:domain], domain: domain) - form_extension_records = extensional_dnskeys_data(params) - - return true if form_extension_records.empty? - - validate_data(subzone_records: subzone_records, form_extension_records: form_extension_records, domain: domain) - end - - def make_magic(subzone_records:, form_data:) - subzone_records.any? do |subzone_data| - subzone_data[:basic] == form_data[:basic] && - subzone_data[:public_key].include?(form_data[:public_key]) - end - end - - def validate_data(subzone_records:, form_extension_records:, domain:) - flag = false - form_extension_records.each do |form_data| - flag = make_magic(subzone_records: subzone_records, form_data: form_data) - - break if flag - end - - return validation_dns_key_error(domain) unless flag - - flag - end - - def get_dnskey_records_from_subzone(resolver:, hostname:, domain:) - ds_records_answers = resolver.query(hostname, 'DNSKEY').answer - - result_container = [] - - ds_records_answers.each do |ds| - next unless ds.type == Dnsruby::Types.DNSKEY - - result_container << { - basic: { - flags: ds.flags.to_s, - algorithm: ds.algorithm.code.to_s, - protocol: ds.protocol.to_s, - }, - public_key: ds.public_key.export.gsub!(/\s+/, ''), - } - end - - result_container - rescue Dnsruby::NXDomain - domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) - end - - def validation_dns_key_error(domain) - domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) - end - - def extensional_dnskeys_data(params) - dnskeys_data = params[:dns_keys] - - return [] if dnskeys_data.nil? - - result_container = [] - - dnskeys_data.each do |ds| - next if ds[:action] == 'rem' - - result_container << { - basic: { - flags: ds[:flags].to_s, - algorithm: ds[:alg].to_s, - protocol: ds[:protocol].to_s, - }, - public_key: ds[:public_key], - } - end - - result_container - end -end From 053382ffa35189be45fec4bcea0886c0a6313688 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Mon, 10 Jan 2022 09:39:14 +0200 Subject: [PATCH 24/33] updated tests --- app/interactions/actions/domain_update.rb | 1 - .../registrant_api_verifications_test.rb | 1 - .../epp/domain/update/base_test.rb | 1 - .../epp/domain/update/rem_dns_test.rb | 1 - .../repp/v1/domains/contacts_test.rb | 1 - .../repp/v1/domains/dnssec_test.rb | 1 - .../repp/v1/domains/nameservers_test.rb | 1 - .../repp/v1/domains/update_test.rb | 1 - test/jobs/domain_update_confirm_job_test.rb | 1 - test/services/validate_dnssec_test.rb | 48 ------------------- 10 files changed, 57 deletions(-) delete mode 100644 test/services/validate_dnssec_test.rb diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index 2e44a015c..40b7876f6 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -14,7 +14,6 @@ module Actions assign_new_registrant if params[:registrant] assign_relational_modifications assign_requested_statuses - # ValidateDnssec.validate_dnssec(params: params, domain: domain) ::Actions::BaseAction.maybe_attach_legal_doc(domain, params[:legal_document]) commit diff --git a/test/integration/api/registrant/registrant_api_verifications_test.rb b/test/integration/api/registrant/registrant_api_verifications_test.rb index 8db49410f..612006eb9 100644 --- a/test/integration/api/registrant/registrant_api_verifications_test.rb +++ b/test/integration/api/registrant/registrant_api_verifications_test.rb @@ -15,7 +15,6 @@ class RegistrantApiVerificationsTest < ApplicationIntegrationTest @domain.update!(statuses: [DomainStatus::PENDING_UPDATE], registrant_verification_asked_at: Time.zone.now - 1.day, registrant_verification_token: @token) - Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end def test_fetches_registrant_change_request diff --git a/test/integration/epp/domain/update/base_test.rb b/test/integration/epp/domain/update/base_test.rb index aaa7e1767..d021b496d 100644 --- a/test/integration/epp/domain/update/base_test.rb +++ b/test/integration/epp/domain/update/base_test.rb @@ -10,7 +10,6 @@ class EppDomainUpdateBaseTest < EppTestCase @original_registrant_change_verification = Setting.request_confirmation_on_registrant_change_enabled ActionMailer::Base.deliveries.clear - Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end teardown do diff --git a/test/integration/epp/domain/update/rem_dns_test.rb b/test/integration/epp/domain/update/rem_dns_test.rb index ecd660fa6..6e079b126 100644 --- a/test/integration/epp/domain/update/rem_dns_test.rb +++ b/test/integration/epp/domain/update/rem_dns_test.rb @@ -12,7 +12,6 @@ class EppDomainUpdateRemDnsTest < EppTestCase @original_registrant_change_verification = Setting.request_confirmation_on_registrant_change_enabled ActionMailer::Base.deliveries.clear - Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end teardown do diff --git a/test/integration/repp/v1/domains/contacts_test.rb b/test/integration/repp/v1/domains/contacts_test.rb index 540514853..b9b26a745 100644 --- a/test/integration/repp/v1/domains/contacts_test.rb +++ b/test/integration/repp/v1/domains/contacts_test.rb @@ -8,7 +8,6 @@ class ReppV1DomainsContactsTest < ActionDispatch::IntegrationTest token = "Basic #{token}" @auth_headers = { 'Authorization' => token } - Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end def test_shows_existing_domain_contacts diff --git a/test/integration/repp/v1/domains/dnssec_test.rb b/test/integration/repp/v1/domains/dnssec_test.rb index 79480c3b8..6835e2600 100644 --- a/test/integration/repp/v1/domains/dnssec_test.rb +++ b/test/integration/repp/v1/domains/dnssec_test.rb @@ -8,7 +8,6 @@ class ReppV1DomainsDnssecTest < ActionDispatch::IntegrationTest token = "Basic #{token}" @auth_headers = { 'Authorization' => token } - Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end def test_shows_dnssec_keys_associated_with_domain diff --git a/test/integration/repp/v1/domains/nameservers_test.rb b/test/integration/repp/v1/domains/nameservers_test.rb index 4c7a1dcc5..780e889c1 100644 --- a/test/integration/repp/v1/domains/nameservers_test.rb +++ b/test/integration/repp/v1/domains/nameservers_test.rb @@ -8,7 +8,6 @@ class ReppV1DomainsNameserversTest < ActionDispatch::IntegrationTest token = "Basic #{token}" @auth_headers = { 'Authorization' => token } - Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end def test_can_add_new_nameserver diff --git a/test/integration/repp/v1/domains/update_test.rb b/test/integration/repp/v1/domains/update_test.rb index 595d094fe..d924fe7a3 100644 --- a/test/integration/repp/v1/domains/update_test.rb +++ b/test/integration/repp/v1/domains/update_test.rb @@ -8,7 +8,6 @@ class ReppV1DomainsUpdateTest < ActionDispatch::IntegrationTest token = "Basic #{token}" @auth_headers = { 'Authorization' => token } - Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end def test_updates_transfer_code_for_domain diff --git a/test/jobs/domain_update_confirm_job_test.rb b/test/jobs/domain_update_confirm_job_test.rb index a5999cd36..158729ae3 100644 --- a/test/jobs/domain_update_confirm_job_test.rb +++ b/test/jobs/domain_update_confirm_job_test.rb @@ -14,7 +14,6 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase new_registrant_name: @new_registrant.name, new_registrant_email: @new_registrant.email, current_user_id: @user.id }) - Spy.on_instance_method(ValidateDnssec, :validate_dnssec).and_return(true) end def teardown diff --git a/test/services/validate_dnssec_test.rb b/test/services/validate_dnssec_test.rb deleted file mode 100644 index b3e939ee4..000000000 --- a/test/services/validate_dnssec_test.rb +++ /dev/null @@ -1,48 +0,0 @@ -require 'test_helper' - -class ValidateDnssecTest < ActiveSupport::TestCase - setup do - @dnskey = dnskeys(:one) - @domain = domains(:shop) - - @result_container = [{ - basic: { - flags: @dnskey.flags.to_s, - algorithm: @dnskey.alg.to_s, - protocol: @dnskey.protocol.to_s, - }, - public_key: @dnskey.public_key.to_s - }] - - Spy.on_instance_method(ValidateDnssec, :validation_dns_key_error).and_return(false) - end - - def test_should_return_true_if_dnssec_data_are_matches - Spy.on_instance_method(ValidateDnssec, :get_dnskey_records_from_subzone).and_return(@result_container) - match_params = build_params(@dnskey.flags) - validate_result = ValidateDnssec.validate_dnssec(params: match_params, domain: @domain) - - assert validate_result - end - - def test_should_return_false_if_dnssec_data_does_not_matcher - Spy.on_instance_method(ValidateDnssec, :get_dnskey_records_from_subzone).and_return(@result_container) - match_params = build_params(256) - validate_result = ValidateDnssec.validate_dnssec(params: match_params, domain: @domain) - - refute validate_result - end - - def build_params(flag) - { - action: "add", - domain: @domain, - dns_keys: [{ - flags: flag, - alg: @dnskey.alg, - protocol: @dnskey.protocol, - public_key: @dnskey.public_key - }] - } - end -end From 35f60e53e59e2ceafd26269e050d5c18cd7efb39 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Mon, 10 Jan 2022 12:05:32 +0200 Subject: [PATCH 25/33] improve notification feature --- app/jobs/nameserver_record_validation_job.rb | 16 +++++++------- app/jobs/validate_dnssec_job.rb | 3 +-- app/mailers/contact_inform_mailer.rb | 5 +++-- app/services/contact_notification.rb | 7 +++---- test/services/contact_notification_test.rb | 22 ++++++++++++++++++++ 5 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 test/services/contact_notification_test.rb diff --git a/app/jobs/nameserver_record_validation_job.rb b/app/jobs/nameserver_record_validation_job.rb index a1787e9d7..5a32ce133 100644 --- a/app/jobs/nameserver_record_validation_job.rb +++ b/app/jobs/nameserver_record_validation_job.rb @@ -95,27 +95,27 @@ class NameserverRecordValidationJob < ApplicationJob end logger.info text - failed_log(text: text, nameserver: nameserver) + failed_log(text: text, nameserver: nameserver, domain: domain) add_nameserver_to_failed(nameserver: nameserver, reason: text) false end - def failed_log(text:, nameserver:) - inform_to_tech_contact(text) + def failed_log(text:, nameserver:, domain:) + inform_to_tech_contact(domain: domain, text: text) inform_to_registrar(text: text, nameserver: nameserver) false end - def inform_to_tech_contact(text) - "NEED TO DO!" - text + def inform_to_tech_contact(domain:, text:) + ContactNotification.notify_tech_contact(domain: domain, text: text) end def inform_to_registrar(text:, nameserver:) - # nameserver.domain.registrar.notifications.create!(text: text) - "NEED TO DO!" + # text = "DNSKEYS for #{domain.name} are invalid!" + logger.info text + ContactNotification.notify_registrar(domain: nameserver.domain, text: text) end def logger diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index ad6b4b768..54f7818c5 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -49,8 +49,7 @@ class ValidateDnssecJob < ApplicationJob text = "DNSKEYS for #{domain.name} are invalid!" logger.info text ContactNotification.notify_registrar(domain: domain, text: text) - ContactNotification.notify_tech_contact(domain: domain) - + ContactNotification.notify_tech_contact(domain: domain, text: text) end def validate(hostname:, domain:, type: 'DNSKEY', klass: 'IN') diff --git a/app/mailers/contact_inform_mailer.rb b/app/mailers/contact_inform_mailer.rb index 5c6f28f2c..00834a8ae 100644 --- a/app/mailers/contact_inform_mailer.rb +++ b/app/mailers/contact_inform_mailer.rb @@ -1,9 +1,10 @@ class ContactInformMailer < ApplicationMailer helper_method :address_processing - def notify(contact:, subject:) - @contact = email + def notify(contact:, domain:, subject:) + @contact = contact @subject = subject + @domain = domain mail(to: contact.email, subject: subject) end diff --git a/app/services/contact_notification.rb b/app/services/contact_notification.rb index 6c5648f74..d14526fea 100644 --- a/app/services/contact_notification.rb +++ b/app/services/contact_notification.rb @@ -5,13 +5,12 @@ module ContactNotification domain.registrar.notifications.create(text: text) end - def notify_tech_contact(domain:) - text = "DNSKEYS for #{domain.name} are invalid!" + def notify_tech_contact(domain:, text:) + # text = "DNSKEYS for #{domain.name} are invalid!" domain.tech_contacts.each do |tech| contact = Contact.find(tech.id) - ContactInformMailer.notify(contact: contact, subject: text) + ContactInformMailer.notify(contact: contact, domain: domain, subject: text).deliver_now end end - end diff --git a/test/services/contact_notification_test.rb b/test/services/contact_notification_test.rb new file mode 100644 index 000000000..317cbb470 --- /dev/null +++ b/test/services/contact_notification_test.rb @@ -0,0 +1,22 @@ +require 'test_helper' + +class ContactNotificationTest < ActionMailer::TestCase + + setup do + @domain = domains(:shop) + @text = 'text' + end + + def test_notify_registrar + assert_difference -> { @domain.registrar.notifications.count } do + ContactNotification.notify_registrar(domain: @domain, text: @text) + end + end + + def test_notify_tech_contacts + ContactNotification.notify_tech_contact(domain: @domain, text: @text) + assert_equal @domain.tech_contacts.count, 2 + assert_emails 2 + end +end + From 09ba0a25113f6f6541e8b820862a2ea649bcc231 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 12 Jan 2022 12:24:44 +0200 Subject: [PATCH 26/33] update mail templates --- app/jobs/nameserver_record_validation_job.rb | 8 ++-- app/jobs/validate_dnssec_job.rb | 4 +- app/mailers/contact_inform_mailer.rb | 13 +++++- app/services/contact_notification.rb | 18 +++++--- .../contact_inform_mailer/notify.html.erb | 1 - .../contact_inform_mailer/notify.text.erb | 1 - .../notify_dnssec.html.erb | 40 +++++++++++++++++ .../notify_dnssec.text.erb | 29 +++++++++++++ .../notify_nameserver.html.erb | 43 +++++++++++++++++++ .../notify_nameserver.text.erb | 29 +++++++++++++ 10 files changed, 171 insertions(+), 15 deletions(-) delete mode 100644 app/views/mailers/contact_inform_mailer/notify.html.erb delete mode 100644 app/views/mailers/contact_inform_mailer/notify.text.erb create mode 100644 app/views/mailers/contact_inform_mailer/notify_dnssec.html.erb create mode 100644 app/views/mailers/contact_inform_mailer/notify_dnssec.text.erb create mode 100644 app/views/mailers/contact_inform_mailer/notify_nameserver.html.erb create mode 100644 app/views/mailers/contact_inform_mailer/notify_nameserver.text.erb diff --git a/app/jobs/nameserver_record_validation_job.rb b/app/jobs/nameserver_record_validation_job.rb index 5a32ce133..d4c9b194d 100644 --- a/app/jobs/nameserver_record_validation_job.rb +++ b/app/jobs/nameserver_record_validation_job.rb @@ -108,12 +108,12 @@ class NameserverRecordValidationJob < ApplicationJob false end - def inform_to_tech_contact(domain:, text:) - ContactNotification.notify_tech_contact(domain: domain, text: text) + def inform_to_tech_contact(domain:, text: nil) + ContactNotification.notify_tech_contact(domain: domain, reason: 'nameserver') end - def inform_to_registrar(text:, nameserver:) - # text = "DNSKEYS for #{domain.name} are invalid!" + def inform_to_registrar(nameserver:, text: nil) + text = "Host record #{nameserver.hostname} of a domain #{nameserver.domain} is invalid. Please fix or contact the registrant." logger.info text ContactNotification.notify_registrar(domain: nameserver.domain, text: text) end diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index 54f7818c5..3277914f1 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -46,10 +46,10 @@ class ValidateDnssecJob < ApplicationJob return if flag - text = "DNSKEYS for #{domain.name} are invalid!" + text = "DNSKEY record of a domain #{domain.name} is invalid. Please fix or contact the registrant." logger.info text ContactNotification.notify_registrar(domain: domain, text: text) - ContactNotification.notify_tech_contact(domain: domain, text: text) + ContactNotification.notify_tech_contact(domain: domain, reason: 'dnssec') end def validate(hostname:, domain:, type: 'DNSKEY', klass: 'IN') diff --git a/app/mailers/contact_inform_mailer.rb b/app/mailers/contact_inform_mailer.rb index 00834a8ae..7423da791 100644 --- a/app/mailers/contact_inform_mailer.rb +++ b/app/mailers/contact_inform_mailer.rb @@ -1,11 +1,20 @@ class ContactInformMailer < ApplicationMailer helper_method :address_processing - def notify(contact:, domain:, subject:) + def notify_dnssec(contact:, domain:) @contact = contact - @subject = subject @domain = domain + subject = "Domeeni #{@domain.name} DNSSEC kirjed ei ole korrektsed / The DNSKEY records of the domain #{@domain.name} are invalid" + + mail(to: contact.email, subject: subject) + end + + def notify_nameserver(contact:, domain:) + @contact = contact + @domain = domain + + subject = "Domeeni #{@domain.name} nimeserveri kirjed ei ole korrektsed / The host records of the domain #{@domain.name} are invalid" mail(to: contact.email, subject: subject) end diff --git a/app/services/contact_notification.rb b/app/services/contact_notification.rb index d14526fea..16765d65d 100644 --- a/app/services/contact_notification.rb +++ b/app/services/contact_notification.rb @@ -5,12 +5,20 @@ module ContactNotification domain.registrar.notifications.create(text: text) end - def notify_tech_contact(domain:, text:) - # text = "DNSKEYS for #{domain.name} are invalid!" - domain.tech_contacts.each do |tech| - contact = Contact.find(tech.id) + def notify_tech_contact(domain:, reason: nil) + case reason + when 'dnssec' + domain.tech_contacts.each do |tech| + contact = Contact.find(tech.id) - ContactInformMailer.notify(contact: contact, domain: domain, subject: text).deliver_now + ContactInformMailer.notify_dnssec(contact: contact, domain: domain).deliver_now + end + when 'nameserver' + domain.tech_contacts.each do |tech| + contact = Contact.find(tech.id) + + ContactInformMailer.notify_nameserver(contact: contact, domain: domain).deliver_now + end end end end diff --git a/app/views/mailers/contact_inform_mailer/notify.html.erb b/app/views/mailers/contact_inform_mailer/notify.html.erb deleted file mode 100644 index 224584706..000000000 --- a/app/views/mailers/contact_inform_mailer/notify.html.erb +++ /dev/null @@ -1 +0,0 @@ -

DNSKEYS for <%= @domain.name %> are invalid!

diff --git a/app/views/mailers/contact_inform_mailer/notify.text.erb b/app/views/mailers/contact_inform_mailer/notify.text.erb deleted file mode 100644 index 224584706..000000000 --- a/app/views/mailers/contact_inform_mailer/notify.text.erb +++ /dev/null @@ -1 +0,0 @@ -

DNSKEYS for <%= @domain.name %> are invalid!

diff --git a/app/views/mailers/contact_inform_mailer/notify_dnssec.html.erb b/app/views/mailers/contact_inform_mailer/notify_dnssec.html.erb new file mode 100644 index 000000000..4b506b9e8 --- /dev/null +++ b/app/views/mailers/contact_inform_mailer/notify_dnssec.html.erb @@ -0,0 +1,40 @@ +

Lugupeetud domeeni <%= @domain.name %> tehniline kontakt,

+ +

+Eesti Interneti Sihtasutusele (EIS) juhib tähelepanu, et domeeni <%= @domain.name %> DNSKEY kirjed on puudulikud ning domeeniga seotud teenuse ei pruugi korrektselt toimida. +

+

+Andmete parandamiseks vaadake palun üle domeeni nimeserverite seaditused või pöörduge palun oma registripidaja <%= @domain.registrar.name %> või nimeserveri teenuse pakkuja poole.

+ +

+Lisaküsimuste korral võtke palun ühendust oma registripidajaga: +

+<%= @domain.registrar.name %>
+Email: <%= @domain.registrar.email %>
+Telefon:<%= @domain.registrar.phone %>
+Veebileht:<%= @domain.registrar.website %>
+ +Lugupidamisega
+Eesti Interneti Sihtasutus
+
+--- +
+ +

Dear technical contact of <%= @domain.name %> domain,

+ +

+Estonian Internet Foundation points out that the DNSKEY record(s) for the domain <%= @domain.name %> are invalid and the service related to the domain may not work correctly. +

+

+Please check the DNSKEY records of the domain or contact your registrar <%= @domain.registrar.name%> or your name server service provider to correct this information. +

+

+Should you have additional questions, please contact your registrar: +

+<%= @domain.registrar.name %>
+Email: <%= @domain.registrar.email %>
+Phone: <%= @domain.registrar.phone %>
+Website: <%= @domain.registrar.website %>
+ +Best Regards,
+Estonian Internet Foundation diff --git a/app/views/mailers/contact_inform_mailer/notify_dnssec.text.erb b/app/views/mailers/contact_inform_mailer/notify_dnssec.text.erb new file mode 100644 index 000000000..09b243854 --- /dev/null +++ b/app/views/mailers/contact_inform_mailer/notify_dnssec.text.erb @@ -0,0 +1,29 @@ +Lugupeetud domeeni <%= @domain.name %> tehniline kontakt, + +Eesti Interneti Sihtasutusele (EIS) juhib tähelepanu, et domeeni <%= @domain.name %> DNSKEY kirjed on puudulikud ning domeeniga seotud teenuse ei pruugi korrektselt toimida. +Andmete parandamiseks vaadake palun üle domeeni nimeserverite seaditused või pöörduge palun oma registripidaja <%= @domain.registrar.name %> või nimeserveri teenuse pakkuja poole. + +Lisaküsimuste korral võtke palun ühendust oma registripidajaga: +<%= @domain.registrar.name%> +Email: <%= @domain.registrar.email %> +Telefon: <%= @domain.registrar.phone %> +Veebileht: <%= @domain.registrar.website %> + +Lugupidamisega +Eesti Interneti Sihtasutus + +--- + +Dear technical contact of <%= @domain.name %> domain, + +Estonian Internet Foundation points out that the DNSKEY record(s) for the domain <%= @domain.name %> are invalid and the service related to the domain may not work correctly. +Please check the DNSKEY records of the domain or contact your registrar <%= @domain.registrar.name%> or your name server service provider to correct this information. + +Should you have additional questions, please contact your registrar: +<%= @domain.registrar.name%> +Email: <%= @domain.registrar.email %> +Phone: <%= @domain.registrar.phone %> +Website: <%= @domain.registrar.website %> + +Best Regards, +Estonian Internet Foundation diff --git a/app/views/mailers/contact_inform_mailer/notify_nameserver.html.erb b/app/views/mailers/contact_inform_mailer/notify_nameserver.html.erb new file mode 100644 index 000000000..ce6b968a0 --- /dev/null +++ b/app/views/mailers/contact_inform_mailer/notify_nameserver.html.erb @@ -0,0 +1,43 @@ +

Lugupeetud domeeni <%= @domain.name %> tehniline kontakt

+ +

+Eesti Interneti Sihtasutusele (EIS) juhib tähelepanu, et domeeni <%= @domain.name %> nimeserverite seaded on puudulikud ning domeeniga seotud teenuse ei pruugi korrektselt toimida.

+

+Andmete parandamiseks vaadake palun üle domeeni nimeserverite seaditused või pöörduge palun oma registripidaja <%= @domain.registrar.name%> või nimeserveri teenuse pakkuja poole. +

+ +

+Lisaküsimuste korral võtke palun ühendust oma registripidajaga: +

+ +<%= @domain.registrar.name %>
+Email: <%= @domain.registrar.email %>
+Telefon: <%= @domain.registrar.phone %>
+Veebileht: <%= @domain.registrar.website %>
+ +Lugupidamisega
+Eesti Interneti Sihtasutus
+
+--- +
+ +

Dear technical contact of <%= @domain.name %> domain,

+ +

+ Estonian Internet Foundation points out that the settings for the name servers of the domain <%= @domain.name %> are incomplete and the service related to the domain may not work correctly. +

+

+Please check the name server settings of the domain or contact your registrar <%= @domain.registrar.name%> or your name server service provider to correct this information. +

+ +

+Should you have additional questions, please contact your registrar: +

+ +<%= @domain.registrar.name%>
+Email: <%= @domain.registrar.email %>
+Phone: <%= @domain.registrar.phone %>
+Website: <%= @domain.registrar.website %>
+ +Best Regards,
+Estonian Internet Foundation
diff --git a/app/views/mailers/contact_inform_mailer/notify_nameserver.text.erb b/app/views/mailers/contact_inform_mailer/notify_nameserver.text.erb new file mode 100644 index 000000000..3a6734402 --- /dev/null +++ b/app/views/mailers/contact_inform_mailer/notify_nameserver.text.erb @@ -0,0 +1,29 @@ +Lugupeetud domeeni <%= @domain.name %> tehniline kontakt + +Eesti Interneti Sihtasutusele (EIS) juhib tähelepanu, et domeeni <%= @domain.name %> nimeserverite seaded on puudulikud ning domeeniga seotud teenuse ei pruugi korrektselt toimida. +Andmete parandamiseks vaadake palun üle domeeni nimeserverite seaditused või pöörduge palun oma registripidaja <%= @domain.registrar.name%> või nimeserveri teenuse pakkuja poole. + +Lisaküsimuste korral võtke palun ühendust oma registripidajaga: +<%= @domain.registrar.name%> +Email: <%= @domain.registrar.email %> +Telefon: <%= @domain.registrar.phone %> +Veebileht: <%= @domain.registrar.website %> + +Lugupidamisega +Eesti Interneti Sihtasutus + +--- + +Dear technical contact of <%= @domain.name %> domain, + +Estonian Internet Foundation points out that the settings for the name servers of the domain <%= @domain.name %> are incomplete and the service related to the domain may not work correctly. +Please check the name server settings of the domain or contact your registrar <%= @domain.registrar.name%> or your name server service provider to correct this information. + +Should you have additional questions, please contact your registrar: +<%= @domain.registrar.name%> +Email: <%= @domain.registrar.email %> +Phone: <%= @domain.registrar.phone %> +Website: <%= @domain.registrar.website %> + +Best Regards, +Estonian Internet Foundation From 635e7b9c4fc36b9f17c3b55e5877afc555f1df67 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 12 Jan 2022 12:53:45 +0200 Subject: [PATCH 27/33] added schedule for running job --- config/schedule.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/schedule.rb b/config/schedule.rb index 0106cc97d..cffe61d37 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -66,6 +66,10 @@ if @cron_group == 'registry' rake 'verify_email:all_domains' end + every 5.minutes do + runner 'NameserverRecordValidationJob.perform_now' + end + # Should be at least once every 4 days, since according to LHV specs: # "Unread messages older than 5 days are automatically scheduled for deletion" # https://partners.lhv.ee/en/connect/#messaging From fff7bcb1cff04330e38ee7c4f49eeb1a4207931a Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 12 Jan 2022 13:11:10 +0200 Subject: [PATCH 28/33] updated tests --- config/schedule.rb | 4 ---- test/services/contact_notification_test.rb | 10 ++++++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/config/schedule.rb b/config/schedule.rb index cffe61d37..0106cc97d 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -66,10 +66,6 @@ if @cron_group == 'registry' rake 'verify_email:all_domains' end - every 5.minutes do - runner 'NameserverRecordValidationJob.perform_now' - end - # Should be at least once every 4 days, since according to LHV specs: # "Unread messages older than 5 days are automatically scheduled for deletion" # https://partners.lhv.ee/en/connect/#messaging diff --git a/test/services/contact_notification_test.rb b/test/services/contact_notification_test.rb index 317cbb470..0e75fb548 100644 --- a/test/services/contact_notification_test.rb +++ b/test/services/contact_notification_test.rb @@ -13,8 +13,14 @@ class ContactNotificationTest < ActionMailer::TestCase end end - def test_notify_tech_contacts - ContactNotification.notify_tech_contact(domain: @domain, text: @text) + def test_notify_tech_contacts_that_nameserver_is_broken + ContactNotification.notify_tech_contact(domain: @domain, reason: 'nameserver') + assert_equal @domain.tech_contacts.count, 2 + assert_emails 2 + end + + def test_notify_tech_contacts_that_dnssec_is_broken + ContactNotification.notify_tech_contact(domain: @domain, reason: 'dnssec') assert_equal @domain.tech_contacts.count, 2 assert_emails 2 end From f6b352a087068ef2dcc4f9233a34c26c739668a4 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 12 Jan 2022 13:40:01 +0200 Subject: [PATCH 29/33] updated nameserver letter --- app/jobs/nameserver_record_validation_job.rb | 17 +++++++++-------- app/jobs/validate_dnssec_job.rb | 7 ------- app/mailers/contact_inform_mailer.rb | 3 ++- app/models/nameserver.rb | 2 +- app/services/contact_notification.rb | 4 ++-- .../notify_nameserver.html.erb | 4 ++++ .../nameserver_record_validation_job_test.rb | 2 +- test/services/contact_notification_test.rb | 3 ++- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/app/jobs/nameserver_record_validation_job.rb b/app/jobs/nameserver_record_validation_job.rb index d4c9b194d..9271d94d7 100644 --- a/app/jobs/nameserver_record_validation_job.rb +++ b/app/jobs/nameserver_record_validation_job.rb @@ -12,7 +12,7 @@ class NameserverRecordValidationJob < ApplicationJob domains.each do |domain| domain.nameservers.each do |nameserver| - next if nameserver.nameserver_failed_validation? || nameserver.validated? + next if nameserver.failed_validation? || nameserver.validated? result = NameserverValidator.run(domain_name: domain.name, nameserver: nameserver) @@ -38,7 +38,7 @@ class NameserverRecordValidationJob < ApplicationJob return logger.info 'Domain not has nameservers' if domain.nameservers.empty? domain.nameservers.each do |nameserver| - next if nameserver.nameserver_failed_validation? + next if nameserver.failed_validation? result = NameserverValidator.run(domain_name: domain.name, nameserver: nameserver) @@ -73,6 +73,8 @@ class NameserverRecordValidationJob < ApplicationJob nameserver.failed_validation_reason = reason nameserver.save + + failed_log(text: reason, nameserver: nameserver, domain: nameserver.domain) if nameserver.failed_validation? end def parse_result(result, nameserver) @@ -95,25 +97,24 @@ class NameserverRecordValidationJob < ApplicationJob end logger.info text - failed_log(text: text, nameserver: nameserver, domain: domain) add_nameserver_to_failed(nameserver: nameserver, reason: text) - false end def failed_log(text:, nameserver:, domain:) - inform_to_tech_contact(domain: domain, text: text) + inform_to_tech_contact(domain: domain, nameserver: nameserver, text: text) inform_to_registrar(text: text, nameserver: nameserver) false end - def inform_to_tech_contact(domain:, text: nil) - ContactNotification.notify_tech_contact(domain: domain, reason: 'nameserver') + def inform_to_tech_contact(domain:, nameserver:, text: nil) + ContactNotification.notify_tech_contact(domain: domain, nameserver: nameserver, reason: 'nameserver') end def inform_to_registrar(nameserver:, text: nil) - text = "Host record #{nameserver.hostname} of a domain #{nameserver.domain} is invalid. Please fix or contact the registrant." + text = "Host record #{nameserver.hostname} of a domain #{nameserver.domain} is invalid. + Please fix or contact the registrant. Problem with nameserver #{nameserver} - #{nameserver.failed_validation_reason}" logger.info text ContactNotification.notify_registrar(domain: nameserver.domain, text: text) end diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index 3277914f1..b5357bead 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -133,13 +133,6 @@ class ValidateDnssecJob < ApplicationJob resolver end - def log_templates - { - "true" => "validated successfully", - "false" => "validated fail" - } - end - def logger @logger ||= Rails.logger end diff --git a/app/mailers/contact_inform_mailer.rb b/app/mailers/contact_inform_mailer.rb index 7423da791..bf5037cbf 100644 --- a/app/mailers/contact_inform_mailer.rb +++ b/app/mailers/contact_inform_mailer.rb @@ -10,9 +10,10 @@ class ContactInformMailer < ApplicationMailer mail(to: contact.email, subject: subject) end - def notify_nameserver(contact:, domain:) + def notify_nameserver(contact:, domain:, nameserver:) @contact = contact @domain = domain + @nameserver = nameserver subject = "Domeeni #{@domain.name} nimeserveri kirjed ei ole korrektsed / The host records of the domain #{@domain.name} are invalid" mail(to: contact.email, subject: subject) diff --git a/app/models/nameserver.rb b/app/models/nameserver.rb index 20d4656c6..ababd84cf 100644 --- a/app/models/nameserver.rb +++ b/app/models/nameserver.rb @@ -55,7 +55,7 @@ class Nameserver < ApplicationRecord } end - def nameserver_failed_validation? + def failed_validation? return false if validation_counter.nil? validation_counter >= NameserverValidator::VALID_NAMESERVER_COUNT_THRESHOLD diff --git a/app/services/contact_notification.rb b/app/services/contact_notification.rb index 16765d65d..e9b00c575 100644 --- a/app/services/contact_notification.rb +++ b/app/services/contact_notification.rb @@ -5,7 +5,7 @@ module ContactNotification domain.registrar.notifications.create(text: text) end - def notify_tech_contact(domain:, reason: nil) + def notify_tech_contact(domain:, nameserver: nil, reason: nil) case reason when 'dnssec' domain.tech_contacts.each do |tech| @@ -17,7 +17,7 @@ module ContactNotification domain.tech_contacts.each do |tech| contact = Contact.find(tech.id) - ContactInformMailer.notify_nameserver(contact: contact, domain: domain).deliver_now + ContactInformMailer.notify_nameserver(contact: contact, domain: domain, nameserver: nameserver).deliver_now end end end diff --git a/app/views/mailers/contact_inform_mailer/notify_nameserver.html.erb b/app/views/mailers/contact_inform_mailer/notify_nameserver.html.erb index ce6b968a0..c9df4f6f0 100644 --- a/app/views/mailers/contact_inform_mailer/notify_nameserver.html.erb +++ b/app/views/mailers/contact_inform_mailer/notify_nameserver.html.erb @@ -6,6 +6,8 @@ Eesti Interneti Sihtasutusele (EIS) juhib tähelepanu, et domeeni <%= @domain.na Andmete parandamiseks vaadake palun üle domeeni nimeserverite seaditused või pöörduge palun oma registripidaja <%= @domain.registrar.name%> või nimeserveri teenuse pakkuja poole.

+Viga nimesereriga <%= @nameserver %> - <%= @nameserver.failed_validation_reason %> +

Lisaküsimuste korral võtke palun ühendust oma registripidajaga:

@@ -30,6 +32,8 @@ Lugupidamisega
Please check the name server settings of the domain or contact your registrar <%= @domain.registrar.name%> or your name server service provider to correct this information.

+Problem with nameserver <%= @nameserver %> - <%= @nameserver.failed_validation_reason %>" +

Should you have additional questions, please contact your registrar:

diff --git a/test/jobs/nameserver_record_validation_job_test.rb b/test/jobs/nameserver_record_validation_job_test.rb index a8d625ca1..1f39c6d33 100644 --- a/test/jobs/nameserver_record_validation_job_test.rb +++ b/test/jobs/nameserver_record_validation_job_test.rb @@ -93,6 +93,6 @@ class NameserverRecordValidationJobTest < ActiveSupport::TestCase 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.nameserver_failed_validation? + assert @nameserver.failed_validation? end end diff --git a/test/services/contact_notification_test.rb b/test/services/contact_notification_test.rb index 0e75fb548..ec3d975e6 100644 --- a/test/services/contact_notification_test.rb +++ b/test/services/contact_notification_test.rb @@ -4,6 +4,7 @@ class ContactNotificationTest < ActionMailer::TestCase setup do @domain = domains(:shop) + @nameserver = nameservers(:shop_ns1) @text = 'text' end @@ -14,7 +15,7 @@ class ContactNotificationTest < ActionMailer::TestCase end def test_notify_tech_contacts_that_nameserver_is_broken - ContactNotification.notify_tech_contact(domain: @domain, reason: 'nameserver') + ContactNotification.notify_tech_contact(domain: @domain, reason: 'nameserver', nameserver: @nameserver) assert_equal @domain.tech_contacts.count, 2 assert_emails 2 end From aba8c1fb1746dc6841349b61af61e583116d92a4 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 12 Jan 2022 17:09:53 +0200 Subject: [PATCH 30/33] addede test for dnssec validator --- app/jobs/validate_dnssec_job.rb | 4 ++ test/jobs/validate_dnssec_job_test.rb | 91 ++++++++++++++++++--------- 2 files changed, 64 insertions(+), 31 deletions(-) diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index b5357bead..07728eff1 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -63,6 +63,7 @@ class ValidateDnssecJob < ApplicationJob logger.info "-----------" response_container = parse_response(answer) + compare_dnssec_data(response_container: response_container, domain: domain) rescue Exception => e logger.error "#{e.message} - domain name: #{domain.name} - hostname: #{hostname}" @@ -76,6 +77,7 @@ class ValidateDnssecJob < ApplicationJob flag = make_magic(response_container: response_container, dnskey: key) text = "#{key.flags} - #{key.protocol} - #{key.alg} - #{key.public_key}" + if flag key.validation_datetime = Time.zone.now key.save @@ -98,7 +100,9 @@ class ValidateDnssecJob < ApplicationJob def parse_response(answer) response_container = [] + answer.each_answer do |a| + a_string = a.to_s a_string = a_string.gsub /\t/, ' ' a_string = a_string.split(' ') diff --git a/test/jobs/validate_dnssec_job_test.rb b/test/jobs/validate_dnssec_job_test.rb index d8207492c..cd207e03a 100644 --- a/test/jobs/validate_dnssec_job_test.rb +++ b/test/jobs/validate_dnssec_job_test.rb @@ -1,42 +1,71 @@ -$VERBOSE=nil require 'test_helper' +class ZoneAnswer + def initialize(valid_response: true) + @answer = [] + + algorithm = OpenStruct.new(code: 13) + + answer = OpenStruct.new + answer.data = "some0 some1 some2 257 some4 some5 some6 mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ== some" + answer.flags = 257 + answer.protocol = 3 + answer.protocol = 7 unless valid_response + answer.algorithm = algorithm + + @answer << answer + end + + def each_answer + @answer.each {|rec| + yield rec + } + end +end + class ValidateDnssecJobTest < ActiveJob::TestCase setup do @domain = domains(:shop) @dnskey = dnskeys(:one) end - def test_job_should_return_successfully_validated_dnskeys - # @domain.dnskeys << @dnskey - # @domain.save - # @domain.reload - # - # mock_zone_data = [ - # { - # flags: @dnskey.flags, - # protocol: @dnskey.protocol, - # alg: @dnskey.alg, - # public_key: @dnskey.public_key - # }] - # - # resolver = Spy.mock(Dnsruby::Recursor) - # Spy.on(resolver, :query).and_return true - # Spy.on_instance_method(ValidateDnssecJob, :parse_response).and_return(mock_zone_data) - # # Spy.on_instance_method(ValidateDnssecJob, :prepare_validator).and_return(true) - # - # - # ValidateDnssecJob.perform_now(domain_name: @domain.name) - # - # @domain.reload - # p @domain.dnskeys + def test_job_should_set_validation_datetime_if_validation_is_valid + @domain.nameservers.each do |n| + n.update(validation_datetime: Time.zone.now - 1.minute) + end + @domain.dnskeys << @dnskey + @domain.save + + @domain.reload + + mock_zone_data = ZoneAnswer.new + + Spy.on_instance_method(ValidateDnssecJob, :prepare_validator).and_return(Dnsruby::Resolver.new) + Spy.on_instance_method(Dnsruby::Resolver, :query).and_return(mock_zone_data) + + ValidateDnssecJob.perform_now(domain_name: @domain.name) + + @domain.reload + assert_not_nil @domain.dnskeys.first.validation_datetime end - # def test_job_discarded_after_error - # assert_no_enqueued_jobs - # assert_performed_jobs 1 do - # TestDiscardedJob.perform_later - # end - # assert_no_enqueued_jobs - # end + def test_job_should_not_set_validation_datetime_if_validation_is_invalid + @domain.nameservers.each do |n| + n.update(validation_datetime: Time.zone.now - 1.minute) + end + @domain.dnskeys << @dnskey + @domain.save + + @domain.reload + + mock_zone_data = ZoneAnswer.new(valid_response: false) + + Spy.on_instance_method(ValidateDnssecJob, :prepare_validator).and_return(Dnsruby::Resolver.new) + Spy.on_instance_method(Dnsruby::Resolver, :query).and_return(mock_zone_data) + + ValidateDnssecJob.perform_now(domain_name: @domain.name) + + @domain.reload + assert_nil @domain.dnskeys.first.validation_datetime + end end From e3b370e7c138c709062b0ff03dc283e25ab44f93 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Thu, 27 Jan 2022 09:31:45 +0200 Subject: [PATCH 31/33] updated condition --- app/services/nameserver_validator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/nameserver_validator.rb b/app/services/nameserver_validator.rb index 410448472..c45003cd3 100644 --- a/app/services/nameserver_validator.rb +++ b/app/services/nameserver_validator.rb @@ -18,7 +18,7 @@ module NameserverValidator # result_response = validate(domain_name: domain_name, hostname: nameserver.ipv6) end - return { result: false, reason: 'glup record' } if result.answer.empty? if result_response[:result] + return { result: false, reason: 'glup record' } unless result_response[:result] return result_response end From d2e7148f4f0b216a0c7c8313e8572c4f88e8788c Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 2 Feb 2022 13:44:30 +0200 Subject: [PATCH 32/33] added condition to skip single domain dnssec check if it does not have any dnskeys --- app/jobs/validate_dnssec_job.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index 07728eff1..452f6b4cb 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -5,6 +5,8 @@ class ValidateDnssecJob < ApplicationJob unless domain_name.nil? domain = Domain.find_by(name: domain_name) + return logger.info "This domain not contain any dnskeys" if domain.dnskeys.empty? + return logger.info "No domain found" if domain.nil? return logger.info "No related nameservers for this domain" if domain.nameservers.empty? From d99330a098b0de6eaf2cc886b193e402c902ce80 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 9 Feb 2022 11:05:23 +0200 Subject: [PATCH 33/33] comment out notifications --- app/jobs/nameserver_record_validation_job.rb | 4 ++-- app/jobs/validate_dnssec_job.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/jobs/nameserver_record_validation_job.rb b/app/jobs/nameserver_record_validation_job.rb index 9271d94d7..7dd2211a4 100644 --- a/app/jobs/nameserver_record_validation_job.rb +++ b/app/jobs/nameserver_record_validation_job.rb @@ -109,14 +109,14 @@ class NameserverRecordValidationJob < ApplicationJob end def inform_to_tech_contact(domain:, nameserver:, text: nil) - ContactNotification.notify_tech_contact(domain: domain, nameserver: nameserver, reason: 'nameserver') + # ContactNotification.notify_tech_contact(domain: domain, nameserver: nameserver, reason: 'nameserver') end def inform_to_registrar(nameserver:, text: nil) text = "Host record #{nameserver.hostname} of a domain #{nameserver.domain} is invalid. Please fix or contact the registrant. Problem with nameserver #{nameserver} - #{nameserver.failed_validation_reason}" logger.info text - ContactNotification.notify_registrar(domain: nameserver.domain, text: text) + # ContactNotification.notify_registrar(domain: nameserver.domain, text: text) end def logger diff --git a/app/jobs/validate_dnssec_job.rb b/app/jobs/validate_dnssec_job.rb index 452f6b4cb..623513768 100644 --- a/app/jobs/validate_dnssec_job.rb +++ b/app/jobs/validate_dnssec_job.rb @@ -50,8 +50,8 @@ class ValidateDnssecJob < ApplicationJob text = "DNSKEY record of a domain #{domain.name} is invalid. Please fix or contact the registrant." logger.info text - ContactNotification.notify_registrar(domain: domain, text: text) - ContactNotification.notify_tech_contact(domain: domain, reason: 'dnssec') + # ContactNotification.notify_registrar(domain: domain, text: text) + # ContactNotification.notify_tech_contact(domain: domain, reason: 'dnssec') end def validate(hostname:, domain:, type: 'DNSKEY', klass: 'IN')