pub struct DnsSinkhole { /* private fields */ }Expand description
Local DNS authority that swallows lookups for disallowed / unknown names.
All agent DNS goes here first (PRODUCT.md B.5 step 1). Combined with the signed auto-updating IOC feed it blunts C2 over freshly-registered domains (PRODUCT.md Part D row “C2 over a freshly-registered domain”: “Signed auto-updating feed + DNS sinkhole + destination-entropy anomaly”).
Fail-closed: an unknown name resolves to a sinkhole / NXDOMAIN, never to the
real address (PRODUCT.md W0).
Implementations§
Source§impl DnsSinkhole
impl DnsSinkhole
Sourcepub fn new() -> Self
pub fn new() -> Self
Construct a fail-closed DNS sinkhole with an empty allowlist: any name not
on the allowlist resolves to NXDOMAIN, never to the real address
(PRODUCT.md W0 - fail-closed by construction).
Sourcepub fn with_allowlist(
self,
hosts: impl IntoIterator<Item = impl Into<String>>,
) -> Self
pub fn with_allowlist( self, hosts: impl IntoIterator<Item = impl Into<String>>, ) -> Self
Set the egress allowlist - only these hostnames are forwarded upstream.
Sourcepub fn with_upstream(self, addr: SocketAddr) -> Self
pub fn with_upstream(self, addr: SocketAddr) -> Self
Override the upstream recursive resolver (default 8.8.8.8:53).
Sourcepub async fn start(&self, addr: SocketAddr) -> Result<()>
pub async fn start(&self, addr: SocketAddr) -> Result<()>
Bind the sinkhole on addr (UDP) and serve until cancelled.
For each query (PRODUCT.md B.5 step 1):
- Hostname in allowlist → forward to upstream resolver.
- Hostname not in allowlist → NXDOMAIN (fail-closed, PRODUCT.md W0).
- Parse/protocol error → SERVFAIL and drop.