async-dns


Nameasync-dns JSON
Version 2.0.0 PyPI version JSON
download
home_pagehttps://github.com/gera2ld/async_dns
SummaryAsynchronous DNS client and server
upload_time2021-07-22 12:15:22
maintainer
docs_urlNone
authorGerald
requires_python>=3.6,<4.0
licenseMIT
keywords async dns asyncio
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # async_dns

[![PyPI](https://img.shields.io/pypi/v/async_dns.svg)]()

This is the documentation for v2.x. Click [here](https://github.com/gera2ld/async_dns/tree/v1.1.10) for 1.x documentation.

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Features](#features)
- [Prerequisite](#prerequisite)
- [Installation](#installation)
- [CLI](#cli)
  - [Resolver](#resolver)
  - [Server](#server)
- [API](#api)
  - [Client](#client)
  - [Routing](#routing)
- [DoH support](#doh-support)
- [DNS Spoofing](#dns-spoofing)
- [Test](#test)
- [Logging](#logging)
- [References](#references)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## 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

``` sh
$ 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:

``` sh
# 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](https://github.com/gera2ld/async-doh) for DoH server support.

Examples:

``` sh
# 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

``` python
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.

```python
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:

```python
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](https://docs.aiohttp.org/en/stable/), or a DoH server, consider [async-doh](https://github.com/gera2ld/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:

  ```bash
  $ python3 -m async_dns.server -b :53 --hosts /path/to/custom/hosts
  ```

- Add some additional records to a resolver:

  ```python
  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

```bash
$ 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.

```py
logging.basicConfig(level=logging.INFO)
```

You can also add a formatter for the logger:

```py
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

- <https://tools.ietf.org/html/rfc1034>
- <https://tools.ietf.org/html/rfc1035>
- <https://tools.ietf.org/html/rfc1464> TXT
- <https://tools.ietf.org/html/rfc2915> NAPTR

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/gera2ld/async_dns",
    "name": "async-dns",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6,<4.0",
    "maintainer_email": "",
    "keywords": "async,dns,asyncio",
    "author": "Gerald",
    "author_email": "gera2ld@live.com",
    "download_url": "https://files.pythonhosted.org/packages/8e/4b/e37f42f7633b3287421545c9dae85cface08d664a638e444953f2b334f6c/async_dns-2.0.0.tar.gz",
    "platform": "",
    "description": "# async_dns\n\n[![PyPI](https://img.shields.io/pypi/v/async_dns.svg)]()\n\nThis is the documentation for v2.x. Click [here](https://github.com/gera2ld/async_dns/tree/v1.1.10) for 1.x documentation.\n\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n\n- [Features](#features)\n- [Prerequisite](#prerequisite)\n- [Installation](#installation)\n- [CLI](#cli)\n  - [Resolver](#resolver)\n  - [Server](#server)\n- [API](#api)\n  - [Client](#client)\n  - [Routing](#routing)\n- [DoH support](#doh-support)\n- [DNS Spoofing](#dns-spoofing)\n- [Test](#test)\n- [Logging](#logging)\n- [References](#references)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n## Features\n\n- Built with `asyncio` in pure Python, no third party dependency is required\n- Support DNS over UDP / TCP\n- Support DNS over HTTPS\n- Support DNS over TLS\n\n## Prerequisite\n\n- Python >=3.6\n\n## Installation\n\n``` sh\n$ pip3 install async_dns\n# or\n$ pip3 install git+https://github.com/gera2ld/async_dns.git\n```\n\n## CLI\n\n### Resolver\n\n```\nusage: python3 -m async_dns.resolver [-h] [-n NAMESERVERS [NAMESERVERS ...]] [-t TYPES [TYPES ...]]\n                                     hostnames [hostnames ...]\n\nAsync DNS resolver\n\npositional arguments:\n  hostnames             the hostnames to query\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -n NAMESERVERS [NAMESERVERS ...], --nameservers NAMESERVERS [NAMESERVERS ...]\n                        name servers\n  -t TYPES [TYPES ...], --types TYPES [TYPES ...]\n                        query types, default as `any`\n```\n\nExamples:\n\n``` sh\n# Resolve an IP\n$ python3 -m async_dns.resolver www.google.com\n$ python3 -m async_dns.resolver -t mx -- gmail.com\n\n# Query via TCP\n$ python3 -m async_dns.resolver -n tcp://127.0.0.1 -- www.google.com\n\n# Query via TLS\n$ python3 -m async_dns.resolver -n tcps://dns.alidns.com -- www.google.com\n\n# Query from non-standard ports\n$ python3 -m async_dns.resolver -n udp://127.0.0.1:1053 -- www.google.com\n\n# Query from HTTPS\n$ python3 -m async_dns.resolver -n https://dns.alidns.com/dns-query -- www.google.com\n```\n\n**Note:** `--` is required before `hostname`s if the previous option can have multiple arguments.\n\n### Server\n\n```\nusage: python3 -m async_dns.server [-h] [-b BIND] [--hosts HOSTS] [-x [PROXY [PROXY ...]]]\n\nDNS server by Gerald.\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -b BIND, --bind BIND  the address for the server to bind\n  --hosts HOSTS         the path of a hosts file, `none` to disable hosts, `local` to read from\n                        local hosts file\n  -x [PROXY [PROXY ...]], --proxy [PROXY [PROXY ...]]\n                        the proxy DNS servers, `none` to serve as a recursive server, `default` to\n                        proxy to default nameservers\n```\n\n**Note:** TLS and HTTPS are not supported in `async_dns` server. Consider [async-doh](https://github.com/gera2ld/async-doh) for DoH server support.\n\nExamples:\n\n``` sh\n# Start a DNS proxy server on :53\n$ python3 -m async_dns.server -b :53 --hosts /etc/hosts\n\n# Start a DNS server over TCP proxy\n$ python3 -m async_dns.server -x tcp://114.114.114.114\n\n# Start a DNS recursive server\n$ python3 -m async_dns.server -x none\n```\n\n## API\n\n``` python\nimport asyncio\nfrom async_dns.core import types\nfrom async_dns.resolver import ProxyResolver\n\nresolver = ProxyResolver()\nres, cached = asyncio.run(resolver.query('www.baidu.com', types.A))\nprint(res)\n```\n\n### Client\n\nThe 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.\n\n```python\nimport asyncio\nfrom async_dns.core import types, Address\nfrom async_dns.resolver import DNSClient\n\nasync def query():\n    client = DNSClient()\n    res = await client.query('www.google.com', types.A,\n                             Address.parse('8.8.8.8'))\n    print(res)\n    print(res.aa)\n\nasyncio.run(query())\n```\n\n### Routing\n\nProxyResolver supports routing based on domains:\n\n```python\nresolver = ProxyResolver(proxies=[\n    ('*.lan', ['192.168.1.1']),                             # query 'udp://192.168.1.1:53' for '*.lan' domains\n    (lambda d: d.endswith('.local'), ['tcp://127.0.0.1']),  # query tcp://127.0.0.1:53 for domains ending with '.local'\n    '8.8.8.8',                                              # equivalent to (None, ['8.8.8.8']), matches all others\n])\n```\n\n## DoH support\n\nThis library contains a simple implementation of DoH (aka DNS over HTTPS) client with partial HTTP protocol implemented.\n\nIf you need a more powerful DoH client based on [aiohttp](https://docs.aiohttp.org/en/stable/), or a DoH server, consider [async-doh](https://github.com/gera2ld/async-doh).\n\n## DNS Spoofing\n\nYou can easily add records to the cache with a hosts file or the cache API.\n\n- Start a server with a custom hosts file:\n\n  ```bash\n  $ python3 -m async_dns.server -b :53 --hosts /path/to/custom/hosts\n  ```\n\n- Add some additional records to a resolver:\n\n  ```python\n  from async_dns.core import parse_hosts_file, types\n\n  for name, qtype, data in parse_hosts_file(hosts):\n      resolver.cache.add(name, qtype, data)\n\n  resolver.cache.add('www.example.com', types.A, ['127.0.0.1'])\n  ```\n\n## Test\n\n```bash\n$ python3 -m unittest\n\n# Or with tox\n$ tox -e py\n```\n\n## Logging\n\nLogging does not work out of the box in v2. It requires at least minimal `logging` configuration.\n\n```py\nlogging.basicConfig(level=logging.INFO)\n```\n\nYou can also add a formatter for the logger:\n\n```py\nimport logging\nfrom async_dns.core import logger\n\nlogger.setLevel(logging.INFO)\nhandler = logging.StreamHandler()\nfmt = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')\nhandler.setFormatter(fmt)\nlogger.addHandler(handler)\n```\n\n## References\n\n- <https://tools.ietf.org/html/rfc1034>\n- <https://tools.ietf.org/html/rfc1035>\n- <https://tools.ietf.org/html/rfc1464> TXT\n- <https://tools.ietf.org/html/rfc2915> NAPTR\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Asynchronous DNS client and server",
    "version": "2.0.0",
    "project_urls": {
        "Homepage": "https://github.com/gera2ld/async_dns",
        "Repository": "https://github.com/gera2ld/async_dns"
    },
    "split_keywords": [
        "async",
        "dns",
        "asyncio"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1b53c105f915ed250f42b6099e5556a075324ef307ed1d3993de85335b513585",
                "md5": "8d3a404205405a79463eb0f4e4058250",
                "sha256": "a257e47cc64022f95d570a1cd7f5fe90c2d8546b24fbe1049c3980a9a5832b96"
            },
            "downloads": -1,
            "filename": "async_dns-2.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8d3a404205405a79463eb0f4e4058250",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6,<4.0",
            "size": 34289,
            "upload_time": "2021-07-22T12:15:19",
            "upload_time_iso_8601": "2021-07-22T12:15:19.982207Z",
            "url": "https://files.pythonhosted.org/packages/1b/53/c105f915ed250f42b6099e5556a075324ef307ed1d3993de85335b513585/async_dns-2.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8e4be37f42f7633b3287421545c9dae85cface08d664a638e444953f2b334f6c",
                "md5": "8ac690523c741d6402304d47b8c874d9",
                "sha256": "8536be11c3789b154472a86db9df5c2149d5466949c78071019bf5edccbb639e"
            },
            "downloads": -1,
            "filename": "async_dns-2.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "8ac690523c741d6402304d47b8c874d9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6,<4.0",
            "size": 27477,
            "upload_time": "2021-07-22T12:15:22",
            "upload_time_iso_8601": "2021-07-22T12:15:22.955465Z",
            "url": "https://files.pythonhosted.org/packages/8e/4b/e37f42f7633b3287421545c9dae85cface08d664a638e444953f2b334f6c/async_dns-2.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2021-07-22 12:15:22",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "gera2ld",
    "github_project": "async_dns",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "async-dns"
}
        
Elapsed time: 0.09629s