Skip to content

Commit

Permalink
Catch valid DNSSEC signed SERVFAIL answers (#3271)
Browse files Browse the repository at this point in the history
Co-authored-by: ammar92 <[email protected]>
Co-authored-by: Jeroen Dekkers <[email protected]>
  • Loading branch information
3 people authored Jul 31, 2024
1 parent 324692c commit 57b2bf0
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ repos:
hooks:
- id: codespell
additional_dependencies: ["tomli"]
args: [-L, lama]
args: ["-L", "lama", "--ignore-regex", ".{1024}|.*codespell-ignore.*"]
exclude: |
(?x)(
\.po$ |
Expand Down
14 changes: 14 additions & 0 deletions boefjes/boefjes/plugins/kat_dns/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from os import getenv

import dns.resolver
from dns.edns import EDEOption
from dns.name import Name
from dns.resolver import Answer

Expand Down Expand Up @@ -52,6 +53,9 @@ def run(boefje_meta: BoefjeMeta) -> list[tuple[set, bytes | str]]:

requested_dns_name = dns.name.from_text(hostname)
resolver = dns.resolver.Resolver()
# https://dnspython.readthedocs.io/en/stable/_modules/dns/edns.html
# enable EDE to get the DNSSEC Bogus return values if the server supports it # codespell-ignore
resolver.use_edns(options=[EDEOption(15)])
nameserver = getenv("REMOTE_NS", "1.1.1.1")
resolver.nameservers = [nameserver]

Expand Down Expand Up @@ -102,6 +106,16 @@ def get_email_security_records(resolver: dns.resolver.Resolver, hostname: str, r
try:
answer = resolver.resolve(f"{record_subdomain}.{hostname}", "TXT", raise_on_no_answer=False)
return answer.response.to_text()
except dns.resolver.NoNameservers as error:
# no servers responded happily, we'll check the response from the first
# https://dnspython.readthedocs.io/en/latest/_modules/dns/rcode.html
# https://www.rfc-editor.org/rfc/rfc8914#name-extended-dns-error-code-6-d
firsterror = error.kwargs["errors"][0]
if firsterror[3] == "SERVFAIL":
edeerror = int(firsterror[4].options[0].code)
if edeerror in (1, 2, 5, 6, 7, 8, 9, 10, 11, 12): # DNSSEC error codes defined in RFC 8914
return "DNSSECFAIL" # returned when the resolver indicates a DNSSEC failure.
raise # Not dnssec related, unhandled, raise.
except dns.resolver.NXDOMAIN:
return "NXDOMAIN"
except dns.resolver.Timeout:
Expand Down
2 changes: 1 addition & 1 deletion boefjes/boefjes/plugins/kat_dns/normalize.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def register_record(record: DNSRecord) -> DNSRecord:

# DKIM
dkim_results = results["dkim_response"]
if dkim_results not in ["NXDOMAIN", "Timeout"] and dkim_results.split("\n")[2] == "rcode NOERROR":
if dkim_results not in ["NXDOMAIN", "Timeout", "DNSSECFAIL"] and dkim_results.split("\n")[2] == "rcode NOERROR":
yield DKIMExists(
hostname=input_hostname.reference,
)
Expand Down

0 comments on commit 57b2bf0

Please sign in to comment.