Skip to content

Instantly share code, notes, and snippets.

@tomdavidson
Last active September 28, 2023 03:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomdavidson/9cfee77b84e2ae2d94e59d57e3863db7 to your computer and use it in GitHub Desktop.
Save tomdavidson/9cfee77b84e2ae2d94e59d57e3863db7 to your computer and use it in GitHub Desktop.
A draft DNS record JSONSchema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "dns-record.schema.json",
"$title": "DNS Record Schema",
"type": "object",
"oneOf": [
{
"$ref": "#/components/records/A"
},
{
"$ref": "#/components/records/AAAA"
},
{
"$ref": "#/components/records/CNAME"
},
{
"$ref": "#/components/records/MX"
},
{
"$ref": "#/components/records/NS"
},
{
"$ref": "#/components/records/PTR"
},
{
"$ref": "#/components/records/SOA"
},
{
"$ref": "#/components/records/TXT"
}
],
"$components": {
"formats": {
"FQDN": {
"type": "string",
"description": "A a unique and unambiguous name of a computer or device on the Internet. This is important because it allows devices to communicate with each other and to access resources on the internet.",
"pattern": "^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](\\.[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9])*$"
},
"SAFETEXT": {
"type": "string",
"description": "A string that is up to 255 characters long with only _ . ! and a space for specials.",
"pattern": "^[a-zA-Z0-9_.!\\s]{1,255}$"
},
"RECORDNAME": {
"type": "string",
"description": "A string similar to a hostname but allows '@' so it can be used as a record name.",
"pattern": "^(?:[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]|(?:@[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]))(\\.[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9])*$"
}
},
"props": {
"MNAME": {
"description": "The DNS primary nameserver is the authoritative server for a DNS zone. It contains the master copy of the zone file and is responsible for distributing updates to the zone file to secondary nameservers. Secondary nameservers maintain copies of the zone file from the primary nameserver. When the primary nameserver updates the zone file, it distributes the changes to the secondary nameservers via a zone transfer.",
"$ref": "#/components/formats/FQDN"
},
"RNAME": {
"description": "Typically used to store the email address of the person responsible for administering the DNS zone. However, it is important to note that the RNAME field is not required to be a valid email address. It can be any string that is up to 255 characters long. In some cases, people may choose to use the RNAME field to store the domain name of the organization that is responsible for administering the DNS zone. For example, the RNAME field for the example.com domain might be set to example.com. This is a valid practice, but it is important to note that it can make it more difficult to contact the person responsible for administering the zone if needed.",
"$ref": "#/components/formats/SAFETEXT"
},
"SERIAL": {
"description": "A version number for the Start of Authority (SOA) record for a DNS zone. The SOA record is a special type of DNS record that contains information about the zone, such as its name, responsible person, and serial number. When the serial number in the SOA record changes, this alerts secondary nameservers that they should update their copies of the zone file via a zone transfer. A zone transfer is a process by which secondary nameservers obtain copies of the zone file from the primary nameserver.",
"type": "integer",
"minimum": 1,
"maximum": 4294967295
},
"REFRESH": {
"description": "The DNS refresh interval is a period of time, in seconds, that secondary nameservers should wait before querying the primary nameserver for the Start of Authority (SOA) record to see if it has been updated. If the serial number in the SOA record has changed, the secondary nameservers will initiate a zone transfer to update their copies of the zone file. The refresh interval is typically set to a value that is much longer than the time it takes for the primary nameserver to propagate changes to the zone file to the secondary nameservers. This is to avoid overloading the primary nameserver with queries from the secondary nameservers.",
"type": "integer",
"minimum": 1,
"maximum": 31536000,
"default": 3600
},
"RETRY": {
"description": "The DNS retry interval is a period of time, in seconds, that a secondary nameserver should wait before retrying a query to the primary nameserver for the SOA record if the primary nameserver does not respond. The retry interval is typically set to a value that is less than the refresh interval. This is to ensure that the secondary nameservers do not go too long without being able to update their copies of the zone file.",
"type": "integer",
"minimum": 1,
"maximum": 31536000,
"default": 1800
},
"EXPIRE": {
"description": "The DNS expire interval is a period of time, in seconds, that a secondary nameserver should wait before stopping to respond to queries for a zone if it does not receive a response from the primary nameserver for the SOA record. The expire interval is typically set to a value that is much longer than the refresh interval. This is to ensure that the secondary nameservers continue to respond to queries for the zone even if the primary nameserver is unavailable.",
"type": "integer",
"minimum": 0,
"maximum": 31536000,
"default": 1209600
},
"PRIORITY": {
"description": "The priority of the DNS record, if applicable.",
"type": "integer",
"minimum": 0,
"maximum": 65535,
"default": 100
},
"TTL": {
"description": "How long, in seconds, a record should be cached by DNS resolvers. Typically set to a value that is long enough for the record to be useful, but short enough to ensure that resolvers do not continue to use outdated records. When a DNS resolver receives a response from a DNS server, it caches the response for the TTL period. This means that the resolver will not query the DNS server for the same record again until the TTL period has expired. This can improve the performance of DNS queries, as the resolvers do not have to query the DNS servers as often.",
"type": "integer",
"minimum": 1,
"maximum": 2147483647,
"default": 3600
},
"IPV4ADDRESS": {
"type": "string",
"description": "An IPv4 address used to identify devices on the Internet.",
"format": "ipv4"
},
"IPV6ADDRESS": {
"type": "string",
"description": "An IPv6 address used to identify devices on the Internet.",
"format": "ipv6"
},
"HOSTNAME": {
"type": "string",
"description": "A name that can be used to identify any device on a network instead of an address but are not fully qualified domain names.",
"format": "idn-hostname"
}
},
"records": {
"A": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"A"
]
},
"name": {
"$ref": "#/components/formats/RECORDNAME"
},
"target": {
"$ref": "#/components/schemas/IPV4ADDRESS"
},
"ttl": {
"$ref": "#/components/schemas/TTL"
}
},
"required": [
"name",
"target",
"ttl"
]
},
"AAAA": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"AAAA"
]
},
"name": {
"$ref": "#/components/formats/RECORDNAME"
},
"target": {
"$ref": "#/components/schemas/IPV6ADDRESS"
},
"ttl": {
"$ref": "#/components/schemas/TTL"
}
},
"required": [
"name",
"target",
"ttl"
]
},
"CNAME": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"CNAME"
]
},
"name": {
"$ref": "#/components/formats/RECORDNAME"
},
"target": {
"$ref": "#/components/schemas/FQDN"
},
"ttl": {
"$ref": "#/components/schemas/TTL"
}
},
"required": [
"name",
"target",
"ttl"
]
},
"NS": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"NS"
]
},
"name": {
"$ref": "#/components/formats/RECORDNAME"
},
"target": {
"$ref": "#/components/formats/FQDN"
},
"ttl": {
"$ref": "#/components/props/TTL"
}
},
"required": [
"name",
"target",
"ttl"
]
},
"MX": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"MX"
]
},
"name": {
"$ref": "#/components/formats/RECORDNAME"
},
"target": {
"$ref": "#/components/formats/FQDN"
},
"priority": {
"$ref": "#/components/schemas/PRIORITY"
},
"ttl": {
"$ref": "#/components/schemas/TTL"
}
},
"required": [
"name",
"target",
"priority",
"ttl"
]
},
"SOA": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"SOA"
]
},
"mname": {
"$ref": "#/components/formats/FQDN"
},
"rname": {
"$ref": "#/components/formats/SAFETEXT"
},
"serial": {
"$ref": "#/components/schemas/SERIAL"
},
"refresh": {
"$ref": "#/components/schemas/REFRESH"
},
"retry": {
"$ref": "#/components/schemas/RETRY"
},
"expire": {
"$ref": "#/components/schemas/EXPIRE"
},
"ttl": {
"$ref": "#/components/schemas/TTL"
}
},
"required": [
"mname",
"rname",
"serial",
"refresh",
"retry",
"expire",
"ttl"
]
},
"PTR": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"PTR"
]
},
"name": {
"$ref": "#/components/formats/IPV4ADDRESS"
},
"target": {
"$ref": "#/components/formats/FQDN",
"description": "The fully qualified domain name (FQDN) of the host associated with the IP address."
},
"ttl": {
"$ref": "#/components/schemas/TTL"
}
},
"required": [
"name",
"target",
"ttl"
]
},
"TXT": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"TXT"
]
},
"name": {
"$ref": "#/components/formats/RECORDNAME"
},
"target": {
"$ref": "#/components/formats/SAFETEXT"
},
"ttl": {
"$ref": "#/components/schemas/TTL"
}
},
"required": [
"name",
"target",
"ttl"
]
}
}
}
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "dns-tool.schema.json",
"title": "Zone Config Schema",
"type": "object",
"properties": {
"records": {
"type": "array",
"items": {
{
"$ref": "dns-record.schema.json"
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment