Troubleshooting BIND DNS Permission Errors for Dynamic Zone Updates with nsupdate


11 views

The permission errors we're seeing stem from BIND's inability to create and modify journal files (.jnl) during dynamic DNS updates. The key symptoms appear in syslog:

Nov 12 08:00:53 ps133045 named[14314]: /etc/bind/zones/mydomain.com.zone.jnl: create: permission denied
Nov 12 08:00:53 ps133045 named[14314]: client 78.72.53.42#50135: updating zone 'mydomain.com/IN': error: journal open failed

Common mistakes include:

  • Incorrect directory ownership (needs bind:bind)
  • Wrong permission bits (directories need execute bit)
  • SELinux/AppArmor restrictions (often overlooked)

Here's the correct setup:

# Directory structure
sudo chown -R bind:bind /etc/bind/zones
sudo chmod -R 775 /etc/bind/zones
sudo chmod g+s /etc/bind/zones  # Set SGID bit

# For journal files
touch /etc/bind/zones/mydomain.com.zone.jnl
chown bind:bind /etc/bind/zones/mydomain.com.zone.jnl
chmod 664 /etc/bind/zones/mydomain.com.zone.jnl

Ensure your named.conf includes proper update policies:

zone "mydomain.com" {
    type master;
    file "/etc/bind/zones/mydomain.com.zone";
    allow-update { key "www.mydomain.com"; };
    journal "/etc/bind/zones/mydomain.com.zone.jnl";
};

When basic permission fixes don't work:

# Check if SELinux is blocking:
sudo ausearch -m avc -ts recent

# Or for AppArmor:
sudo aa-status
sudo journalctl -u apparmor --no-pager | grep named

# Temporary test:
sudo setenforce 0  # For SELinux
sudo systemctl stop apparmor  # For AppArmor

Here's a complete remediation script:

#!/bin/bash
# Fix BIND permissions
ZONE_DIR="/etc/bind/zones"
ZONE_FILE="mydomain.com.zone"

sudo systemctl stop named
sudo chown -R bind:bind $ZONE_DIR
sudo chmod -R 775 $ZONE_DIR
sudo chmod g+s $ZONE_DIR
sudo touch $ZONE_DIR/$ZONE_FILE.jnl
sudo chown bind:bind $ZONE_DIR/$ZONE_FILE.jnl
sudo chmod 664 $ZONE_DIR/$ZONE_FILE.jnl
sudo restorecon -Rv $ZONE_DIR  # For SELinux
sudo systemctl start named

Test with nsupdate:

nsupdate -k Kwww.mydomain.com.+157.17183.key <<EOF
server ns1.mydomain.com
zone mydomain.com
update add test.mydomain.com 300 A 192.168.1.1
send
EOF

Check logs for success messages. Properly configured systems should show:

client x.x.x.x#port: updating zone 'mydomain.com/IN': update successful

When working with BIND and nsupdate for dynamic DNS updates, the most common roadblock developers face is permission-related errors. The log entries clearly show the named daemon is failing to create/modify journal files and configuration files:

Nov 12 08:00:53 ps133045 named[14314]: /etc/bind/zones/mydomain.com.zone.jnl: create: permission denied
Nov 12 08:40:10 ps133045 named[21169]: /etc/bind/named.conf.local:9: open: /var/named/dnskeys.conf: permission denied

The key misconception in the original setup was applying 666 permissions indiscriminately. Here's the correct approach:

# Directory structure should have execute permissions
chmod 775 /etc/bind
chmod 775 /var/named

# Zone files should be readable by bind group
chown root:bind /etc/bind/zones/mydomain.com.zone
chmod 640 /etc/bind/zones/mydomain.com.zone

# Journal files need proper ownership
chown bind:bind /etc/bind/zones/mydomain.com.zone.jnl
chmod 660 /etc/bind/zones/mydomain.com.zone.jnl

Modern Linux systems often have additional security layers that might block BIND operations:

# For AppArmor (Ubuntu/Debian):
sudo aa-complain /etc/apparmor.d/usr.sbin.named

# For SELinux (RHEL/CentOS):
sudo chcon -R -t named_zone_t /etc/bind/zones/
sudo restorecon -Rv /var/named

Here's a properly configured named.conf.local snippet for dynamic updates:

zone "mydomain.com" {
    type master;
    file "/etc/bind/zones/mydomain.com.zone";
    allow-update { key "www.mydomain.com"; };
    journal "/etc/bind/zones/mydomain.com.zone.jnl";
};

include "/var/named/dnskeys.conf";

When testing updates, use this verbose nsupdate command:

nsupdate -k Kwww.mydomain.com.+157.17183.key -v
> server ns1.mydomain.com
> zone mydomain.com
> update add test.mydomain.com. 300 A 192.168.1.1
> send
> quit

Check the journal file status immediately after:

ls -la /etc/bind/zones/mydomain.com.zone.jnl
journalprint -j /etc/bind/zones/mydomain.com.zone.jnl