root hints vs RFC 8806

An interesting discussion came up at a nerd dinner :-), where, the argument was that a recursive resolver already knows where the root servers are (root hints ) i.e the IPv4 and IPv6 addresses, so then what is the purpose of running a local copy of the root zone in the recursive resolver aka RFC 8806?

What are the root hints?

The root hints are a list of the servers that are authoritative for the root domain “.”, along with their IPv4 and IPv6 addresses. In other words, this is a collection of NS, A, and AAAA records for the root nameservers.
Source

Coming back to the question, to answer this, let’s look at a few assumptions,

  1. The root servers are going to be available at all times
  2. Even if the DNS query is not for a fully qualified domain name(FQDN), send the query to the root aka send junk to the root
  3. Because my recursive resolver knows the IPv4 and IPv6 addresses of the root servers, and, there are local instances of the root servers in the country, the DNS query to the root will hit the local instance

All the above assumptions are the reason recursive resolvers must embrace RFC 8806. For now, let’s focus on the third point because just knowing the IP addresses of the root servers is not enough. Packets need to traverse to the right address.

Aye Aye BGP!

Even if there’s a local root server instance in your country and your recursive resolver knows its IP address (from the root.hints file), the actual query might still transit outside the country due to BGP path selection inefficiencies. Case in point.

All root servers use IP anycast, which means:

  • The same IP address (e.g., for F-root: 192.5.5.241) is announced by multiple physical servers worldwide.
  • BGP determines which instance your resolver talks to, based on routing.

So even if:

  • A root server instance is in your country,
  • Your resolver queries 192.5.5.241 (from root hints),

…it could still be routed to another country, depending on how BGP steers the traffic at that time.

RFC 8806 suggests keeping a local copy of the root zone, which allows the resolver to:

  • Provide the same referrals the root server would give, but from memory/disk instead of waiting for a network response.

A recursive resolver with a local copy of the root zone is shaving off the round-trip time(RTT) to the root servers entirely, thereby eliminating any inefficiency in BGP routing. This may not mean much in low-traffic environments, but if you are an ISP/network operator, shaving even 20–50ms per resolution adds up.

Despite high TTLs on DNS A and AAAA records, a local root zone is especially beneficial during a cold start, when the resolver has no cached data.

Stop sending junk DNS queries to core Internet infrastructure

While it may not be possible to fix all software and ensure full RFC compliance, we can certainly put measures in place to mitigate unwanted or intentional or unintentional abuse of core Internet infrastructure.

An added benefit? It also eliminates junk traffic to the root servers. From a make-the-internet-better perspective, that’s a net win!

If you found this blog post useful, you might find RBI Cyber Security policy .bank.in and .fin.in interesting.

APRICOT 2025 – DNS RPZ tutorial

I recently delivered a hands-on tutorial at APRICOT 2025 on Blocking Threats at the DNS Layer: Using Response Policy Zones (RPZ) for Threat Detection & Mitigation. Thanks to CISA, DNS RPZ is now widely recognized under the broader umbrella of Protective DNS.

The goal was to introduce the power of DNS RPZ and demonstrate practical ways to deploy a DNS Firewall for blocking and mitigating threats at the DNS layer.

Swapneel Patnekar delivering a tutorial at APRICOT

Figure 1: Swapneel Patnekar delivering a tutorial

While network operators understand the critical nature of DNS infrastructure, few realize that DNS can also serve as a chokepoint—or sinkhole—to disrupt malicious communications.

Aside from the usefulness of DNS RPZ in an enterprise network, DNS RPZ has immense value for a network operator.

Why network operators should leverage DNS RPZ?

One of the persistent challenges for network operators is that IP addresses from their customer networks end up on blocklists. This typically occurs due to malicious traffic (e.g., spam, malware, botnet C2) originating from infected or compromised devices within their network.

The upstream impact of this can be severe:

  • The customer is unable to access a particular website/service on the Internet.
    Web Application firewalls(WAF) deploy blacklisting/threat intelligence to block access to the website/application
  • The Customer is unable to make a payment online
    Fraud detection algorithms at payment deploy blocklist/threat intelligence to block access
  • An enterprise customer is unable to sending and receive email
    IP address assigned to the customer is listed in blocklist database/threat intelligence

A network operator can choose to:

  1. Block DNS queries to known malicious domains, or
  2. Redirect them to a sinkhole for analysis or remediation

This helps contain abuse before it results in IP reputation damage. For large-scale operators, contacting individual customers is not scalable.

⚠️ Important Caveat: DNS RPZ is effective only when the communication uses domain names. It does not block direct IP-based malicious communication.

If you found this blog post useful, you might find APNIC 52 – Threat Hunting using DNS or RPZ Feed list: OSINT Threat Intelligence for DNS Security or Open resolvers in India interesting.

RBI Cyber Security policy .bank.in and .fin.in

The Reserve Bank of India (RBI) in its latest cyber security policy released on 7th February 2025, has mandated all banks to use .bank.in and non-banks(other financial institutions) to use .fin.in. The goal of the measures is to curb phishing attacks against citizens of India.

RBI Cyber Security policy for banks to use .bank.in and non-banks to use fin.in

Figure 1: Snippet of RBI’s Cybersecurity policy

Notably, Institute for Development and Research in Banking Technology (IDRBT) will be the registrar for the parent domain names (.bank.in and .fin.in)

Technical details

In a DNS context, I am guessing IDRBT would control the parent zones .bank.in and .fin.in and delegate for example icici.bank.in to ICICI Bank authoritative nameservers.

Similarly, zerodha.fin.in would be delegated to Zerodha authoritative nameservers.

IDRBT would be able to control the namespace and delegate child zone to the respective bank or financial institution.

Delegation of DNS namespace from the root to .in and .bank.in and .fin.in

Figure 2: Diagrammatic representation of possible delegation of bank.in and fin.in domain namespace

Limitations of the cyber security policy

In my opinion, this is an excellent move at the policy level from a cybersecurity perspective. There will be operational challenges from the perspective of the banks or financial institutions. I will reserve them for another blog post.

However, this measure will not eliminate all types of phishing/impersonation , typo-squatting or domain shadowing attacks

Despite this, the RBI Cyber Security Policy aims to build trust in the namespace by restricting domain names for banks and non-banks to .bank.in and .fin.in, respectively. From a consumer’s perspective, this simplifies decision-making. As I mentioned earlier, this won’t eliminate all threats, but it is a good start and certainly better than the common advice banks give—checking for the padlock to ensure a website uses HTTPS!

At the time of writing, the delegation from .in at NIXI to IDRBT was not yet operational.

Delegation of bank.in and fin.in not yet implemented in .in namespace at NIXI

Figure 3: Delegation of bank.in and fin.in not yet implemented at NIXI

It is to be noted, that the RBI cyber security policy implementation will start April 2025 onwards.

If you liked this blog post, you might also enjoy reading Jio VoWiFi issue – It’s always DNS! or The curious case of esic.in DNS

RPZ Feed list: OSINT Threat Intelligence for DNS Security

This page lists OSINT DNS RPZ Feeds for recursive resolvers to enhance security by blocking malware, phishing, and C2 domains. Submit your RPZ feed if it’s not listed.

Response Policy Zones(RPZ) or DNS Firewall or Protective DNS (thanks CISA) is a solid way to use the DNS protocol as a defense. For a primer on DNS RPZ, please see the blog post

URLhaus Abuse.ch – Primarily malware domain names

CERT.pl – Phishing domain names targeting Polish citizens

YOYO – Advertisement domain names

StevenBlack hosts – Advertisement domain names & others(malware, gambling, porn)

If you enjoyed reading this blog post, you might find APRICOT 2025 – DNS RPZ tutorial interesting.

CERT-In : Sensor for MSME networks for logs

If you are an MSME and are looking at complying to the CERT-In directives on logs, then, a sensor we’ve built for generating and storing logs of the entire network, might just be what you are looking for.

What do the CERT-In directives on logs state

All service providers, intermediaries, data centres, body corporate and
Government organisations shall mandatorily enable logs of all their ICT
systems and maintain them securely for a rolling period of 180 days and
the same shall be maintained within the Indian jurisdiction. These should
be provided to CERT-In along with reporting of any incident or when
ordered / directed by CERT-In.

Challenges faced in incident response environments (MSME) with no logs

The idea of building a sensor stemmed from our experiences of incident response in environments with zero security posture.

CERT-In sensor MSME logs

The same sensor can capture network packets and generate logs per the CERT-In directives.

At the btNOG-9 Conference on the 14th October 2022, I’ll be presenting Incident Response on a shoestring budget

In the presentation, I’ll share the challenges we faced in incident response environments with zero security posture, i.e. lacking logs, etc. The presentation will then focus on the solution – a sensor we built using open-source software such as Suricata and Zeek, logging DNS queries etc.

By deploying a sensor in the network, MSMEs can comply with the CERT-In directives and also facilitate incident responders to investigate security incidents.

Incident responders can leverage the rich logs by intercepting and ingesting packets into tools such as Zeek. If you are new to Zeek, check the blog post, Packets don’t lie – Threat Hunting with Zeek and the APNIC Academy page where a recording of the webinar will be available soon.

For a broader deep dive into why Network Security Monitoring is important in the context of incident response, check my presentation on Packets don’t lie – Network Security Monitoring (NSM) for the masses

Aside from the folks at BtCIRT, I am hoping there would be a bunch of other folks from a security background interested in incident response.

Little Snitch – Capturing traffic of a specific process

While investigating a bit of oddity with the Skype app on Mac OS X, I wanted to capture all traffic from only the Skype processes.

But first, a little background on the issue. All DNS traffic from my systems is routed through a WireGuard tunnel. The peer endpoint at the other end runs a recursive resolver with DNS Response Policy Zones (DNS RPZ).

The issue is – that as soon as the WireGuard tunnel is disabled, Skype will try connecting to Google DNS(8.8.8.8) and www.bing.com. Perhaps Skype bypasses the local recursive resolver set on the system and sends the DNS queries for its hosts to Google DNS directly? I cannot ascertain that yet, and it warrants a thorough investigation.

I was alerted to this by Little Snitch after I refreshed the rules. A ritual that I seem to follow every few months.

Little Snitch Network Monitor contains a hidden gem. The ability to capture traffic of a specific process.

For example, by right-clicking on any process, you should see the option to Capture Traffic. That should open a terminal window prompting for the sudo password.

After capturing traffic and interrupting should result in a PCAP on the Desktop. Neat!

Little Snitch documentation about this feature.

If you liked this blog post, you might also enjoy reading Firefox Multi Account Containers

Shodan geoping and geodns – check ping & DNS resolution

Measuring ping and DNS from different vantage points using RIPE Atlas has been something that I have been using for some time now. You can read about installing a RIPE Atlas software probe here

A few weeks ago, I came across Shodan’s geoping and geodns API, which provides ping and DNS lookup from a few locations and other details such as RTT. This is great because you can quickly check ping and DNS resolution on systems where you only have curl running.

You always have the RIPE Atlas project for more detailed and sophisticated use-cases. To get started with the RIPE Atlas project, check the webinar I delivered some time ago for APNIC.

curl https://geonet.shodan.io/api/geoping/139.59.19.245 | jq .
[
  {
    "ip": "139.59.19.245",
    "is_alive": true,
    "min_rtt": 41.439,
    "avg_rtt": 41.539,
    "max_rtt": 41.689,
    "rtts": [
      41.68868064880371,
      41.4891242980957,
      41.43881797790527
    ],
    "packets_sent": 3,
    "packets_received": 3,
    "packet_loss": 0,
    "from_loc": {
      "city": "Singapore",
      "country": "SG",
      "latlon": "1.3215,103.6957"
    }
  },
  {
    "ip": "139.59.19.245",
    "is_alive": true,
    "min_rtt": 229.823,
    "avg_rtt": 230.04,
    "max_rtt": 230.268,
    "rtts": [
      230.2682399749756,
      229.82311248779297,
      230.0271987915039
    ],
    "packets_sent": 3,
    "packets_received": 3,
    "packet_loss": 0,
    "from_loc": {
      "city": "Santa Clara",
      "country": "US",
      "latlon": "37.3924,-121.9623"
    }
  },
  {
    "ip": "139.59.19.245",
    "is_alive": true,
    "min_rtt": 183.42,
    "avg_rtt": 183.567,
    "max_rtt": 183.683,
    "rtts": [
      183.68268013000488,
      183.41970443725586,
      183.59804153442383
    ],
    "packets_sent": 3,
    "packets_received": 3,
    "packet_loss": 0,
    "from_loc": {
      "city": "Frankfurt am Main",
      "country": "DE",
      "latlon": "50.1025,8.6299"
    }
  },
  {
    "ip": "139.59.19.245",
    "is_alive": true,
    "min_rtt": 185.742,
    "avg_rtt": 185.865,
    "max_rtt": 185.993,
    "rtts": [
      185.99295616149902,
      185.86158752441406,
      185.74166297912598
    ],
    "packets_sent": 3,
    "packets_received": 3,
    "packet_loss": 0,
    "from_loc": {
      "city": "Amsterdam",
      "country": "NL",
      "latlon": "52.3740,4.8897"
    }
  },
  {
    "ip": "139.59.19.245",
    "is_alive": true,
    "min_rtt": 267.025,
    "avg_rtt": 267.047,
    "max_rtt": 267.061,
    "rtts": [
      267.0609951019287,
      267.05384254455566,
      267.0247554779053
    ],
    "packets_sent": 3,
    "packets_received": 3,
    "packet_loss": 0,
    "from_loc": {
      "city": "Clifton",
      "country": "US",
      "latlon": "40.8344,-74.1377"
    }
  },
  {
    "ip": "139.59.19.245",
    "is_alive": true,
    "min_rtt": 261.196,
    "avg_rtt": 261.239,
    "max_rtt": 261.279,
    "rtts": [
      261.1956596374512,
      261.24072074890137,
      261.2793445587158
    ],
    "packets_sent": 3,
    "packets_received": 3,
    "packet_loss": 0,
    "from_loc": {
      "city": "London",
      "country": "GB",
      "latlon": "51.5085,-0.1257"
    }
  }
]

The geodns API enables looking up DNS across multiple locations.

curl https://geonet.shodan.io/api/geodns/brainattic.in  | jq .
[
  {
    "answers": [
      {
        "type": "A",
        "value": "139.59.19.245"
      }
    ],
    "from_loc": {
      "city": "Clifton",
      "country": "US",
      "latlon": "40.8344,-74.1377"
    }
  },
  {
    "answers": [
      {
        "type": "A",
        "value": "139.59.19.245"
      }
    ],
    "from_loc": {
      "city": "Frankfurt am Main",
      "country": "DE",
      "latlon": "50.1025,8.6299"
    }
  },
  {
    "answers": [
      {
        "type": "A",
        "value": "139.59.19.245"
      }
    ],
    "from_loc": {
      "city": "London",
      "country": "GB",
      "latlon": "51.5085,-0.1257"
    }
  },
  {
    "answers": [
      {
        "type": "A",
        "value": "139.59.19.245"
      }
    ],
    "from_loc": {
      "city": "Amsterdam",
      "country": "NL",
      "latlon": "52.3740,4.8897"
    }
  },
  {
    "answers": [
      {
        "type": "A",
        "value": "139.59.19.245"
      }
    ],
    "from_loc": {
      "city": "Singapore",
      "country": "SG",
      "latlon": "1.3215,103.6957"
    }
  },
  {
    "answers": [
      {
        "type": "A",
        "value": "139.59.19.245"
      }
    ],
    "from_loc": {
      "city": "Santa Clara",
      "country": "US",
      "latlon": "37.3924,-121.9623"
    }
  }
]

The geodns command provides the output in shell format,

# geodns google.com
142.250.178.14                 London
142.250.186.46                 Frankfurt am Main
142.250.80.46                  Clifton
142.251.36.46                  Amsterdam
74.125.68.100                  Singapore
74.125.68.101                  Singapore
74.125.68.102                  Singapore
74.125.68.113                  Singapore
74.125.68.138                  Singapore
74.125.68.139                  Singapore

Similarly, the geoping command,

# geoping 8.8.8.8
Amsterdam (NL)                 0.863 ms       (min: 0.509 ms, max: 1.414 ms)
Clifton (US)                   1.985 ms       (min: 1.729 ms, max: 2.443 ms)
Frankfurt am Main (DE)         1.167 ms       (min: 0.754 ms, max: 1.979 ms)
London (GB)                    0.769 ms       (min: 0.527 ms, max: 1.229 ms)
Santa Clara (US)               2.273 ms       (min: 1.638 ms, max: 3.151 ms)
Singapore (SG)                  1.53 ms       (min:  1.13 ms, max: 2.204 ms)

The details about the geoping and geodns commands are available here

Further reading

The curious case of esic.in DNS

A couple of weeks ago, at my $dayjob, we implemented a recursive resolver with RPZ in an enterprise network.

After a few days, the customer got back to us with an issue – the DNS resolution of the domain esic.in failed with an NXDOMAIN response. After a cursory look at the problem, it became evident that esic.in resolved correctly but www.esic.in did not.

The customer also reported that if they switched the resolver to 8.8.8.8, the DNS resolution of www.esic.in was without any problems, and the website was accessible in the network.

So, what is causing the DNS issue with www.esic.in with the on-prem resolver?

Let’s find out. To start with the basics, here are the authoritative name servers of the domain esic.in,

$ whois esic.in | grep "Name Server:"
Name Server: ns-1089.awsdns-08.org
Name Server: ns-52.awsdns-06.com
Name Server: ns-1978.awsdns-55.co.uk
Name Server: ns-882.awsdns-46.net

If we traverse the DNS delegation from the root to esic.in, we get valuable insights,

.	518400	IN	NS	k.root-servers.net.
.	518400	IN	NS	l.root-servers.net.
.	518400	IN	NS	d.root-servers.net.
.	518400	IN	NS	e.root-servers.net.
.	518400	IN	NS	j.root-servers.net.
.	518400	IN	NS	b.root-servers.net.
.	518400	IN	NS	g.root-servers.net.
.	518400	IN	NS	a.root-servers.net.
.	518400	IN	NS	h.root-servers.net.
.	518400	IN	NS	m.root-servers.net.
.	518400	IN	NS	i.root-servers.net.
.	518400	IN	NS	c.root-servers.net.
.	518400	IN	NS	f.root-servers.net.
in.	172800	IN	NS	ns1.registry.in.
in.	172800	IN	NS	ns2.registry.in.
in.	172800	IN	NS	ns3.registry.in.
in.	172800	IN	NS	ns4.registry.in.
in.	172800	IN	NS	ns5.registry.in.
in.	172800	IN	NS	ns6.registry.in.
esic.in.	3600	IN	NS	ns-882.awsdns-46.net.
esic.in.	3600	IN	NS	ns-1978.awsdns-55.co.uk.
esic.in.	3600	IN	NS	ns-52.awsdns-06.com.
esic.in.	3600	IN	NS	ns-1089.awsdns-08.org.
esic.in.	300	IN	A	115.113.201.36
esic.in.	300	IN	A	218.248.15.136
esic.in.	172800	IN	NS	ns-1089.awsdns-08.org.
esic.in.	172800	IN	NS	ns-1978.awsdns-55.co.uk.
esic.in.	172800	IN	NS	ns-52.awsdns-06.com.
esic.in.	172800	IN	NS	ns-882.awsdns-46.net.

And, here is the delegation trace from the root to www.esic.in,

.	518400	IN	NS	a.root-servers.net.
.	518400	IN	NS	e.root-servers.net.
.	518400	IN	NS	c.root-servers.net.
.	518400	IN	NS	b.root-servers.net.
.	518400	IN	NS	m.root-servers.net.
.	518400	IN	NS	l.root-servers.net.
.	518400	IN	NS	h.root-servers.net.
.	518400	IN	NS	j.root-servers.net.
.	518400	IN	NS	d.root-servers.net.
.	518400	IN	NS	g.root-servers.net.
.	518400	IN	NS	i.root-servers.net.
.	518400	IN	NS	k.root-servers.net.
.	518400	IN	NS	f.root-servers.net.
in.	172800	IN	NS	ns1.registry.in.
in.	172800	IN	NS	ns4.registry.in.
in.	172800	IN	NS	ns5.registry.in.
in.	172800	IN	NS	ns6.registry.in.
in.	172800	IN	NS	ns3.registry.in.
in.	172800	IN	NS	ns2.registry.in.
esic.in.	3600	IN	NS	ns-882.awsdns-46.net.
esic.in.	3600	IN	NS	ns-1089.awsdns-08.org.
esic.in.	3600	IN	NS	ns-1978.awsdns-55.co.uk.
esic.in.	3600	IN	NS	ns-52.awsdns-06.com.
www.esic.in.	3600	IN	NS	lbr1.esic.in.
www.esic.in.	3600	IN	NS	lbr2.esic.in.
www.esic.in.	0	IN	A	218.248.15.136

If you compare the two outputs and look closely, the authoritative nameservers have delegated www.esic.in to the name servers lbr1.esic.in and lbr2.esic.in

And at the time of the issue, the nameservers lbr1.esic.in and lbr2.esic.in did not respond to Do53(UDP) resulting in an NXDOMAIN!

DNSViz also reported the non-responsive nameservers as well as OpenDNS cachecheck,

At the time of writing this blog post, the name servers lbr1.esic.in. and lbr2.esic.in. were responding and www.esic.in was resolving correctly. But for more than 24+ hours, they were unresponsive resulting in some random people on the Internet in India being unable to access the website.

If you liked this blog post, you might also enjoy reading RBI Cyber Security policy .bank.in and .fin.in

APNIC 52 – Threat Hunting using DNS

I presented on how we at my $dayjob do Threat Hunting using DNS at APNIC 52.

This is the same presentation I gave at SANOG 37, but luckily, I had the full quota of 20 minutes to complete the presentation without rushing into it.

Here is the video of the presentation,

Happy hunting!

sdns://2021 – Hyperlocal root and LocalRoot

Image Source: sdns2021.dnscrypt.info

I had the opportunity to present on Hyperlocal root and the LocalRoot project at sdns://2021 last week

I’ve written and presented about Hyperlocal root aka RFC 8806 in the past. In the context of privacy, Hyperlocal root does provide a possible solution to the problem,

Prevent snooping by third parties of requests sent to DNS root servers

RFC8806

Aside from that, faster negative responses to non-existent domains eliminates junk to the root

Speaking of junk to the root, I did mention in my presentation that Chromium 87 has stopped sending junk queries to the root based on the Chromium bug report and Verisign’s blog post Chromium’s reduction of root DNS traffic

I did a quick check with Google Chrome 92.0.4515.131 and oddly enough I am still seeing this behaviour,

Aug 16 09:03:24 unbound[1:0] info: 192.168.100.4 ckgydztukkdsta. A IN
Aug 16 09:03:24 unbound[1:0] info: 192.168.100.4 lubdcupibujjne. A IN
Aug 16 09:03:24 unbound[1:0] info: 192.168.100.4 ltvlataieb. A IN

This will need further researching and debugging which I will save for another post.

A big thank you to Frank for organising sdns://2021 and also to folks from Quad9 for their help.

For some reason as can be seen in the video, presentation is stuck at a specific slide, the PDF can be found here

All the presentations are available on Youtube.