DNS.Zone (DNS v0.4.1)
View SourceDNS Zone management and operations.
This module provides the core DNS zone functionality including zone creation, management, validation, zone file parsing, and zone transfers.
Zone Types
The following zone types are supported:
:authoritative
- Primary authoritative zone with full record management:stub
- Stub zone containing only NS records for delegation:forward
- Forward zone redirecting queries to specified servers:cache
- Cache zone for temporary DNS response caching
Creating Zones
Basic Zone Creation
# Create a basic authoritative zone
zone = DNS.Zone.new("example.com")
# Create a zone with specific type
zone = DNS.Zone.new("example.com", :authoritative)
# Create a zone with options
zone = DNS.Zone.new("example.com", :authoritative, soa_records: [soa_record])
Interactive Zone Creation
# Create zone with interactive prompts
{:ok, zone} = DNS.Zone.Editor.create_zone_interactive("example.com")
# Create zone with initial records
{:ok, zone} = DNS.Zone.Editor.create_zone_interactive("example.com",
type: :authoritative,
soa: [
mname: "ns1.example.com",
rname: "admin.example.com",
serial: 2024010101,
refresh: 3600,
retry: 1800,
expire: 604800,
minimum: 300
],
ns: ["ns1.example.com", "ns2.example.com"],
a: ["192.168.1.1"]
)
Managing Zone Records
Adding Records
# Add an A record
{:ok, zone} = DNS.Zone.Editor.add_record("example.com", :a,
name: "www.example.com",
ip: {192, 168, 1, 100},
ttl: 300
)
# Add an MX record
{:ok, zone} = DNS.Zone.Editor.add_record("example.com", :mx,
name: "example.com",
preference: 10,
exchange: "mail.example.com"
)
# Add a CNAME record
{:ok, zone} = DNS.Zone.Editor.add_record("example.com", :cname,
name: "ftp.example.com",
target: "www.example.com"
)
Listing and Searching Records
# List all records in a zone
{:ok, records} = DNS.Zone.Editor.list_records("example.com")
# Search for specific records
{:ok, a_records} = DNS.Zone.Editor.search_records("example.com", type: :a)
{:ok, www_records} = DNS.Zone.Editor.search_records("example.com", name: "www.example.com")
Updating and Removing Records
# Update a record
{:ok, zone} = DNS.Zone.Editor.update_record(
"example.com", :a,
[name: "www.example.com"],
[ttl: 600]
)
# Remove records
{:ok, zone} = DNS.Zone.Editor.remove_record("example.com", :a, name: "old.example.com")
Zone Validation
Basic Validation
# Validate a zone
case DNS.Zone.Validator.validate_zone(zone) do
{:ok, result} ->
IO.puts("Zone is valid: #{result.zone_name}")
{:error, result} ->
IO.puts("Zone has errors: #{inspect(result.errors)}")
end
Comprehensive Diagnostics
# Generate zone diagnostics
diagnostics = DNS.Zone.Validator.generate_diagnostics(zone)
IO.inspect(diagnostics.statistics)
IO.inspect(diagnostics.security_assessment)
IO.inspect(diagnostics.recommendations)
Zone File Operations
Parsing Zone Files
# Load zone from BIND format file
{:ok, zone} = DNS.Zone.Loader.load_zone_from_file("example.com", "example.com.zone")
# Load zone from string
zone_content = """
$TTL 3600
$ORIGIN example.com.
@ IN SOA ns1.example.com. admin.example.com. (
2024010101 ; serial
3600 ; refresh
1800 ; retry
604800 ; expire
300 ; minimum
)
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
www IN A 192.168.1.100
mail IN A 192.168.1.200
"""
{:ok, zone} = DNS.Zone.Loader.load_zone_from_string(zone_content)
Exporting Zone Files
# Export to BIND format
{:ok, bind_content} = DNS.Zone.Editor.export_zone("example.com", format: :bind)
File.write!("example.com.zone", bind_content)
# Export to JSON
{:ok, json_content} = DNS.Zone.Editor.export_zone("example.com", format: :json)
File.write!("example.com.json", json_content)
# Export to YAML
{:ok, yaml_content} = DNS.Zone.Editor.export_zone("example.com", format: :yaml)
File.write!("example.com.yaml", yaml_content)
Zone Transfers
Full Zone Transfer (AXFR)
# Perform AXFR transfer
case DNS.Zone.Transfer.axfr("example.com") do
{:ok, records} ->
IO.puts("Received #{length(records)} records via AXFR")
{:error, reason} ->
IO.puts("AXFR failed: #{reason}")
end
Incremental Zone Transfer (IXFR)
# Perform IXFR transfer
case DNS.Zone.Transfer.ixfr("example.com", 2024010101) do
{:ok, changes} ->
IO.puts("Received #{length(changes)} changes via IXFR")
{:error, reason} ->
IO.puts("IXFR failed: #{reason}")
end
Applying Zone Transfers
# Apply transferred zone data
records = [...] # Records from AXFR/IXFR
case DNS.Zone.Transfer.apply_transfer("example.com", records, transfer_type: :axfr) do
{:ok, zone} ->
IO.puts("Zone updated successfully")
{:error, reason} ->
IO.puts("Failed to apply transfer: #{reason}")
end
DNSSEC Management
Enabling DNSSEC
# Enable DNSSEC for a zone
case DNS.Zone.Editor.enable_dnssec("example.com") do
{:ok, signed_zone} ->
IO.puts("DNSSEC enabled successfully")
{:error, reason} ->
IO.puts("DNSSEC setup failed: #{reason}")
end
Manual DNSSEC Signing
# Sign zone with custom options
case DNS.Zone.DNSSEC.sign_zone(zone,
algorithm: :rsasha256,
key_size: 2048,
nsec3_enabled: true
) do
{:ok, signed_zone} ->
IO.puts("Zone signed successfully")
{:error, reason} ->
IO.puts("Signing failed: #{reason}")
end
Zone Cloning
Clone Zone for Testing
# Clone an existing zone
case DNS.Zone.Editor.clone_zone("production.com", "staging.com") do
{:ok, cloned_zone} ->
IO.puts("Zone cloned successfully")
{:error, reason} ->
IO.puts("Cloning failed: #{reason}")
end
Examples
Complete Zone Setup
# Create a complete zone with all essential records
{:ok, zone} = DNS.Zone.Editor.create_zone_interactive("company.com",
type: :authoritative,
soa: [
mname: "ns1.company.com",
rname: "admin.company.com",
serial: 2024010101,
refresh: 3600,
retry: 1800,
expire: 604800,
minimum: 300
],
ns: ["ns1.company.com", "ns2.company.com"],
a: [
{"@", "192.168.1.10"},
{"www", "192.168.1.10"},
{"mail", "192.168.1.20"},
{"ns1", "192.168.1.1"},
{"ns2", "192.168.1.2"}
],
mx: [{10, "mail.company.com"}],
txt: [{"@", "v=spf1 mx ~all"}]
)
# Validate the zone
{:ok, validation} = DNS.Zone.Validator.validate_zone(zone)
IO.inspect(validation.summary)
# Export to BIND format
{:ok, zone_file} = DNS.Zone.Editor.export_zone("company.com", format: :bind)
File.write!("company.com.zone", zone_file)
Summary
Types
@type t() :: %DNS.Zone{name: DNS.Zone.Name.t(), options: [term()], type: zone_type()}
@type zone_type() :: :authoritative | :stub | :forward | :cache
Functions
@spec hostname(DNS.Zone.Name.t(), DNS.Message.Domain.t()) :: DNS.Zone.Name.t() | false