DNS toolkit for Python supporting almost all record types with high-level and low-level DNS operations
85
Comprehensive DNS record type support including all standard and modern record types. Provides record type constants, class constants, and complete record data parsing and formatting functionality.
Complete set of DNS record type constants including legacy, standard, and modern record types.
# Core record types
NONE = 0
A = 1 # IPv4 address
NS = 2 # Name server
MD = 3 # Mail destination (obsolete)
MF = 4 # Mail forwarder (obsolete)
CNAME = 5 # Canonical name
SOA = 6 # Start of authority
MB = 7 # Mailbox domain (experimental)
MG = 8 # Mail group member (experimental)
MR = 9 # Mail rename domain (experimental)
NULL = 10 # Null resource record (experimental)
WKS = 11 # Well known service description
PTR = 12 # Domain name pointer
HINFO = 13 # Host information
MINFO = 14 # Mailbox or mail list information
MX = 15 # Mail exchange
TXT = 16 # Text strings
# Extended record types
RP = 17 # Responsible person
AFSDB = 18 # AFS database location
X25 = 19 # X.25 PSDN address
ISDN = 20 # ISDN address
RT = 21 # Route through
NSAP = 22 # NSAP address
NSAP_PTR = 23 # Reverse NSAP lookup
SIG = 24 # Security signature
KEY = 25 # Security key
PX = 26 # X.400 mail mapping information
GPOS = 27 # Geographical position
AAAA = 28 # IPv6 address
LOC = 29 # Location information
NXT = 30 # Next domain (obsolete)
EID = 31 # Endpoint identifier
NIMLOC = 32 # Nimrod locator
SRV = 33 # Service location
ATMA = 34 # ATM address
NAPTR = 35 # Naming authority pointer
KX = 36 # Key exchanger
CERT = 37 # Certificate resource record
A6 = 38 # A6 (obsolete)
DNAME = 39 # DNAME redirection
SINK = 40 # Kitchen sink (obsolete)
OPT = 41 # EDNS option
APL = 42 # Address prefix list
DS = 43 # Delegation signer
SSHFP = 44 # SSH key fingerprint
IPSECKEY = 45 # IPSEC key
RRSIG = 46 # DNSSEC signature
NSEC = 47 # Next secure record
DNSKEY = 48 # DNS key
DHCID = 49 # DHCP identifier
NSEC3 = 50 # Next secure record version 3
NSEC3PARAM = 51 # NSEC3 parameters
TLSA = 52 # TLSA certificate association
# Modern record types
HIP = 55 # Host identity protocol
NINFO = 56 # NINFO
RKEY = 57 # RKEY
TALINK = 58 # Trust anchor link
CDS = 59 # Child delegation signer
CDNSKEY = 60 # Child DNS key
OPENPGPKEY = 61 # OpenPGP key
CSYNC = 62 # Child-to-parent synchronization
SPF = 99 # Sender policy framework
UINFO = 100 # IANA reserved
UID = 101 # IANA reserved
GID = 102 # IANA reserved
UNSPEC = 103 # IANA reserved
EUI48 = 108 # MAC address (EUI-48)
EUI64 = 109 # MAC address (EUI-64)
# Query types
TKEY = 249 # Transaction key
TSIG = 250 # Transaction signature
IXFR = 251 # Incremental zone transfer
AXFR = 252 # Authoritative zone transfer
MAILB = 253 # Mailbox-related RRs
MAILA = 254 # Mail agent RRs
ANY = 255 # Any record type
# Extended types
URI = 256 # Uniform resource identifier
CAA = 257 # Certification authority authorization
AVC = 258 # Application visibility and control
DLV = 32769 # DNSSEC lookaside validationDNS record class constants for different protocol classes.
# Standard classes
RESERVED0 = 0 # Reserved
IN = 1 # Internet
CH = 3 # Chaos
HS = 4 # Hesiod
NONE = 254 # None
ANY = 255 # Any classUtility functions for working with record types and classes.
def from_text(text):
"""
Convert text to record type value.
Args:
text (str): Record type name (e.g., 'A', 'AAAA', 'MX')
Returns:
int: Record type constant
Raises:
dns.rdatatype.UnknownRdatatype: If type is unknown
"""
def to_text(value):
"""
Convert record type value to text.
Args:
value (int): Record type constant
Returns:
str: Record type name
"""
def is_metatype(rdtype):
"""
Check if record type is a metatype.
Metatypes are types used in queries but not in zone data
(AXFR, IXFR, ANY, etc.)
Args:
rdtype (int): Record type
Returns:
bool: True if metatype
"""
def is_singleton(rdtype):
"""
Check if record type is a singleton.
Singleton types can have only one record per name
(SOA, CNAME, etc.)
Args:
rdtype (int): Record type
Returns:
bool: True if singleton type
"""Base classes and specific record data implementations for all supported record types.
class Rdata:
"""
Base class for DNS record data.
All specific record types inherit from this class and implement
their own parsing, formatting, and wire format methods.
"""
def __init__(self, rdclass, rdtype):
"""Initialize record data."""
def to_text(self, origin=None, relativize=True):
"""Convert to text format."""
def to_wire(self, file, compress=None, origin=None):
"""Convert to wire format."""
def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
"""Parse from text format."""
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
"""Parse from wire format."""
# Common record data classes
class A(Rdata):
"""IPv4 address record."""
address: str # IPv4 address
class AAAA(Rdata):
"""IPv6 address record."""
address: str # IPv6 address
class CNAME(Rdata):
"""Canonical name record."""
target: dns.name.Name # Target name
class MX(Rdata):
"""Mail exchange record."""
preference: int # Preference value
exchange: dns.name.Name # Mail server name
class NS(Rdata):
"""Name server record."""
target: dns.name.Name # Name server name
class PTR(Rdata):
"""Pointer record."""
target: dns.name.Name # Target name
class SOA(Rdata):
"""Start of authority record."""
mname: dns.name.Name # Primary name server
rname: dns.name.Name # Responsible person email
serial: int # Serial number
refresh: int # Refresh interval
retry: int # Retry interval
expire: int # Expire time
minimum: int # Minimum TTL
class SRV(Rdata):
"""Service record."""
priority: int # Priority
weight: int # Weight
port: int # Port number
target: dns.name.Name # Target host
class TXT(Rdata):
"""Text record."""
strings: list # List of text strings
class NAPTR(Rdata):
"""Naming authority pointer record."""
order: int # Order
preference: int # Preference
flags: bytes # Flags
service: bytes # Service
regexp: bytes # Regular expression
replacement: dns.name.Name # Replacement
class TLSA(Rdata):
"""TLSA certificate association record."""
usage: int # Certificate usage
selector: int # Selector
mtype: int # Matching type
cert: bytes # Certificate data
class CAA(Rdata):
"""Certification authority authorization record."""
flags: int # Flags
tag: bytes # Property tag
value: bytes # Property value
class DS(Rdata):
"""Delegation signer record."""
key_tag: int # Key tag
algorithm: int # Algorithm
digest_type: int # Digest type
digest: bytes # Digest
class DNSKEY(Rdata):
"""DNS key record."""
flags: int # Flags
protocol: int # Protocol
algorithm: int # Algorithm
key: bytes # Public key
class RRSIG(Rdata):
"""Resource record signature."""
type_covered: int # Type covered
algorithm: int # Algorithm
labels: int # Original TTL
original_ttl: int # Original TTL
expiration: int # Signature expiration
inception: int # Signature inception
key_tag: int # Key tag
signer: dns.name.Name # Signer name
signature: bytes # Signature
class NSEC(Rdata):
"""Next secure record."""
next: dns.name.Name # Next domain name
windows: list # Type bit maps
class NSEC3(Rdata):
"""Next secure record version 3."""
algorithm: int # Hash algorithm
flags: int # Flags
iterations: int # Iterations
salt: bytes # Salt
next: bytes # Next hashed owner name
windows: list # Type bit mapsClasses for managing collections of resource records.
class RRset:
"""
A resource record set (RRset).
An RRset contains all resource records at a particular name
with the same type and class.
Attributes:
name (dns.name.Name): Record name
rdclass (int): Record class
rdtype (int): Record type
ttl (int): Time to live
items (list): List of record data
"""
def __init__(self, name, rdclass, rdtype, covers='NONE'):
"""Initialize RRset."""
def __len__(self):
"""Return number of records."""
def __iter__(self):
"""Iterate over record data."""
def __getitem__(self, index):
"""Get record data by index."""
def add(self, rd, ttl=None):
"""Add record data to RRset."""
def union_update(self, other):
"""Update RRset with records from another RRset."""
def intersection_update(self, other):
"""Keep only records present in both RRsets."""
def update(self, other):
"""Replace RRset contents with another RRset."""
class Rdataset:
"""
A DNS rdataset (resource record data set).
An rdataset contains the resource record data for all records
at a name with the same type and class, but without the name itself.
Attributes:
rdclass (int): Record class
rdtype (int): Record type
covers (int): Covered type for RRSIG records
ttl (int): Time to live
items (list): List of record data
"""
def __init__(self, rdclass, rdtype, covers='NONE'):
"""Initialize rdataset."""
def __len__(self):
"""Return number of records."""
def __iter__(self):
"""Iterate over record data."""
def add(self, rd, ttl=None):
"""Add record data to rdataset."""
def union_update(self, other):
"""Update rdataset with records from another rdataset."""
def to_text(self, name=None, origin=None, relativize=True):
"""Convert rdataset to text format."""
def to_wire(self, name, file, compress=None, origin=None):
"""Convert rdataset to wire format."""import dns.rdatatype
import dns.rdataclass
# Convert between text and numeric values
a_type = dns.rdatatype.from_text('A')
print(f"A record type: {a_type}") # 1
aaaa_text = dns.rdatatype.to_text(28)
print(f"Type 28: {aaaa_text}") # AAAA
# Check record type properties
print(f"SOA is singleton: {dns.rdatatype.is_singleton(dns.rdatatype.SOA)}")
print(f"AXFR is metatype: {dns.rdatatype.is_metatype(dns.rdatatype.AXFR)}")
# Work with classes
in_class = dns.rdataclass.from_text('IN')
print(f"IN class: {in_class}") # 1import dns.rdata
import dns.rdatatype
import dns.rdataclass
# Create A record
a_rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '192.0.2.1')
print(f"A record: {a_rdata.address}")
# Create MX record
mx_rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '10 mail.example.com.')
print(f"MX preference: {mx_rdata.preference}")
print(f"MX exchange: {mx_rdata.exchange}")
# Create SRV record
srv_rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SRV,
'10 20 80 www.example.com.')
print(f"SRV priority: {srv_rdata.priority}")
print(f"SRV weight: {srv_rdata.weight}")
print(f"SRV port: {srv_rdata.port}")
print(f"SRV target: {srv_rdata.target}")
# Create TXT record with multiple strings
txt_rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.TXT,
'"v=spf1" "include:_spf.example.com" "~all"')
print(f"TXT strings: {txt_rdata.strings}")import dns.rrset
import dns.name
import dns.rdata
import dns.rdatatype
import dns.rdataclass
# Create RRset
name = dns.name.from_text('example.com.')
rrset = dns.rrset.RRset(name, dns.rdataclass.IN, dns.rdatatype.A)
# Add records to RRset
a1 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '192.0.2.1')
a2 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '192.0.2.2')
rrset.add(a1, ttl=300)
rrset.add(a2, ttl=300)
print(f"RRset name: {rrset.name}")
print(f"RRset type: {rrset.rdtype}")
print(f"RRset TTL: {rrset.ttl}")
print(f"Record count: {len(rrset)}")
# Iterate over records
for rdata in rrset:
print(f" Address: {rdata.address}")
# Create from text
text_rrset = dns.rrset.from_text('example.com.', 300, 'IN', 'MX',
'10 mail1.example.com.', '20 mail2.example.com.')import dns.rdata
import dns.rdatatype
import dns.rdataclass
# TLSA record for certificate association
tlsa_rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.TLSA,
'3 1 1 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef')
print(f"TLSA usage: {tlsa_rdata.usage}")
print(f"TLSA selector: {tlsa_rdata.selector}")
print(f"TLSA matching type: {tlsa_rdata.mtype}")
print(f"TLSA cert data: {tlsa_rdata.cert.hex()}")
# CAA record for certificate authority authorization
caa_rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CAA,
'0 issue "letsencrypt.org"')
print(f"CAA flags: {caa_rdata.flags}")
print(f"CAA tag: {caa_rdata.tag}")
print(f"CAA value: {caa_rdata.value}")
# NAPTR record for naming authority pointer
naptr_rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NAPTR,
'100 10 "u" "E2U+sip" "!^.*$!sip:info@example.com!" .')
print(f"NAPTR order: {naptr_rdata.order}")
print(f"NAPTR preference: {naptr_rdata.preference}")
print(f"NAPTR flags: {naptr_rdata.flags}")
print(f"NAPTR service: {naptr_rdata.service}")
print(f"NAPTR regexp: {naptr_rdata.regexp}")import dns.rdata
import dns.rdatatype
import dns.rdataclass
import io
# Create record data
mx_rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
'10 mail.example.com.')
# Convert to wire format
wire_buffer = io.BytesIO()
mx_rdata.to_wire(wire_buffer)
wire_data = wire_buffer.getvalue()
print(f"Wire format length: {len(wire_data)} bytes")
# Parse from wire format
parsed_rdata = dns.rdata.from_wire(dns.rdataclass.IN, dns.rdatatype.MX,
wire_data, 0, len(wire_data))
print(f"Parsed MX preference: {parsed_rdata.preference}")
print(f"Parsed MX exchange: {parsed_rdata.exchange}")A (1): IPv4 addressAAAA (28): IPv6 addressNS (2): Name serverCNAME (5): Canonical namePTR (12): PointerDNAME (39): Delegation nameMX (15): Mail exchangeTXT (16): Text (often used for SPF)SRV (33): Service locationNAPTR (35): Naming authority pointerURI (256): Uniform resource identifierDS (43): Delegation signerDNSKEY (48): DNS keyRRSIG (46): Resource record signatureNSEC (47): Next secureNSEC3 (50): Next secure version 3TLSA (52): TLS associationCAA (257): Certificate authority authorizationSOA (6): Start of authorityOPT (41): EDNS optionsHINFO (13): Host informationLOC (29): LocationSSHFP (44): SSH fingerprintSPF (99): Sender policy frameworkclass UnknownRdatatype(DNSException):
"""An unknown DNS record type was encountered."""
class UnknownRdataclass(DNSException):
"""An unknown DNS record class was encountered."""Install with Tessl CLI
npx tessl i tessl/pypi-dnspythondocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10