Have you ever wanted to query DNS using SQL? No? Well now you can π€ͺ
dns.sql
is a sqlite3
extension that allows you to query DNS using SQL. Load it into your sqlite3
environment and run,
SELECT * FROM dns WHERE domain = FQDN('riyazali.net') AND nameserver = SystemResolver();
The above query yields a result similar to:
domain section class type ttl nameserver data
------------- ------- ----- ---- --- -------------------- ------------------------
riyazali.net. answer IN A 289 udp://192.168.1.1:53 {"A":"185.199.110.153"}
riyazali.net. answer IN A 289 udp://192.168.1.1:53 {"A":"185.199.111.153"}
riyazali.net. answer IN A 289 udp://192.168.1.1:53 {"A":"185.199.108.153"}
riyazali.net. answer IN A 289 udp://192.168.1.1:53 {"A":"185.199.109.153"}
You can download the extension using sqlpkg
or download pre-built binaries for Linux and MacOS from the releases page.
sqlpkg install riyaz-ali/dns.sql
Alternatively, you can use bindings for one of the following languages.
Language | Install | |
---|---|---|
Python | pip install sqlite-dns |
|
Node.js | npm install sqlite-dns |
To build from source, you can use the cmd/shared/shared.go
target.
> go build -o libdns.so -buildmode=c-shared cmd/shared/shared.go
Then, to load the extension into your sqlite3
shell:
sqlite> .load libdns.so
The module provides the following virtual tables and SQL functions:
-
DNS()
is a table-valued function module that provides the main lookup functionality. It contains the following columns:domain
is theFQDN
of the query / name being resolved.
It needs to be a fully-qualified name. UseFQDN()
function (defined below) to ensure the name you pass here is fully qualified.section
is the setion in the DNS response where this resource record appeared. Valid values includeanswer
,authority
andextra
class
is the class code of the DNS recordtype
is the type of the resource recordsttl
is the Time-to-live value before the record must be refetched / refreshed.nameserver
is either the authoritative or recursive nameserver that answered the query.
When querying, this is a required parameter and must be provided. Use one ofClassicResolver()
,TlsResolver()
or a formattedhttp
url (forDoH
)data
is the JSON-formatted implementations ofdns.RR
-
SearchList()
is a table-valued function module that provides search list resolution functionality. It contains the following columns:partial
is the user-provided partial input to the function. This is aHIDDEN
column.ndots
is the user-provided value for thendots
option. This is aHIDDEN
column.fqdn
is the resolved FQDN based on system's search list andndots
Assuming system's search list is
ns1.svc.cluster.local
,svc.cluster.local
,cluster.local
, andndots
is5
(example taken from http://redd.it/duj86x)SELECT * FROM search_list('app.ns2', 5)
fqdn ------------------------------ app.ns2.ns1.svc.cluster.local. app.ns2.svc.cluster.local. app.ns2.cluster.local. app.ns2.
-
FQDN(name)
is a custom scalar function that takes inname
and returns a formatted, fully-qualified domain name. -
ClassicResolver(protocol, host, port)
is a custom scalar function and builds a well-formatted resolver url for use as adns.nameserver
constraint.
Supported protocol values includeudp
andtcp
. Specify53
as default port. -
TlsResolver(remote, port, hostname)
is a custom scalar function and builds a well-formatted resolver url for use as adns.nameserver
constraint. It builds a url used byDoT
resolver.hostname
is used to verify the server's TLS certificate. -
SystemResolver()
is a custom scalar function and builds a well-formatted resolver url for use as adns.nameserver
constraint. It reads from system's DNS configuration and returns a well-formed url. It reads from/etc/resolv.conf
. This resolver is not supported on Windows.
To use DoH
, specify a valid url to a DoH
service (like https://cloudflare-dns.com/dns-query
), eg:
SELECT * FROM dns
WHERE domain = FQDN('riyazali.net') AND nameserver = 'https://cloudflare-dns.com/dns-query';
MIT License Copyright (c) 2023 Riyaz Ali. Refer to LICENSE for full text.