Advanced 15 min DNS 9

NOTAUTH — Unauthorized DNS Dynamic Update

Triệu chứng

- `nsupdate` returns `update failed: NOTAUTH` or `update failed: REFUSED`
- DDNS client logs show 'dynamic update failed' with rcode 9 (NOTAUTH)
- Let's Encrypt DNS-01 challenge fails because the ACME client cannot create `_acme-challenge` TXT records
- Automated certificate renewal (Certbot, acme.sh) fails with 'DNS challenge failed'
- BIND named logs show 'not authoritative for update zone' or 'signer had no key'

Nguyên nhân gốc rễ

  • nsupdate targeting a secondary or recursive nameserver instead of the primary master
  • TSIG key mismatch — the shared secret on the client does not match the key in named.conf
  • DNS server's allow-update ACL does not include the client's IP address or TSIG key name
  • Zone delegated to a DNS provider that does not support RFC 2136 dynamic updates
  • BIND named.conf missing the allow-update directive for the specific zone

Chẩn đoán

**Step 1 — Identify the primary master for the zone**

```bash
# Dynamic updates must go to the primary master (not secondary NS):
dig example.com SOA +short
# First field after the serial = primary NS (MNAME)
# e.g.: ns1.example.com. admin.example.com. 2024010101 3600 900 604800 300
# ^^^ this is the primary master

# nsupdate: specify the server explicitly:
nsupdate -v << 'EOF'
server ns1.example.com
zone example.com
update add test.example.com 60 A 203.0.113.1
send
EOF
```

**Step 2 — Test with IP-based auth (no TSIG)**

```bash
# Try update from localhost on the nameserver itself (should pass IP ACL):
ssh ns1.example.com
nsupdate << 'EOF'
server 127.0.0.1
zone example.com
update add testdel.example.com 60 A 203.0.113.1
send
EOF
# If this fails → named.conf allow-update is missing even for localhost
```

**Step 3 — Check BIND allow-update configuration**

```bash
# On the nameserver:
grep -A15 'zone.*example.com' /etc/named.conf | grep -i 'allow-update\|key'

# If missing or set to 'none':
# allow-update { none; }; ← blocks all dynamic updates
# allow-update { key ddns-key; }; ← only TSIG 'ddns-key' is allowed
```

**Step 4 — Verify TSIG key consistency**

```bash
# Generate a new TSIG key pair (if needed):
tsig-keygen -a hmac-sha256 ddns-key
# Outputs a 'key' block — copy the 'secret' value exactly to both server and client

# Test update with explicit TSIG key:
nsupdate -k /etc/named/ddns.key << 'EOF'
server ns1.example.com
zone example.com
update add testdel.example.com 60 A 203.0.113.1
send
EOF
# 'update successful' = TSIG key is correct
```

**Step 5 — Check BIND logs for the exact rejection reason**

```bash
sudo journalctl -u named -n 50 | grep -E 'update|NOTAUTH|signer|key'
# Common messages:
# 'signer had no key' = TSIG key name mismatch
# 'not authoritative for update zone' = targeting a secondary NS
# 'Update from x.x.x.x denied' = IP not in allow-update ACL
```

Giải quyết

**Fix 1 — Target the correct primary master for updates**

```bash
# Get the primary master from SOA MNAME field:
PRIMARY=$(dig example.com SOA +short | awk '{print $1}')
echo "Primary master: $PRIMARY"

# Use it in nsupdate:
nsupdate -k /etc/named/ddns.key << EOF
server $PRIMARY
zone example.com
update add _acme-challenge.example.com 60 TXT "your-acme-token"
send
EOF
```

**Fix 2 — Configure allow-update in BIND for TSIG**

```named
# /etc/named.conf — generate key and allow updates:
key ddns-key {
algorithm hmac-sha256;
secret "base64encodedsharedsecret==";
};

zone "example.com" {
type master;
file "/etc/named/zones/db.example.com";
allow-update { key ddns-key; };
};
```

```bash
sudo named-checkconf && sudo systemctl reload named
```

**Fix 3 — Fix Certbot DNS-01 with nsupdate plugin**

```bash
# Install certbot-dns-rfc2136 plugin:
pip install certbot-dns-rfc2136

# Create credentials file:
cat > /etc/letsencrypt/rfc2136.ini << 'EOF'
dns_rfc2136_server = ns1.example.com
dns_rfc2136_port = 53
dns_rfc2136_name = ddns-key
dns_rfc2136_secret = base64encodedsharedsecret==
dns_rfc2136_algorithm = HMAC-SHA256
EOF
chmod 600 /etc/letsencrypt/rfc2136.ini

certbot certonly --dns-rfc2136 \
--dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini \
-d example.com -d '*.example.com'
```

Phòng ngừa

- Always use TSIG authentication for dynamic DNS updates; never allow by IP alone in production
- Store TSIG keys in a secrets manager and rotate them annually
- Test dynamic update access from your ACME client IP before setting up automated certificate renewal
- Use a dedicated zone (e.g., acme.example.com) for DNS-01 challenges with its own allow-update policy
- Document the primary master hostname and TSIG key name in your infrastructure runbook

Mã trạng thái liên quan

Thuật ngữ liên quan