# compactdenial
Small library to work with Compact Denial of Existence in DNSSEC.
The Compact Denial of Existence method is defined in the following
Internet draft, which will be published as an RFC in the near
future: https://datatracker.ietf.org/doc/draft-ietf-dnsop-compact-denial-of-existence/
At the current time, Cloudflare and NS1 are known to implement the NXNAME
distinguisher described in the draft that allows precise identification of
non-existent domains.
A small testing script, called "compactrcode" is also included that uses the library:
```
$ compactrcode.py -h
usage: compactrcode.py [-h] [--response] [--resolver RESOLVER]
[--server SERVER] [--nsecdebug] [--coflag]
qname qtype
positional arguments:
qname DNS query name
qtype DNS query type
optional arguments:
-h, --help show this help message and exit
--response Print full response
--resolver RESOLVER Resolver IP address to send query to
--server SERVER Server IP address to send query to
--nsecdebug Decode NSEC records in response
--coflag Send Compact Answers OK EDNS flag
```
### Example program usage:
Print effective response code for a given DNS query. In this example,
the response is a Compact Denial style NXDOMAIN disguised as a NOERROR.
The program examines the NXNAME sentinel type in the response's NSEC
record, deduces that the name doesn't actually exist, and returns
NXDOMAIN.
```
$ compactrcode.py nxdomain.cloudflare.net. A
NXDOMAIN
```
Print full response for a given DNS query. The exit code will reflect the effective response code (3, NXDOMAIN in this case).
```
$ compactrcode.py --response nxdomain.cloudflare.net. A
id 21074
opcode QUERY
rcode NOERROR
flags QR RD RA AD
edns 0
eflags DO
payload 512
;QUESTION
nxdomain.cloudflare.net. IN A
;ANSWER
;AUTHORITY
cloudflare.net. 1800 IN SOA ns1.cloudflare.net. dns.cloudflare.com. 2324138674 10000 2400 604800 1800
nxdomain.cloudflare.net. 1800 IN NSEC \000.nxdomain.cloudflare.net. RRSIG NSEC TYPE65283
cloudflare.net. 1800 IN RRSIG SOA 13 2 1800 20231120030733 20231118010733 34505 cloudflare.net. Y40wrXU14EsCuL5l6sDUAyh4o277iJ99 RbnUKOO6IDbHUUmYzcwt1OssstfTRkyH SVlgAco16+md7kmpXRSU7Q==
nxdomain.cloudflare.net. 1800 IN RRSIG NSEC 13 3 1800 20231120030733 20231118010733 34505 cloudflare.net. tqE4kDr2Er7Ck/tUUnZszYTiOzROvp7R Lel0iOyRz+0b1m3/VAJKzXBCBNCLl+co QeQdygRBlFdire8PxzKxxA==
;ADDITIONAL
$ echo $?
3
```
### Library Functions in compactdenial.py
```
get_resolver(addresses=None, lifetime=5, payload=1420, coflag=False)
Return resolver object configured to use given list of addresses, and
that sets DO=1, RD=1, AD=1, and EDNS payload for queries to the resolver.
is_authenticated(msg)
Does DNS message have Authenticated Data (AD) flag set?
nsec_type_set(type_bitmaps)
Return set of RR types present in given NSEC record's type bitmaps.
nsec_windows(type_bitmaps)
Iterator that returns info about the next NSEC windowed bitmap.
Mainly used for debugging or diagnostics.
query_resolver(qname, qtype, resolver=None)
Queries a DNS resolver for a given DNS qname and qtype and returns
the response message.
query_server(qname, qtype, server, coflag=False)
Queries a DNS server directly for a given DNS qname and qtype and returns
the response message. Uses UDP transport with fallback to TCP upon
truncation.
rcode(msg, qname)
Return rcode for given DNS response message. If a compact denial
style NOERROR response is detected, return NXDOMAIN. Otherwise
return the actual rcode observed in the DNS reply message.
A compact denial style NOERROR response is a NXDOMAIN response
disguised as a NOERROR/NODATA. It is identified by a NOERROR
response with an empty answer section, and an authority section
containing an NSEC record matching the query name that contains
in its type bitmaps field: NSEC, RRSIG, and the NXNAME sentinel type.
It is sufficent to only check for the presence of NXNAME.
https://datatracker.ietf.org/doc/draft-ietf-dnsop-compact-denial-of-existence/
DATA
DEFAULT_QUERY_TIMEOUT = 5
DEFAULT_UDP_PAYLOAD = 1420
EDNS_FLAG_CO = 16384
NXNAME_RRTYPE = 128
RESOLVER_LIST = ['8.8.8.8', '1.1.1.1']
```
Raw data
{
"_id": null,
"home_page": "https://github.com/shuque/compactdenial",
"name": "compactdenial",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": null,
"author": "Shumon Huque",
"author_email": "Shumon Huque <shuque@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/62/36/ef0393a656e64ab40cc7f2dfdf2448981595481f73f0998ffdda62343132/compactdenial-0.0.5.tar.gz",
"platform": null,
"description": "# compactdenial\nSmall library to work with Compact Denial of Existence in DNSSEC.\n\nThe Compact Denial of Existence method is defined in the following\nInternet draft, which will be published as an RFC in the near\nfuture: https://datatracker.ietf.org/doc/draft-ietf-dnsop-compact-denial-of-existence/\n\nAt the current time, Cloudflare and NS1 are known to implement the NXNAME\ndistinguisher described in the draft that allows precise identification of\nnon-existent domains.\n\nA small testing script, called \"compactrcode\" is also included that uses the library:\n\n```\n$ compactrcode.py -h\nusage: compactrcode.py [-h] [--response] [--resolver RESOLVER]\n [--server SERVER] [--nsecdebug] [--coflag]\n qname qtype\n\npositional arguments:\n qname DNS query name\n qtype DNS query type\n\noptional arguments:\n -h, --help show this help message and exit\n --response Print full response\n --resolver RESOLVER Resolver IP address to send query to\n --server SERVER Server IP address to send query to\n --nsecdebug Decode NSEC records in response\n --coflag Send Compact Answers OK EDNS flag\n```\n\n### Example program usage:\n\nPrint effective response code for a given DNS query. In this example,\nthe response is a Compact Denial style NXDOMAIN disguised as a NOERROR.\nThe program examines the NXNAME sentinel type in the response's NSEC\nrecord, deduces that the name doesn't actually exist, and returns\nNXDOMAIN.\n\n```\n$ compactrcode.py nxdomain.cloudflare.net. A\nNXDOMAIN\n```\n\nPrint full response for a given DNS query. The exit code will reflect the effective response code (3, NXDOMAIN in this case).\n\n```\n$ compactrcode.py --response nxdomain.cloudflare.net. A\nid 21074\nopcode QUERY\nrcode NOERROR\nflags QR RD RA AD\nedns 0\neflags DO\npayload 512\n;QUESTION\nnxdomain.cloudflare.net. IN A\n;ANSWER\n;AUTHORITY\ncloudflare.net. 1800 IN SOA ns1.cloudflare.net. dns.cloudflare.com. 2324138674 10000 2400 604800 1800\nnxdomain.cloudflare.net. 1800 IN NSEC \\000.nxdomain.cloudflare.net. RRSIG NSEC TYPE65283\ncloudflare.net. 1800 IN RRSIG SOA 13 2 1800 20231120030733 20231118010733 34505 cloudflare.net. Y40wrXU14EsCuL5l6sDUAyh4o277iJ99 RbnUKOO6IDbHUUmYzcwt1OssstfTRkyH SVlgAco16+md7kmpXRSU7Q==\nnxdomain.cloudflare.net. 1800 IN RRSIG NSEC 13 3 1800 20231120030733 20231118010733 34505 cloudflare.net. tqE4kDr2Er7Ck/tUUnZszYTiOzROvp7R Lel0iOyRz+0b1m3/VAJKzXBCBNCLl+co QeQdygRBlFdire8PxzKxxA==\n;ADDITIONAL\n\n$ echo $?\n3\n```\n\n### Library Functions in compactdenial.py\n\n```\n get_resolver(addresses=None, lifetime=5, payload=1420, coflag=False)\n Return resolver object configured to use given list of addresses, and\n that sets DO=1, RD=1, AD=1, and EDNS payload for queries to the resolver.\n\n is_authenticated(msg)\n Does DNS message have Authenticated Data (AD) flag set?\n\n nsec_type_set(type_bitmaps)\n Return set of RR types present in given NSEC record's type bitmaps.\n\n nsec_windows(type_bitmaps)\n Iterator that returns info about the next NSEC windowed bitmap.\n Mainly used for debugging or diagnostics.\n\n query_resolver(qname, qtype, resolver=None)\n Queries a DNS resolver for a given DNS qname and qtype and returns\n the response message.\n\n query_server(qname, qtype, server, coflag=False)\n Queries a DNS server directly for a given DNS qname and qtype and returns\n the response message. Uses UDP transport with fallback to TCP upon\n truncation.\n\n rcode(msg, qname)\n Return rcode for given DNS response message. If a compact denial\n style NOERROR response is detected, return NXDOMAIN. Otherwise\n return the actual rcode observed in the DNS reply message.\n\n A compact denial style NOERROR response is a NXDOMAIN response\n disguised as a NOERROR/NODATA. It is identified by a NOERROR\n response with an empty answer section, and an authority section\n containing an NSEC record matching the query name that contains\n in its type bitmaps field: NSEC, RRSIG, and the NXNAME sentinel type.\n It is sufficent to only check for the presence of NXNAME.\n https://datatracker.ietf.org/doc/draft-ietf-dnsop-compact-denial-of-existence/\n\nDATA\n DEFAULT_QUERY_TIMEOUT = 5\n DEFAULT_UDP_PAYLOAD = 1420\n EDNS_FLAG_CO = 16384\n NXNAME_RRTYPE = 128\n RESOLVER_LIST = ['8.8.8.8', '1.1.1.1']\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "DNS Compact Denial of Existence Library",
"version": "0.0.5",
"project_urls": {
"Homepage": "https://github.com/shuque/compactdenial",
"Issues": "https://github.com/shuque/compactdenial/issues"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "4c2485ef8e5ea8443083ebacb2c46cd1a856801aa112ba0233d9c48ea8ac501f",
"md5": "b50f5976e3ccda0a9c2eb8ec7372ba02",
"sha256": "17179c868e8111b06641000252e7f6725f357456f2a6790e0ff85d00c16847f3"
},
"downloads": -1,
"filename": "compactdenial-0.0.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b50f5976e3ccda0a9c2eb8ec7372ba02",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 7190,
"upload_time": "2024-09-14T00:32:51",
"upload_time_iso_8601": "2024-09-14T00:32:51.832598Z",
"url": "https://files.pythonhosted.org/packages/4c/24/85ef8e5ea8443083ebacb2c46cd1a856801aa112ba0233d9c48ea8ac501f/compactdenial-0.0.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "6236ef0393a656e64ab40cc7f2dfdf2448981595481f73f0998ffdda62343132",
"md5": "df628e6c147a3ff941485ae01d008b2c",
"sha256": "23edbe4fcf62a7ea5343672ff00d368a4dd167e632bcacf9aa1b4e98ebd2d8c0"
},
"downloads": -1,
"filename": "compactdenial-0.0.5.tar.gz",
"has_sig": false,
"md5_digest": "df628e6c147a3ff941485ae01d008b2c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 5961,
"upload_time": "2024-09-14T00:32:53",
"upload_time_iso_8601": "2024-09-14T00:32:53.101873Z",
"url": "https://files.pythonhosted.org/packages/62/36/ef0393a656e64ab40cc7f2dfdf2448981595481f73f0998ffdda62343132/compactdenial-0.0.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-14 00:32:53",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "shuque",
"github_project": "compactdenial",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "compactdenial"
}