Comprehensive security and hardening guidance for Knot DNS authoritative deployments with DNSSEC, access controls, and monitoring for Linux DevOps. This guide covers all aspects of securing Knot DNS in production environments.
Knot DNS is designed as an authoritative-only DNS server, which inherently reduces attack surface compared to recursive resolvers. However, proper security configuration is essential for protecting your DNS infrastructure.
When securing Knot DNS, consider these threats:
Operating System Security:
Process Isolation:
knot)File System Permissions:
# Set proper ownership and permissions
sudo chown -R knot:knot /etc/knot/
sudo chmod 750 /etc/knot/
sudo chmod 640 /etc/knot/knot.conf
sudo chown -R knot:knot /var/lib/knot/
sudo chmod 750 /var/lib/knot/
# Secure key files with restricted access
sudo chmod 600 /var/lib/knot/keys/
Restrict access to DNS ports:
# Using iptables
sudo iptables -A INPUT -p udp --dport 53 -s 0.0.0.0/0 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 53 -s 0.0.0.0/0 -j ACCEPT
# Restrict control socket access (if used)
sudo iptables -A INPUT -p tcp --dport 1234 -s 127.0.0.1 -j ACCEPT
Or using ufw:
sudo ufw allow from any to any port 53 proto udp
sudo ufw allow from any to any port 53 proto tcp
Configure ACLs to restrict access to various server functions:
acl:
# Secure zone transfers
- id: secure_transfer
address: [ 192.168.1.0/24, 10.0.0.0/8 ] # Trusted networks only
key: transfer_tsig_key
action: [ transfer ]
# Restrict dynamic updates
- id: secure_update
address: [ 192.168.1.100 ] # Specific management host
key: update_tsig_key
action: [ update ]
# Restrict notifications
- id: secure_notify
address: [ 192.168.1.10, 192.168.1.11 ] # Known secondary servers
action: [ notify ]
Configure RRL to mitigate DNS amplification attacks:
server:
listen: [ 0.0.0.0@53, ::@53 ]
# RRL configuration
rrl-whitelist-ratio: 0.1
rrl-slots: 10000
rrl-ipv4-prefix-length: 24
rrl-ipv6-prefix-length: 56
rrl-max-ratelimit: 200
rrl-lease-interval: 60
Bind to specific interfaces rather than all:
server:
# Bind only to public interface
listen: [ 192.168.1.10@53, 2001:db8::10@53 ]
# Avoid binding to all interfaces unless necessary
# listen: [ 0.0.0.0@53, ::@53 ]
Generate Strong Keys:
# Generate KSK (Key Signing Key)
sudo keymgr example.com key-create ksk algorithm=ecdsap256
# Generate ZSK (Zone Signing Key)
sudo keymgr example.com key-create zsk algorithm=ecdsap256
Secure Key Storage:
# Set restrictive permissions on key directory
sudo mkdir -p /var/lib/knot/keys
sudo chown knot:knot /var/lib/knot/keys
sudo chmod 700 /var/lib/knot/keys
Key Backup and Recovery:
# Regular backup of DNSSEC keys
sudo tar -czf dnssec-keys-backup-$(date +%Y%m%d).tar.gz /var/lib/knot/keys/
sudo gpg --encrypt --recipient admin@example.com dnssec-keys-backup-*.tar.gz
policy:
- id: secure_policy
algorithm: ECDSAP256SHA256
ksk-sizes: ecdsa256
zsk-sizes: ecdsa256
# Timing settings for security
propagation-delay: 2d
rrsig-lifetime: 30d
dnskey-ttl: 1h
# Key rollover settings
ksk-scheme: 2,2,2
zsk-scheme: 2,2,2
automatic-ksk-rollover: on
# Security features
publish-cdnskey: on
cds-digest-type: [ 2 ] # SHA-256
Properly manage DS records with your registrar:
# Extract DS records for delegation
sudo keymgr example.com ds-publish
# Secure server configuration
server:
listen: [ 0.0.0.0@53, ::@53 ]
workers: 4
tcp-workers: 2
rundir: /var/run
user: knot:knot
# Disable unnecessary features
answer-cksum: off # Only enable if required for specific legacy clients
max-udp-payload: 1232
database:
storage: /var/lib/knot
journal-max-usage: 100MiB
# Apply security-focused templates
template:
- id: secure_zone
file: /var/lib/knot/zones/%s.zone
zonefile-sync: 0
dnssec-signing: on
dnssec-policy: secure_policy
semantic-checks: on
journal-content: all
zone:
- domain: example.com
template: secure_zone
# Security-focused settings
zonefile-sync: 0 # Don't sync immediately to reduce I/O
semantic-checks: on # Enable semantic validation
# Restrict access via ACLs
acl: [ secure_transfer, secure_update, secure_notify ]
Enhance the systemd service file for additional security:
# /etc/systemd/system/knot.service.d/hardening.conf
[Service]
# Drop all capabilities except those required
CapabilityBoundingSet=
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/knot /var/run
ReadOnlyPaths=/etc/knot
# Restrict system calls
SystemCallFilter=@system-service
Monitor the Knot DNS process for anomalies:
# Check process integrity
ps aux | grep knotd
# Verify file integrity
sudo aide --check # if AIDE is installed
log:
# Security-focused logging
- target: /var/log/knot/security.log
any: info
client: info
zone: warning
# Log security-relevant events
network: info
control: info
Enable system auditing for DNS-related activities:
# Add audit rules for DNS configuration files
sudo auditctl -w /etc/knot/knot.conf -p wa -k dns_config
sudo auditctl -w /var/lib/knot -p wa -k dns_zones
Set up log monitoring for security events:
# Monitor for failed zone transfers
sudo grep -i "transfer" /var/log/knot/security.log
# Monitor for unauthorized updates
sudo grep -i "update" /var/log/knot/security.log
# Monitor for RRL triggers
sudo grep -i "rrl" /var/log/knot/security.log
# Generate strong TSIG keys using keymgr (Knot DNS utility)
sudo keymgr transfer_tsig_key generate algorithm=hmac-sha256 > /etc/knot/keys/transfer.key
sudo keymgr update_tsig_key generate algorithm=hmac-sha256 > /etc/knot/keys/update.key
# Alternative: Generate and extract the secret directly
sudo keymgr transfer_tsig_key generate algorithm=hmac-sha256
# Output will include the secret - copy it to your configuration
# Secure key files
sudo chmod 600 /etc/knot/keys/*.key
sudo chown knot:knot /etc/knot/keys/*.key
Note: Use keymgr (Knot DNS’s key management utility) instead of tsig-keygen (which is a BIND tool). The keymgr command generates keys and stores them in Knot’s database, and can output them for configuration use.
# Define TSIG keys in configuration
key:
- id: transfer_tsig_key
algorithm: hmac-sha256
secret: "your-generated-secret-here"
- id: update_tsig_key
algorithm: hmac-sha256
secret: "another-generated-secret-here"
If running in containers, implement additional security measures:
# docker-compose.yml with security enhancements
version: '3.8'
services:
knotdns:
image: cznic/knot:3.5 # Official Docker image with minor version tag
container_name: knotdns
restart: unless-stopped
network_mode: "host" # Required for port 53
command: knotd -c /config/knot.conf # Explicit command required
read_only: true
security_opt:
- no-new-privileges:true
- apparmor:docker-default
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
tmpfs:
- /tmp
- /run
- /var/run
volumes:
- ./config:/etc/knot:ro
- ./zones:/var/lib/knot:rw
- ./logs:/var/log/knot:rw
environment:
- TZ=Etc/UTC
user: "65534:65534" # nobody user
Regularly scan for vulnerabilities:
# Check for known vulnerabilities
sudo apt update && sudo apt install --only-upgrade knot knot-dnsutils
# Use vulnerability scanners
sudo openvas-start # if Greenbone is installed
Test security configurations:
# Test zone transfers
dig @your-dns-server example.com AXFR
# Test for recursion (should not work on authoritative servers)
dig @your-dns-server google.com
Unauthorized Access Detection:
Compromise Response:
Maintain secure backups of:
# Automated backup script
#!/bin/bash
BACKUP_DIR="/backup/dns/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
# Backup configuration
sudo cp -r /etc/knot "$BACKUP_DIR/config"
# Backup zones
sudo cp -r /var/lib/knot/zones "$BACKUP_DIR/zones"
# Backup keys (encrypted)
sudo tar -czf "$BACKUP_DIR/keys.tar.gz" -C /var/lib/knot keys/
sudo gpg --encrypt --recipient admin@example.com "$BACKUP_DIR/keys.tar.gz"
# Verify backup integrity
sudo tar -tzf "$BACKUP_DIR/keys.tar.gz.gpg" > /dev/null && echo "Backup OK"
Ensure compliance with relevant standards:
Regular security audits should include:
Integrate security into deployment pipelines:
# Example security checks in CI/CD
- name: Validate DNS configuration
run: |
knotc conf-check
for zone in zones/*.zone; do
kzonecheck "$zone"
done
- name: Security scanning
run: |
# Run security scanner on configuration
shellcheck dns-security-check.sh
Secure your IaC templates:
# Example Terraform security for DNS infrastructure
resource "aws_security_group" "dns_sg" {
name_prefix = "dns-secure-"
ingress {
from_port = 53
to_port = 53
protocol = "udp"
cidr_blocks = ["203.0.113.0/24"] # Your trusted networks
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
# Additional security settings
revoke_rules_on_delete = true
}