From ea42a347ebf094a497096b769d99abce8a615636 Mon Sep 17 00:00:00 2001 From: Deon George Date: Sun, 12 Nov 2023 18:14:53 +1100 Subject: [PATCH] As per RFC 2308, add SOA to authoriative answers with nodata, or errors --- app/Classes/Protocol/DNS.php | 76 +++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/app/Classes/Protocol/DNS.php b/app/Classes/Protocol/DNS.php index 8a4b07d..79050e8 100644 --- a/app/Classes/Protocol/DNS.php +++ b/app/Classes/Protocol/DNS.php @@ -91,6 +91,7 @@ final class DNS extends BaseProtocol * Handle a DNS query * * https://www.ietf.org/rfc/rfc1035.txt + * https://www.ietf.org/rfc/rfc2308.txt * https://github.com/guyinatuxedo/dns-fuzzer/blob/master/dns.md * * labels 63 octets or less @@ -119,7 +120,7 @@ final class DNS extends BaseProtocol // If the wrong class if ($this->query->class !== self::DNS_QUERY_IN) { Log::error(sprintf('%s:! We only service Internet queries [%d]',self::LOGKEY,$this->query->class)); - return $this->reply(self::DNS_NOTIMPLEMENTED); + return $this->reply(self::DNS_NOTIMPLEMENTED,[],$this->soa()); } $dos = Domain::select(['id','name','dnsdomain'])->active(); @@ -148,15 +149,7 @@ final class DNS extends BaseProtocol return $this->reply( self::DNS_NOERROR, - [serialize([ - $this->domain_split(gethostname()), - $this->domain_split(Str::replace('@','.',config('app.mail.mail_from','nobody@'.gethostname()))), - 1, - self::DEFAULT_TTL, - self::DEFAULT_TTL, - self::DEFAULT_TTL, - self::DEFAULT_TTL - ]) => self::DNS_TYPE_SOA], + $this->soa(), [], [serialize($this->domain_split(gethostname())) => self::DNS_TYPE_NS], ); @@ -255,7 +248,7 @@ final class DNS extends BaseProtocol ]) => self::DNS_TYPE_SRV]); } else { - return $this->nameerr(); + return $this->nodata(); } case self::DNS_TYPE_TXT: @@ -279,7 +272,7 @@ final class DNS extends BaseProtocol default: Log::error(sprintf('%s:! We dont support DNS query types [%d]',self::LOGKEY,$this->query->type)); - return $this->reply(self::DNS_NOTIMPLEMENTED); + return $this->reply(self::DNS_NOTIMPLEMENTED,[],$this->soa()); } } @@ -294,11 +287,36 @@ final class DNS extends BaseProtocol return pack('n',$offset | (3 << 14)); } + /** + * Split a domain into a DNS domain string + * + * @param string $domain + * @return string + */ + private function domain_split(string $domain): string + { + $a = ''; + + foreach (explode('.',$domain) as $item) + $a .= pack('C',strlen($item)).$item; + + $a .= "\x00"; + + return $a; + } + private function nameerr(): int { Log::error(sprintf('%s:! DNS query for a resource we dont manage [%s]',self::LOGKEY,$this->query->domain)); - return $this->reply(self::DNS_NAMEERR); + return $this->reply(self::DNS_NAMEERR,[],$this->soa()); + } + + private function nodata(): int + { + Log::error(sprintf('%s:! DNS query for a resource we dont manage [%s] in our zone(s)',self::LOGKEY,$this->query->domain)); + + return $this->reply(self::DNS_NOERROR,[],$this->soa()); } /** @@ -384,24 +402,6 @@ final class DNS extends BaseProtocol return TRUE; } - /** - * Split a domain into a DNS domain string - * - * @param string $domain - * @return string - */ - private function domain_split(string $domain): string - { - $a = ''; - - foreach (explode('.',$domain) as $item) - $a .= pack('C',strlen($item)).$item; - - $a .= "\x00"; - - return $a; - } - /** * Return a DNS Resource Record * @@ -458,4 +458,18 @@ final class DNS extends BaseProtocol return $reply; } + + private function soa(): array + { + return + [serialize([ + $this->domain_split(gethostname()), + $this->domain_split(Str::replace('@','.',config('app.mail.mail_from','nobody@'.gethostname()))), + 1, // Serial + self::DEFAULT_TTL, // Refresh + self::DEFAULT_TTL, // Retry + self::DEFAULT_TTL*7,// Expire + self::DEFAULT_TTL // Minimum cache + ]) => self::DNS_TYPE_SOA]; + } } \ No newline at end of file