Asynchronous DNS client and server
Project description
async_dns
This is the documentation for v2.x. Click here for 1.x documentation.
Features
- Built with
asyncio
in pure Python, no third party dependency is required - Support DNS over UDP / TCP
- Support DNS over HTTPS
- Support DNS over TLS
Prerequisite
- Python >=3.6
Installation
$ pip3 install async_dns
# or
$ pip3 install git+https://github.com/gera2ld/async_dns.git
CLI
Resolver
usage: python3 -m async_dns.resolver [-h] [-n NAMESERVERS [NAMESERVERS ...]] [-t TYPES [TYPES ...]]
hostnames [hostnames ...]
Async DNS resolver
positional arguments:
hostnames the hostnames to query
optional arguments:
-h, --help show this help message and exit
-n NAMESERVERS [NAMESERVERS ...], --nameservers NAMESERVERS [NAMESERVERS ...]
name servers
-t TYPES [TYPES ...], --types TYPES [TYPES ...]
query types, default as `any`
Examples:
# Resolve an IP
$ python3 -m async_dns.resolver www.google.com
$ python3 -m async_dns.resolver -t mx -- gmail.com
# Query via TCP
$ python3 -m async_dns.resolver -n tcp://127.0.0.1 -- www.google.com
# Query via TLS
$ python3 -m async_dns.resolver -n tcps://dns.alidns.com -- www.google.com
# Query from non-standard ports
$ python3 -m async_dns.resolver -n udp://127.0.0.1:1053 -- www.google.com
# Query from HTTPS
$ python3 -m async_dns.resolver -n https://dns.alidns.com/dns-query -- www.google.com
Note: --
is required before hostname
s if the previous option can have multiple arguments.
Server
usage: python3 -m async_dns.server [-h] [-b BIND] [--hosts HOSTS] [-x [PROXY [PROXY ...]]]
DNS server by Gerald.
optional arguments:
-h, --help show this help message and exit
-b BIND, --bind BIND the address for the server to bind
--hosts HOSTS the path of a hosts file, `none` to disable hosts, `local` to read from
local hosts file
-x [PROXY [PROXY ...]], --proxy [PROXY [PROXY ...]]
the proxy DNS servers, `none` to serve as a recursive server, `default` to
proxy to default nameservers
Note: TLS and HTTPS are not supported in async_dns
server. Consider async-doh for DoH server support.
Examples:
# Start a DNS proxy server on :53
$ python3 -m async_dns.server -b :53 --hosts /etc/hosts
# Start a DNS server over TCP proxy
$ python3 -m async_dns.server -x tcp://114.114.114.114
# Start a DNS recursive server
$ python3 -m async_dns.server -x none
API
import asyncio
from async_dns.core import types
from async_dns.resolver import ProxyResolver
resolver = ProxyResolver()
res, cached = asyncio.run(resolver.query('www.baidu.com', types.A))
print(res)
Client
The client sends a request to a remote server and returns the message directly. Unlike resolvers, client does not have a cache and does not modify the response.
import asyncio
from async_dns.core import types, Address
from async_dns.resolver import DNSClient
async def query():
client = DNSClient()
res = await client.query('www.google.com', types.A,
Address.parse('8.8.8.8'))
print(res)
print(res.aa)
asyncio.run(query())
Routing
ProxyResolver supports routing based on domains:
resolver = ProxyResolver(proxies=[
('*.lan', ['192.168.1.1']), # query 'udp://192.168.1.1:53' for '*.lan' domains
(lambda d: d.endswith('.local'), ['tcp://127.0.0.1']), # query tcp://127.0.0.1:53 for domains ending with '.local'
'8.8.8.8', # equivalent to (None, ['8.8.8.8']), matches all others
])
DoH support
This library contains a simple implementation of DoH (aka DNS over HTTPS) client with partial HTTP protocol implemented.
If you need a more powerful DoH client based on aiohttp, or a DoH server, consider async-doh.
DNS Spoofing
You can easily add records to the cache with a hosts file or the cache API.
-
Start a server with a custom hosts file:
$ python3 -m async_dns.server -b :53 --hosts /path/to/custom/hosts
-
Add some additional records to a resolver:
from async_dns.core import parse_hosts_file, types for name, qtype, data in parse_hosts_file(hosts): resolver.cache.add(name, qtype, data) resolver.cache.add('www.example.com', types.A, ['127.0.0.1'])
Test
$ python3 -m unittest
# Or with tox
$ tox -e py
Logging
Logging does not work out of the box in v2. It requires at least minimal logging
configuration.
logging.basicConfig(level=logging.INFO)
You can also add a formatter for the logger:
import logging
from async_dns.core import logger
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
fmt = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
handler.setFormatter(fmt)
logger.addHandler(handler)
References
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file async_dns-2.0.0.tar.gz
.
File metadata
- Download URL: async_dns-2.0.0.tar.gz
- Upload date:
- Size: 27.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.7 CPython/3.9.6 Darwin/20.5.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8536be11c3789b154472a86db9df5c2149d5466949c78071019bf5edccbb639e |
|
MD5 | 8ac690523c741d6402304d47b8c874d9 |
|
BLAKE2b-256 | 8e4be37f42f7633b3287421545c9dae85cface08d664a638e444953f2b334f6c |
File details
Details for the file async_dns-2.0.0-py3-none-any.whl
.
File metadata
- Download URL: async_dns-2.0.0-py3-none-any.whl
- Upload date:
- Size: 34.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.7 CPython/3.9.6 Darwin/20.5.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a257e47cc64022f95d570a1cd7f5fe90c2d8546b24fbe1049c3980a9a5832b96 |
|
MD5 | 8d3a404205405a79463eb0f4e4058250 |
|
BLAKE2b-256 | 1b53c105f915ed250f42b6099e5556a075324ef307ed1d3993de85335b513585 |