OPNsense Forum

English Forums => Development and Code Review => Topic started by: Th0mas on December 14, 2024, 07:39:05 AM

Title: Feature Request: DNSSEC Support for Local BIND Zones
Post by: Th0mas on December 14, 2024, 07:39:05 AM
I am currently using OPNsense 25.1.a_589-amd64 and attempted to configure BIND to enable DNSSEC for my zones. However, it seems there is no configuration option available yet, and I have been unsuccessful in introducing this functionality through a custom template.

My zones are internet-facing, and increasingly, DNS resolvers block insecure zones, requiring DNSSEC. As a result, I can no longer resolve my private zones from our company DNS.

Are there plans to officially introduce DNSSEC support into the BIND plugin? Alternatively, is there a workaround available that persists across OPNsense upgrades?
Title: Re: Feature Request: DNSSEC Support for Local BIND Zones
Post by: Th0mas on December 14, 2024, 09:09:26 AM
As a temporary workaround I've set "DNSSEC Validation" = "Auto" in Binds General tab and executed this script:

#!/bin/sh

# Configuration
NAMEDB_DIR="/usr/local/etc/namedb"
KEYS_DIR="${NAMEDB_DIR}/keys"
PRIMARY_DIR="${NAMEDB_DIR}/primary"

# Create required directories and set permissions
mkdir -p "${KEYS_DIR}"
chown bind:bind "${KEYS_DIR}"

# Process a single zone
process_zone() {
    local zonefile=$1
    local zone=$(basename "$zonefile" .db)
   
    echo "Processing zone: ${zone}"
   
    # Clean up any existing keys for this zone
    rm -f "${KEYS_DIR}"/K${zone}.+007+*.key "${KEYS_DIR}"/K${zone}.+007+*.private
   
    # Generate keys directly in the keys directory
    cd "${KEYS_DIR}"
   
    # Generate ZSK and KSK
    echo "Generating new keys for ${zone}"
    dnssec-keygen -a NSEC3RSASHA1 -b 2048 -n ZONE "${zone}"
    dnssec-keygen -f KSK -a NSEC3RSASHA1 -b 4096 -n ZONE "${zone}"
   
    # Make sure keys are owned by bind
    chown bind:bind K${zone}.*
   
    # Backup original zone file
    cp "${PRIMARY_DIR}/${zone}.db" "${PRIMARY_DIR}/${zone}.db.backup"
   
    # Remove any existing DNSKEY records
    grep -v "IN DNSKEY" "${PRIMARY_DIR}/${zone}.db.backup" > "${PRIMARY_DIR}/${zone}.db"
   
    # Add new DNSKEY records
    for keyfile in "${KEYS_DIR}"/K${zone}.+007+*.key; do
        if [ -f "$keyfile" ]; then
            cat "$keyfile" >> "${PRIMARY_DIR}/${zone}.db"
        fi
    done
   
    # Sign the zone
    cd "${PRIMARY_DIR}"
    echo "Signing zone ${zone}"
    dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1) \
        -N INCREMENT -o "${zone}" -K "${KEYS_DIR}" "${zone}.db"
   
    if [ -f "${zone}.db.signed" ]; then
        echo "Zone ${zone} signed successfully"
        chown bind:bind "${zone}.db.signed"
       
        # Update named.conf if needed
        if ! grep -q "${zone}.db.signed" "${NAMEDB_DIR}/named.conf"; then
            sed -i '' -E "s|(file \"${PRIMARY_DIR}/${zone}).db\"|\1.db.signed\"|" "${NAMEDB_DIR}/named.conf"
        fi
       
        # Display DS records
        echo "DS records for ${zone}:"
        for keyfile in "${KEYS_DIR}"/K${zone}.+007+*.key; do
            if grep -q "KSK" "$keyfile" 2>/dev/null; then
                dnssec-dsfromkey "$keyfile"
            fi
        done
    else
        echo "Failed to sign zone ${zone}"
        # Restore original zone file
        mv "${PRIMARY_DIR}/${zone}.db.backup" "${PRIMARY_DIR}/${zone}.db"
    fi
   
    # Clean up backup file
    rm -f "${PRIMARY_DIR}/${zone}.db.backup"
}

# Process all zone files
for zonefile in "${PRIMARY_DIR}"/*.db; do
    [ -f "$zonefile" ] || continue
    process_zone "$zonefile"
done

# Reload BIND
service named reload

echo "DNSSEC setup completed"