Add the ability to return synthetic response for undelegated TLDs

solofilter
Frank Denis 4 years ago
parent 3d3a96a6f9
commit 3864de1951

@ -170,6 +170,14 @@ key_cache_capacity = 10000
# domain_blacklist = "/etc/domain_blacklist.txt"
## List of undelegated TLDs
## This is the list of nonexistent TLDs that queries are frequently observed for,
## but will never resolve to anything. The server will immediately return a
## synthesized NXDOMAIN response instead of hitting root servers.
# undelegated_list = "/etc/undelegated.txt"
#########################
# Metrics #

@ -48,6 +48,7 @@ pub struct ListenAddrConfig {
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct FilteringConfig {
pub domain_blacklist: Option<PathBuf>,
pub undelegated_list: Option<PathBuf>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]

@ -214,6 +214,10 @@ pub fn normalize_qname(packet: &mut [u8]) -> Result<(), Error> {
Ok(())
}
pub fn qname_tld(qname: &[u8]) -> &[u8] {
qname.rsplit(|c| *c == b'.').next().unwrap_or_default()
}
pub fn recase_qname(packet: &mut [u8], qname: &[u8]) -> Result<(), Error> {
debug_assert!(std::usize::MAX > 0xffff);
ensure!(qdcount(packet) == 1, "Unexpected query count");
@ -457,7 +461,7 @@ pub fn serve_certificates<'t>(
Ok(Some(packet))
}
pub fn serve_truncated(client_packet: Vec<u8>) -> Result<Vec<u8>, Error> {
pub fn serve_truncated_response(client_packet: Vec<u8>) -> Result<Vec<u8>, Error> {
ensure!(client_packet.len() >= DNS_HEADER_SIZE, "Short packet");
ensure!(qdcount(&client_packet) == 1, "No question");
ensure!(
@ -474,6 +478,23 @@ pub fn serve_truncated(client_packet: Vec<u8>) -> Result<Vec<u8>, Error> {
Ok(packet)
}
pub fn serve_nxdomain_response(client_packet: Vec<u8>) -> Result<Vec<u8>, Error> {
ensure!(client_packet.len() >= DNS_HEADER_SIZE, "Short packet");
ensure!(qdcount(&client_packet) == 1, "No question");
ensure!(
!is_response(&client_packet),
"Question expected, but got a response instead"
);
let offset = skip_name(&client_packet, DNS_HEADER_SIZE)?;
let mut packet = client_packet;
ensure!(packet.len() - offset >= 4, "Short packet");
packet.truncate(offset + 4);
an_ns_ar_count_clear(&mut packet);
authoritative_response(&mut packet);
set_rcode_nxdomain(&mut packet);
Ok(packet)
}
pub fn serve_blocked_response(client_packet: Vec<u8>) -> Result<Vec<u8>, Error> {
ensure!(client_packet.len() >= DNS_HEADER_SIZE, "Short packet");
ensure!(qdcount(&client_packet) == 1, "No question");

@ -41,6 +41,7 @@ pub struct Globals {
pub cache: Cache,
pub cert_cache: Cache,
pub blacklist: Option<BlackList>,
pub undelegated_list: Option<BlackList>,
pub anonymized_dns_enabled: bool,
pub anonymized_dns_allowed_ports: Vec<u16>,
pub anonymized_dns_allow_non_reserved_ports: bool,

@ -102,7 +102,7 @@ fn maybe_truncate_response(
if encrypted_response_min_len > original_packet_size
|| encrypted_response_min_len > DNSCRYPT_UDP_RESPONSE_MAX_SIZE
{
return Ok(dns::serve_truncated(packet)?);
return Ok(dns::serve_truncated_response(packet)?);
}
}
Ok(response)
@ -618,6 +618,16 @@ fn main() -> Result<(), Error> {
.map_err(|e| anyhow!("Unable to load the blacklist [{:?}]: [{}]", path, e))?,
),
};
let undelegated_list = match config.filtering.undelegated_list {
None => None,
Some(path) => Some(BlackList::load(&path).map_err(|e| {
anyhow!(
"Unable to load the list of undelegated TLDs [{:?}]: [{}]",
path,
e
)
})?),
};
let (
anonymized_dns_enabled,
anonymized_dns_allowed_ports,
@ -662,6 +672,7 @@ fn main() -> Result<(), Error> {
cache,
cert_cache,
blacklist,
undelegated_list,
anonymized_dns_enabled,
anonymized_dns_allowed_ports,
anonymized_dns_allow_non_reserved_ports,

@ -170,6 +170,13 @@ pub async fn get_cached_response_or_resolve(
return dns::serve_blocked_response(packet.to_vec());
}
}
if let Some(undelegated_list) = &globals.undelegated_list {
if undelegated_list.find(dns::qname_tld(&packet_qname)) {
#[cfg(feature = "metrics")]
globals.varz.client_queries_rcode_nxdomain.inc();
return dns::serve_nxdomain_response(packet.to_vec());
}
}
let original_tid = dns::tid(&packet);
dns::set_tid(&mut packet, 0);
dns::normalize_qname(&mut packet)?;

@ -0,0 +1,38 @@
1
airdream
api
bbrouter
belkin
blinkap
corp
davolink
dearmyrouter
dhcp
dlink
domain
envoy
grp
gw==
home
hub
internal
intra
invalid
ksyun
loc
local
localdomain
localnet
modem
mynet
myrouter
novalocal
openstacklocal
priv
prv
router
telus
totolink
wlan_ap
workgroup
zghjccbob3n0
Loading…
Cancel
Save