As per RFC 2308, add SOA to authoriative answers with nodata, or errors

This commit is contained in:
Deon George 2023-11-12 18:14:53 +11:00
parent 85243d128e
commit ea42a347eb

View File

@ -91,6 +91,7 @@ final class DNS extends BaseProtocol
* Handle a DNS query * Handle a DNS query
* *
* https://www.ietf.org/rfc/rfc1035.txt * https://www.ietf.org/rfc/rfc1035.txt
* https://www.ietf.org/rfc/rfc2308.txt
* https://github.com/guyinatuxedo/dns-fuzzer/blob/master/dns.md * https://github.com/guyinatuxedo/dns-fuzzer/blob/master/dns.md
* *
* labels 63 octets or less * labels 63 octets or less
@ -119,7 +120,7 @@ final class DNS extends BaseProtocol
// If the wrong class // If the wrong class
if ($this->query->class !== self::DNS_QUERY_IN) { if ($this->query->class !== self::DNS_QUERY_IN) {
Log::error(sprintf('%s:! We only service Internet queries [%d]',self::LOGKEY,$this->query->class)); 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(); $dos = Domain::select(['id','name','dnsdomain'])->active();
@ -148,15 +149,7 @@ final class DNS extends BaseProtocol
return $this->reply( return $this->reply(
self::DNS_NOERROR, self::DNS_NOERROR,
[serialize([ $this->soa(),
$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],
[], [],
[serialize($this->domain_split(gethostname())) => self::DNS_TYPE_NS], [serialize($this->domain_split(gethostname())) => self::DNS_TYPE_NS],
); );
@ -255,7 +248,7 @@ final class DNS extends BaseProtocol
]) => self::DNS_TYPE_SRV]); ]) => self::DNS_TYPE_SRV]);
} else { } else {
return $this->nameerr(); return $this->nodata();
} }
case self::DNS_TYPE_TXT: case self::DNS_TYPE_TXT:
@ -279,7 +272,7 @@ final class DNS extends BaseProtocol
default: default:
Log::error(sprintf('%s:! We dont support DNS query types [%d]',self::LOGKEY,$this->query->type)); 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)); 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 private function nameerr(): int
{ {
Log::error(sprintf('%s:! DNS query for a resource we dont manage [%s]',self::LOGKEY,$this->query->domain)); 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; 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 * Return a DNS Resource Record
* *
@ -458,4 +458,18 @@ final class DNS extends BaseProtocol
return $reply; 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];
}
} }