Unbound + TOR + BIND + NGINX - Local DNSSEC Nested in CA DNSSEC

The whole of this post should be treated as incomplete at this time. That’s because it is not complete :slight_smile: . Looking for something with a little more polish? Check this out - LXC TOR + Pihole + Unbound + DNSSEC - Anonymous Recursive Secure DNS

BIND + NGINX - Local DNSSEC Nested in CA DNSSEC

deploy2.sh

#!/bin/bash
set -e

# Ensure the script is running as root
if [ "$(id -u)" -ne 0 ]; then
  echo "This script must be run as root"
  exit 1
fi

# Update system and install dependencies
apt update && apt upgrade -y
apt install -y unbound tor nginx certbot python3-certbot-nginx curl jq dnsutils bind9 bind9utils bind9-doc

# DOMAIN configuration
DOMAIN="REPLACEWITHYOURDOMAINHERE"

# Configure Unbound with DNSSEC
echo "Configuring Unbound with DNSSEC..."
cat <<EOF > /etc/unbound/unbound.conf
server:
  verbosity: 1
  interface: 0.0.0.0
  access-control: 0.0.0.0/0 allow
  port: 53
  do-ip6: no
  root-hints: /var/lib/unbound/root.hints
  auto-trust-anchor-file: "/var/lib/unbound/root.key"
  logfile: "/var/log/unbound.log"
  log-time-ascii: yes
  use-syslog: yes
  log-level: 2
  cache-min-ttl: 3600
  cache-max-ttl: 86400
EOF

# Fetch DNSSEC root hints
wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
touch /var/lib/unbound/root.key

# Obtain or renew SSL certificate using HTTP-01 challenge
echo "Obtaining or renewing SSL certificate using HTTP-01 challenge..."
certbot certonly --standalone --http-01-port 8080 -d $DOMAIN --agree-tos --no-eff-email --email [email protected]

# Generate DNSSEC Key with BIND tools
echo "Generating DNSSEC Key with BIND..."
cd /etc/bind
dnssec-keygen -a RSASHA256 -b 2048 -n ZONE $DOMAIN

# Find the key file generated by dnssec-keygen
KEY_FILE=$(ls K$DOMAIN.+008+*.key | head -n 1)

# Ensure the key file exists
if [ ! -f "$KEY_FILE" ]; then
  echo "Key file $KEY_FILE not found!"
  exit 1
fi

echo "Using key file: $KEY_FILE"

# Generate DS Record using dnssec-dsfromkey
echo "Generating DS record for DNSSEC..."
DS_RECORD=$(dnssec-dsfromkey -2 $KEY_FILE)

# Output the raw DS record for debugging
echo "Raw DS record: $DS_RECORD"

# Check if the DS Record was generated successfully
if [ $? -ne 0 ]; then
  echo "Error generating DS record!"
  exit 1
fi

# Extract the DS record contents using awk
DS_KEY_TAG=$(echo $DS_RECORD | awk '{print $3}')
DS_ALGORITHM=$(echo $DS_RECORD | awk '{print $4}')
DS_DIGEST_TYPE=$(echo $DS_RECORD | awk '{print $5}')
DS_DIGEST=$(echo $DS_RECORD | awk '{print $6}')

# Check if the DS fields are extracted correctly
if [ -z "$DS_KEY_TAG" ] || [ -z "$DS_ALGORITHM" ] || [ -z "$DS_DIGEST_TYPE" ] || [ -z "$DS_DIGEST" ]; then
  echo "Error: Missing required DS record fields."
  exit 1
fi

echo "DNSSEC setup completed successfully!"

# Configure NGINX for SSL
echo "Configuring NGINX for SSL..."
cat <<EOF > /etc/nginx/sites-available/unbound
server {
    listen 8080;
    server_name $DOMAIN;

    location / {
        proxy_pass http://127.0.0.1:5335;
    }
}

server {
    listen 443 ssl;
    server_name $DOMAIN;

    ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:5335;
    }
}
EOF

# Ensure no existing symbolic link is in place before creating a new one
if [ -L /etc/nginx/sites-enabled/unbound ]; then
  rm /etc/nginx/sites-enabled/unbound
fi

ln -s /etc/nginx/sites-available/unbound /etc/nginx/sites-enabled/
systemctl restart nginx

echo "[+] Setup completed."

This script automates the setup of a self-hosted, secure DNS and SSL environment using Unbound, NGINX, Certbot, and BIND for DNSSEC. It was originally designed to use Cloudflare for external DNS management but has been modified to operate independently with self-signed DNSSEC inside a CA-signed certificate.

How It Works

  1. System Preparation
  • Ensures the script runs as root.
  • Updates and installs required dependencies (Unbound, Tor, NGINX, Certbot, BIND, etc.).
  1. Unbound DNSSEC Setup
  • Configures Unbound as a recursive DNS resolver with DNSSEC validation.
  • Fetches root hints for secure name resolution.
  • Generates a DNSSEC signing key using BIND.
  1. SSL Certificate Management with Certbot
  • Originally, Cloudflare API integration was used for DNS-based SSL validation, but this is now disabled.
  • Certbot obtains a CA-signed SSL certificate for external use (e.g., HTTPS websites).
  • Internally, self-signed DNSSEC keys are generated.
  1. NGINX Configuration
  • Sets up reverse proxy rules to serve DNS-over-HTTPS (DoH) or other services securely.
  • Uses Certbot-generated SSL certificates for public-facing services.
  • Ensures that internally signed DNSSEC works without CA trust requirements.
  1. DNSSEC Key Generation & Deployment
  • Generates a self-signed DNSSEC key inside the internal Unbound system.
  • Distributes the DNSSEC signature without relying on external DNS providers.
  • Avoids browsers marking internal DNS as insecure while keeping encryption self-managed.

Use Cases

  1. Self-Hosted Secure DNS Resolver
  • Users can run their own private, encrypted DNS resolver instead of relying on third-party providers like Google or Cloudflare.
  • Prevents DNS tracking and enhances privacy.
  1. Decentralized & Encrypted Home Network
  • Ideal for homelab setups where users want their own CA-signed external certificates while keeping DNSSEC fully internal.
  • Supports off-grid or self-sovereign infrastructure without dependence on external CAs.
  1. Stealth & Anti-Censorship DNS
  • Allows users to bypass ISP-level DNS blocking by running a hidden DNS resolver.
  • Works with Tor integration for anonymity.
  1. Zero-Trust Internal Network
  • Keeps DNSSEC encryption valid for internal traffic without trusting third-party CAs.
  • Prevents devices from marking internal sites as “untrusted” due to self-signed DNSSEC.

Cloudflare

This appears to work with marginal Cloudflare support:

#!/bin/bash
set -e

# Ensure script is run as root
if [ "$(id -u)" -ne 0 ]; then
  echo "This script must be run as root"
  exit 1
fi

# Variables (Update these with your actual details)
CLOUDFLARE_ZONE_ID="YOUR_CLOUDFLARE_ZONE_ID"
CLOUDFLARE_API_TOKEN="YOUR_CLOUDFLARE_API_TOKEN"
DOMAIN="YOUR_FULLY_QUALIFIED_DOMAIN_NAME"
EMAIL="[email protected]"

# Update system and install dependencies
apt update && apt upgrade -y
apt install -y unbound tor nginx certbot python3-certbot-dns-cloudflare curl jq dnsutils bind9 bind9utils bind9-doc

# Configure Unbound with DNSSEC
echo "Configuring Unbound with DNSSEC..."
cat <<EOF > /etc/unbound/unbound.conf
server:
  verbosity: 1
  interface: 0.0.0.0
  access-control: 0.0.0.0/0 allow
  port: 53
  do-ip6: no
  root-hints: /var/lib/unbound/root.hints
  auto-trust-anchor-file: "/var/lib/unbound/root.key"
  logfile: "/var/log/unbound.log"
  log-time-ascii: yes
  use-syslog: yes
  log-level: 2
  cache-min-ttl: 3600
  cache-max-ttl: 86400
EOF

# Fetch DNSSEC root hints
wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
touch /var/lib/unbound/root.key

# Configure Cloudflare DNS API credentials for Certbot
echo "dns_cloudflare_api_token = $CLOUDFLARE_API_TOKEN" > /root/.cloudflare.ini
chmod 600 /root/.cloudflare.ini

# Obtain SSL certificate using DNS-01 challenge
echo "Obtaining SSL certificate using DNS-01 challenge..."
certbot certonly --dns-cloudflare --dns-cloudflare-credentials /root/.cloudflare.ini -d $DOMAIN --agree-tos --no-eff-email --email $EMAIL --non-interactive --force-renewal || echo "Certificate renewal not necessary or failed, script continues..."

# Generate DNSSEC Key with BIND tools
echo "Generating DNSSEC Key with BIND..."
cd /etc/bind
dnssec-keygen -a RSASHA256 -b 2048 -n ZONE $DOMAIN

# Find the key file generated by dnssec-keygen
KEY_FILE=$(ls K$DOMAIN.+008+*.key | head -n 1)

# Ensure the key file exists
if [ ! -f "$KEY_FILE" ]; then
  echo "Key file $KEY_FILE not found!"
  exit 1
fi

echo "Using key file: $KEY_FILE"

# Generate DS Record using dnssec-dsfromkey
echo "Generating DS record for DNSSEC..."
DS_RECORD=$(dnssec-dsfromkey -2 $KEY_FILE)

# Output the raw DS record for debugging
echo "Raw DS record: $DS_RECORD"

# Check if the DS Record was generated successfully
if [ $? -ne 0 ]; then
  echo "Error generating DS record!"
  exit 1
fi

# Extract the DS record contents using awk
DS_KEY_TAG=$(echo $DS_RECORD | awk '{print $3}')
DS_ALGORITHM=$(echo $DS_RECORD | awk '{print $4}')
DS_DIGEST_TYPE=$(echo $DS_RECORD | awk '{print $5}')
DS_DIGEST=$(echo $DS_RECORD | awk '{print $6}')

# Check if the DS fields are extracted correctly
if [ -z "$DS_KEY_TAG" ] || [ -z "$DS_ALGORITHM" ] || [ -z "$DS_DIGEST_TYPE" ] || [ -z "$DS_DIGEST" ]; then
  echo "Error: Missing required DS record fields."
  exit 1
fi

echo "DNSSEC setup completed successfully!"

# Configure NGINX for SSL
echo "Configuring NGINX for SSL..."
cat <<EOF > /etc/nginx/sites-available/unbound
server {
    listen 8080;
    server_name $DOMAIN;

    location / {
        proxy_pass http://127.0.0.1:5335;
    }
}

server {
    listen 443 ssl;
    server_name $DOMAIN;

    ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:5335;
    }
}
EOF

# Ensure no existing symbolic link is in place before creating a new one
if [ -L /etc/nginx/sites-enabled/unbound ]; then
  rm /etc/nginx/sites-enabled/unbound
fi

ln -s /etc/nginx/sites-available/unbound /etc/nginx/sites-enabled/
systemctl restart nginx

echo "[+] Setup completed."

This is Broken:

#!/bin/bash
set -e

# Ensure script is run as root
if [ "$(id -u)" -ne 0 ]; then
  echo "This script must be run as root"
  exit 1
fi

# Variables (Update these with your actual details)
DOMAIN="YOUR-FQDN"
CLOUDFLARE_API_TOKEN="YOUR_CLOUDFLARE_API_TOKEN"
CLOUDFLARE_ZONE_ID="YOUR_+CLOUDFLARE_ZONE_ID"
EMAIL="[email protected]"

# Update system and install dependencies
apt update && apt upgrade -y
apt install -y unbound tor nginx certbot python3-certbot-dns-cloudflare curl jq dnsutils bind9 bind9utils bind9-doc

# Configure Unbound with DNSSEC
echo "Configuring Unbound with DNSSEC..."
cat <<EOF > /etc/unbound/unbound.conf
server:
  verbosity: 1
  interface: 0.0.0.0
  access-control: 0.0.0.0/0 allow
  port: 53
  do-ip6: no
  root-hints: /var/lib/unbound/root.hints
  auto-trust-anchor-file: "/var/lib/unbound/root.key"
  logfile: "/var/log/unbound.log"
  log-time-ascii: yes
  use-syslog: yes
  log-level: 2
  cache-min-ttl: 3600
  cache-max-ttl: 86400
EOF

# Fetch DNSSEC root hints
wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
touch /var/lib/unbound/root.key

# Configure Cloudflare DNS API credentials for Certbot
echo "dns_cloudflare_api_token = $CLOUDFLARE_API_TOKEN" > /root/.cloudflare.ini
chmod 600 /root/.cloudflare.ini

# Obtain SSL certificate using DNS-01 challenge
echo "Obtaining SSL certificate using DNS-01 challenge..."
certbot certonly --dns-cloudflare --dns-cloudflare-credentials /root/.cloudflare.ini -d $DOMAIN --agree-tos --no-eff-email --email $EMAIL --non-interactive --force-renewal || echo "Certificate renewal not necessary or failed, script continues..."

# Generate DNSSEC Key with BIND tools
echo "Generating DNSSEC Key with BIND..."
cd /etc/bind
dnssec-keygen -a RSASHA256 -b 2048 -n ZONE $DOMAIN

# Find the key file generated by dnssec-keygen
KEY_FILE=$(ls K$DOMAIN.+008+*.key | head -n 1)

# Ensure the key file exists
if [ ! -f "$KEY_FILE" ]; then
  echo "Key file $KEY_FILE not found!"
  exit 1
fi

echo "Using key file: $KEY_FILE"

# Generate DS Record using dnssec-dsfromkey
echo "Generating DS record for DNSSEC..."
DS_RECORD=$(dnssec-dsfromkey -2 $KEY_FILE)

# Output the raw DS record for debugging
echo "Raw DS record: $DS_RECORD"

# Check if the DS Record was generated successfully
if [ $? -ne 0 ]; then
  echo "Error generating DS record!"
  exit 1
fi

# Extract the DS record contents using awk
DS_KEY_TAG=$(echo $DS_RECORD | awk '{print $3}')
DS_ALGORITHM=$(echo $DS_RECORD | awk '{print $4}')
DS_DIGEST_TYPE=$(echo $DS_RECORD | awk '{print $5}')
DS_DIGEST=$(echo $DS_RECORD | awk '{print $6}')

# Check if the DS fields are extracted correctly
if [ -z "$DS_KEY_TAG" ] || [ -z "$DS_ALGORITHM" ] || [ -z "$DS_DIGEST_TYPE" ] || [ -z "$DS_DIGEST" ]; then
  echo "Error: Missing required DS record fields."
  exit 1
fi

echo "DNSSEC setup completed successfully!"

# Configure NGINX for SSL
echo "Configuring NGINX for SSL..."
cat <<EOF > /etc/nginx/sites-available/unbound
server {
    listen 8080;
    server_name $DOMAIN;

    location / {
        proxy_pass http://127.0.0.1:5335;
    }
}

server {
    listen 443 ssl;
    server_name $DOMAIN;

    ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:5335;
    }
}
EOF

# Ensure no existing symbolic link is in place before creating a new one
if [ -L /etc/nginx/sites-enabled/unbound ]; then
  rm /etc/nginx/sites-enabled/unbound
fi

ln -s /etc/nginx/sites-available/unbound /etc/nginx/sites-enabled/
systemctl restart nginx

echo "[+] Setup completed."

This is my preferred script, but Cloudflare’s API has a problem which will hopefully soon be patched as of this writing. Otherwise, there do appear to be work-arounds. I just haven’t found one for my specific application yet…

#!/bin/bash
set -e

# Ensure the script is running as root
if [ "$(id -u)" -ne 0 ]; then
  echo "This script must be run as root"
  exit 1
fi

# Update system and install dependencies
apt update && apt upgrade -y
apt install -y unbound tor nginx certbot python3-certbot-nginx python3-certbot-dns-cloudflare curl jq dnsutils bind9 bind9utils bind9-doc

# Cloudflare API configuration
CLOUDFLARE_ZONE_ID="ZONEID" 
CLOUDFLARE_API_TOKEN="APITOKEN" 
DOMAIN="REPLACE_DOMAIN_HERE"

# Function to create DNS record in Cloudflare for DS records
create_dns_record() {
  local record_type=$1
  local record_name=$2
  local key_tag=$3
  local algorithm=$4
  local digest_type=$5
  local digest=$6
  local ttl=$7

  local json_data="{\"type\":\"$record_type\",\"name\":\"$record_name\",\"content\":{\"key_tag\":$key_tag,\"algorithm\":$algorithm,\"digest_type\":$digest_type,\"digest\":\"$digest\"},\"ttl\":$ttl,\"proxied\":false}"
  
  echo "JSON data being sent: $json_data"  # Debug output
  
  curl -X POST "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records" \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data "$json_data"
}

# Configure Unbound with DNSSEC
echo "Configuring Unbound with DNSSEC..."
cat <<EOF > /etc/unbound/unbound.conf
server:
  verbosity: 1
  interface: 0.0.0.0
  access-control: 0.0.0.0/0 allow
  port: 53
  do-ip6: no
  root-hints: /var/lib/unbound/root.hints
  auto-trust-anchor-file: "/var/lib/unbound/root.key"
  logfile: "/var/log/unbound.log"
  log-time-ascii: yes
  use-syslog: yes
  log-level: 2
  cache-min-ttl: 3600
  cache-max-ttl: 86400
EOF

# Fetch DNSSEC root hints
wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
touch /var/lib/unbound/root.key

# Cloudflare credentials file for Certbot
echo "dns_cloudflare_api_token = $CLOUDFLARE_API_TOKEN" > /etc/letsencrypt/cloudflare.ini
chmod 600 /etc/letsencrypt/cloudflare.ini

# Obtain or renew SSL certificate using DNS-01 challenge
echo "Obtaining or renewing SSL certificate using DNS-01 challenge..."
certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini -d $DOMAIN --agree-tos --no-eff-email --email [email protected]

# Generate DNSSEC Key with BIND tools
echo "Generating DNSSEC Key with BIND..."
cd /etc/bind
dnssec-keygen -a RSASHA256 -b 2048 -n ZONE $DOMAIN

# Find the key file generated by dnssec-keygen
KEY_FILE=$(ls K$DOMAIN.+008+*.key | head -n 1)

# Ensure the key file exists
if [ ! -f "$KEY_FILE" ]; then
  echo "Key file $KEY_FILE not found!"
  exit 1
fi

echo "Using key file: $KEY_FILE"

# Generate DS Record using dnssec-dsfromkey
echo "Generating DS record for DNSSEC..."
DS_RECORD=$(dnssec-dsfromkey -2 $KEY_FILE)

# Output the raw DS record for debugging
echo "Raw DS record: $DS_RECORD"

# Check if the DS Record was generated successfully
if [ $? -ne 0 ]; then
  echo "Error generating DS record!"
  exit 1
fi

# Extract the DS record contents using awk
DS_KEY_TAG=$(echo $DS_RECORD | awk '{print $3}')
DS_ALGORITHM=$(echo $DS_RECORD | awk '{print $4}')
DS_DIGEST_TYPE=$(echo $DS_RECORD | awk '{print $5}')
DS_DIGEST=$(echo $DS_RECORD | awk '{print $6}')

# Check if the DS fields are extracted correctly
if [ -z "$DS_KEY_TAG" ] || [ -z "$DS_ALGORITHM" ] || [ -z "$DS_DIGEST_TYPE" ] || [ -z "$DS_DIGEST" ]; then
  echo "Error: Missing required DS record fields."
  exit 1
fi

# Now we can upload the DS record to Cloudflare
echo "Creating DS record in Cloudflare..."
create_dns_record "DS" "$DOMAIN" "$DS_KEY_TAG" "$DS_ALGORITHM" "$DS_DIGEST_TYPE" "$DS_DIGEST" 3600

echo "DNSSEC setup completed successfully!"

# Configure NGINX for SSL
echo "Configuring NGINX for SSL..."
cat <<EOF > /etc/nginx/sites-available/unbound
server {
    listen 8080;
    server_name $DOMAIN;

    location / {
        proxy_pass http://127.0.0.1:5335;
    }
}

server {
    listen 443 ssl;
    server_name $DOMAIN;

    ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:5335;
    }
}
EOF

# Ensure no existing symbolic link is in place before creating a new one
if [ -L /etc/nginx/sites-enabled/unbound ]; then
  rm /etc/nginx/sites-enabled/unbound
fi

ln -s /etc/nginx/sites-available/unbound /etc/nginx/sites-enabled/
systemctl restart nginx

echo "[+] Setup completed."

https://forums.unraid.net/topic/126445-support-kilrahcloudflare-ddns-config/page/2/

https://community.ui.com/questions/DynDNS-current-support-for-NON-Global-TOKEN-key-is-borken/57205ad1-3911-40e1-afc4-0caff3b9ad1d

https://www.reddit.com/r/CloudFlare/comments/1916dpj/cloudflare_api_assistance/

https://community.cloudflare.com/t/cannot-patch-dns-record/606912

Earlier Revisions…

script1.sh

#!/bin/bash
set -e

echo "[+] Updating system..."
apt update && apt upgrade -y

echo "[+] Installing dependencies..."
apt install -y curl iptables-persistent unbound tor avahi-daemon avahi-utils jq

# Install Pi-hole with option to skip OS check for compatibility
sudo PIHOLE_SKIP_OS_CHECK=true curl -sSL https://install.pi-hole.net | bash

echo "[+] Configuring Unbound..."
cat > /etc/unbound/unbound.conf <<EOL
server:
    interface: 127.0.0.1
    interface: ::1
    access-control: 127.0.0.1 allow
    access-control: ::1 allow
    port: 5335
    do-ip4: yes
    do-ip6: yes
    do-udp: yes
    do-tcp: yes
    hide-identity: yes
    hide-version: yes
    forward-zone:
        name: "."
        forward-addr: 127.0.0.1@9053
EOL

# Add DNSSEC validation to Unbound
echo "[+] Adding DNSSEC validation to Unbound..."
cat > /etc/unbound/unbound.conf.d/pi-hole.conf <<EOL
server:
    verbosity: 1
    interface: 0.0.0.0
    port: 5353
    do-ip4: yes
    do-ip6: yes
    do-udp: yes
    do-tcp: yes
    access-control: 0.0.0.0/0 allow
    cache-max-ttl: 86400
    cache-min-ttl: 3600
    harden-dnssec-stripped: yes
    use-caps-for-id: no
    prefetch: yes
    num-threads: 2
    so-reuseport: yes
    msg-cache-size: 128m
    rrset-cache-size: 256m
    infra-cache-numhosts: 100000
    neg-cache-size: 4m
    do-not-query-localhost: no
    hide-identity: yes
    hide-version: yes
    qname-minimisation: yes
    harden-glue: yes
    harden-below-nxdomain: yes
    target-fetch-policy: "2 1 0 0 0"
    val-log-level: 1
    tls-cert-bundle: "/etc/ssl/certs/ca-certificates.crt"
EOL

echo "[+] Restarting Unbound and Pi-hole..."
systemctl restart pihole-FTL unbound

echo "[+] Configuring Tor Hidden Service..."
mkdir -p /var/lib/tor/pihole
chown -R debian-tor:debian-tor /var/lib/tor/pihole
chmod 700 /var/lib/tor/pihole
cat > /etc/tor/torrc <<EOL
HiddenServiceDir /var/lib/tor/pihole/
HiddenServicePort 53 127.0.0.1:53
HiddenServicePort 80 127.0.0.1:80
HiddenServicePort 9053 127.0.0.1:9053
AutomapHostsOnResolve 1
DNSPort 127.0.0.1:9053
TransPort 9040
SocksPort 127.0.0.1:9050

VirtualAddrNetworkIPv4 10.192.0.0/10
AutomapHostsSuffixes .onion,.exit
TransListenAddress 0.0.0.0
DNSListenAddress 0.0.0.0
EOL

echo "[+] Restarting Tor..."
systemctl restart tor

echo "[+] Enabling Avahi for local discovery..."
systemctl enable avahi-daemon
systemctl restart avahi-daemon

echo "[+] Waiting for Tor Hidden Service to be available..."
sleep 20
ONION_ADDR=$(cat /var/lib/tor/pihole/hostname)

echo "[+] Registering local and remote peers..."
PEER_FILE="/etc/pihole/nodes.conf"
avahi-browse -rt _pihole._tcp | grep "=" | awk '{print $6}' > $PEER_FILE
echo "tor://$ONION_ADDR" >> $PEER_FILE

while read -r NODE; do
    echo "Discovered node: $NODE"
    curl -s "http://$NODE/peers" >> $PEER_FILE || true
done < $PEER_FILE

echo "[+] Updating Unbound configuration..."
UNBOUND_CONF="/etc/unbound/unbound.conf"
sed -i 's/do-not-query-localhost: yes/do-not-query-localhost: no/g' $UNBOUND_CONF
sed -i '/forward-zone:/,/^$/d' $UNBOUND_CONF

cat >> $UNBOUND_CONF <<EOL
forward-zone:
    name: "."
    forward-addr: 127.0.0.1@9053
EOL

echo "[+] Restarting Unbound..."
systemctl restart unbound

echo "[+] Configuring iptables to force all traffic through Tor..."
iptables -F
iptables -t nat -F
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 9040
iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-port 9040
iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-port 9053
iptables-save > /etc/iptables.rules
netfilter-persistent save
netfilter-persistent reload

echo "[+] Script completed."

Script2.sh

#!/bin/bash
set -e

# Ensure the script is running as root
if [ "$(id -u)" -ne 0 ]; then
  echo "This script must be run as root"
  exit 1
fi

# Update system and install dependencies
apt update && apt upgrade -y
apt install -y unbound tor nginx certbot python3-certbot-nginx curl jq dnsutils

# Cloudflare API configuration
CLOUDFLARE_API_TOKEN="your-cloudflare-api-token"
CLOUDFLARE_ZONE_ID="your-cloudflare-zone-id"
DOMAIN="yourdomain.com"

# Create DNS record in Cloudflare
create_dns_record() {
  local record_type=$1
  local record_name=$2
  local record_content=$3
  local ttl=$4

  curl -X POST "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records" \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data "{\"type\":\"$record_type\",\"name\":\"$record_name\",\"content\":\"$record_content\",\"ttl\":$ttl,\"proxied\":false}"
}

# Configure Unbound with DNSSEC
echo "Configuring Unbound with DNSSEC..."
cat <<EOF > /etc/unbound/unbound.conf
server:
  verbosity: 1
  interface: 0.0.0.0
  access-control: 0.0.0.0/0 allow
  port: 53
  do-ip6: no
  root-hints: /var/lib/unbound/root.hints
  auto-trust-anchor-file: "/var/lib/unbound/root.key"
  logfile: "/var/log/unbound.log"
  log-time-ascii: yes
  use-syslog: yes
  log-level: 2
  cache-min-ttl: 3600
  cache-max-ttl: 86400
EOF

# Fetch DNSSEC root hints
wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
touch /var/lib/unbound/root.key

# Configure SSL with Certbot
echo "Obtaining SSL certificate..."
certbot certonly --standalone -d $DOMAIN --agree-tos --no-eff-email --email [email protected]

# Generate DS record
echo "Generating DS record for DNSSEC..."
dnssec-dsfromkey -2 /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/unbound/ds-record.txt
DS_RECORD_CONTENT=$(cat /etc/unbound/ds-record.txt)

# Create DS record in Cloudflare
create_dns_record "DS" "$DOMAIN" "$DS_RECORD_CONTENT" 3600

# Configure NGINX
echo "Configuring NGINX for SSL..."
cat <<EOF > /etc/nginx/sites-available/unbound
server {
    listen 80;
    server_name $DOMAIN;

    location / {
        proxy_pass http://127.0.0.1:5335;
    }
}

server {
    listen 443 ssl;
    server_name $DOMAIN;

    ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:5335;
    }
}
EOF

ln -s /etc/nginx/sites-available/unbound /etc/nginx/sites-enabled/
systemctl restart nginx

echo "[+] Setup completed."

NestedA.sh

#!/bin/bash
set -e

# Ensure the script is running as root
if [ "$(id -u)" -ne 0 ]; then
  echo "This script must be run as root"
  exit 1
fi

# Update system and install dependencies
apt update && apt upgrade -y
apt install -y unbound tor nginx certbot python3-certbot-nginx curl jq dnsutils bind9 bind9utils bind9-doc

# DOMAIN configuration
DOMAIN="REPLACEWITHYOURDOMAINHERE"

# Configure Unbound with DNSSEC
echo "Configuring Unbound with DNSSEC..."
cat <<EOF > /etc/unbound/unbound.conf
server:
  verbosity: 1
  interface: 0.0.0.0
  access-control: 0.0.0.0/0 allow
  port: 53
  do-ip6: no
  root-hints: /var/lib/unbound/root.hints
  auto-trust-anchor-file: "/var/lib/unbound/root.key"
  logfile: "/var/log/unbound.log"
  log-time-ascii: yes
  use-syslog: yes
  log-level: 2
  cache-min-ttl: 3600
  cache-max-ttl: 86400
EOF

# Fetch DNSSEC root hints
wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
touch /var/lib/unbound/root.key

# Obtain or renew SSL certificate using HTTP-01 challenge
echo "Obtaining or renewing SSL certificate using HTTP-01 challenge..."
certbot certonly --standalone --http-01-port 8080 -d $DOMAIN --agree-tos --no-eff-email --email [email protected]

# Generate DNSSEC Key with BIND tools
echo "Generating DNSSEC Key with BIND..."
cd /etc/bind
dnssec-keygen -a RSASHA256 -b 2048 -n ZONE $DOMAIN

# Find the key file generated by dnssec-keygen
KEY_FILE=$(ls K$DOMAIN.+008+*.key | head -n 1)

# Ensure the key file exists
if [ ! -f "$KEY_FILE" ]; then
  echo "Key file $KEY_FILE not found!"
  exit 1
fi

echo "Using key file: $KEY_FILE"

# Generate DS Record using dnssec-dsfromkey (locally)
echo "Generating DS record for DNSSEC..."
DS_RECORD=$(dnssec-dsfromkey -2 $KEY_FILE)

# Output the raw DS record for debugging
echo "Raw DS record: $DS_RECORD"

# Check if the DS Record was generated successfully
if [ $? -ne 0 ]; then
  echo "Error generating DS record!"
  exit 1
fi

# Extract the DS record contents using awk
DS_KEY_TAG=$(echo $DS_RECORD | awk '{print $3}')
DS_ALGORITHM=$(echo $DS_RECORD | awk '{print $4}')
DS_DIGEST_TYPE=$(echo $DS_RECORD | awk '{print $5}')
DS_DIGEST=$(echo $DS_RECORD | awk '{print $6}')

# Check if the DS fields are extracted correctly
if [ -z "$DS_KEY_TAG" ] || [ -z "$DS_ALGORITHM" ] || [ -z "$DS_DIGEST_TYPE" ] || [ -z "$DS_DIGEST" ]; then
  echo "Error: Missing required DS record fields."
  exit 1
fi

echo "DNSSEC setup completed successfully!"

# DNSSEC Nested Setup (local generation)
echo "Local DS record generated for nested DNSSEC setup:"
echo "$DS_KEY_TAG $DS_ALGORITHM $DS_DIGEST_TYPE $DS_DIGEST"

# Add DS record to your parent zone manually (for nested DNSSEC setup)
echo "Ensure that the DS record for $DOMAIN is added to your parent zone."

# Configure NGINX for SSL
echo "Configuring NGINX for SSL..."
cat <<EOF > /etc/nginx/sites-available/unbound
server {
    listen 8080;
    server_name $DOMAIN;

    location / {
        proxy_pass http://127.0.0.1:5335;
    }
}

server {
    listen 443 ssl;
    server_name $DOMAIN;

    ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:5335;
    }
}
EOF

# Ensure no existing symbolic link is in place before creating a new one
if [ -L /etc/nginx/sites-enabled/unbound ]; then
  rm /etc/nginx/sites-enabled/unbound
fi

ln -s /etc/nginx/sites-available/unbound /etc/nginx/sites-enabled/
systemctl restart nginx

echo "[+] Setup completed."

NestedB1.sh

#!/bin/bash

# Ensure the script is running as root
if [ "$(id -u)" -ne 0 ]; then
  echo "This script must be run as root"
  exit 1
fi

# Update the system and install dependencies
apt update && apt upgrade -y
apt install -y unbound tor nginx certbot python3-certbot-nginx curl jq dnsutils

# Set up Cloudflare API for DNS record management
CLOUDFLARE_API_TOKEN="your-cloudflare-api-token"
CLOUDFLARE_ZONE_ID="your-cloudflare-zone-id"
DOMAIN="yourdomain.com"

# Function to create DNS record in Cloudflare
create_dns_record() {
  local record_type=$1
  local record_name=$2
  local record_content=$3
  local ttl=$4

  curl -X POST "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records" \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data "{\"type\":\"$record_type\",\"name\":\"$record_name\",\"content\":\"$record_content\",\"ttl\":$ttl,\"proxied\":false}"
}

# Set up Unbound with DNSSEC and CA-signed certificate
echo "Configuring Unbound with DNSSEC and CA-signed certificate..."

# Backup current Unbound config
cp /etc/unbound/unbound.conf /etc/unbound/unbound.conf.bak

# Update Unbound config for DNSSEC
cat <<EOF > /etc/unbound/unbound.conf
server:
  verbosity: 1
  interface: 0.0.0.0
  access-control: 0.0.0.0/0 allow
  port: 53
  do-ip6: no
  root-hints: /var/lib/unbound/root.hints
  auto-trust-anchor-file: "/var/lib/unbound/root.key"
  logfile: "/var/log/unbound.log"
  log-time-ascii: yes
  use-syslog: yes
  log-level: 2
  cache-min-ttl: 3600
  cache-max-ttl: 86400
  edns-buffer-size: 1232
  prefetch: yes
  prefetch-key: yes
  trust-anchor-file: "/etc/unbound/trust-anchor.pem"
  include: /etc/unbound/unbound.conf.d/*.conf
EOF

# Fetch root hints and trust anchor
wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
touch /var/lib/unbound/root.key

# Dynamically fetch the CA DNSSEC trust anchor (example for Let's Encrypt)
curl -s https://letsencrypt.org/certificates/lets-encrypt-x3-cross-signed.pem > /etc/unbound/trust-anchor.pem

# Install certificate via Certbot
echo "Obtaining SSL certificate via Certbot..."

# Replace 'yourdomain.com' with your domain
certbot certonly --standalone -d $DOMAIN --agree-tos --no-eff-email --email [email protected]

# Generate DS record from DNSSEC key
echo "Generating DS record for DNSSEC..."

# First, generate the DS record
dnssec-dsfromkey -2 /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/unbound/ds-record.txt

# Extract the DS record from the file
DS_RECORD_CONTENT=$(cat /etc/unbound/ds-record.txt)

# Create the DS record in Cloudflare
create_dns_record "DS" "$DOMAIN" "$DS_RECORD_CONTENT" 3600

# Configure NGINX to use SSL and serve Unbound DNSSEC
echo "Configuring NGINX for SSL..."

cat <<EOF > /etc/nginx/sites-available/unbound
server {
    listen 80;
    server_name $DOMAIN;

    location / {
        proxy_pass http://127.0.0.1:53;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}

server {
    listen 443 ssl;
    server_name $DOMAIN;

    ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:53;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    }
}
EOF

# Enable and start NGINX
ln -s /etc/nginx/sites-available/unbound /etc/nginx/sites-enabled/
systemctl restart nginx

# Set up Tor and configure strict routing (following script2 rules)
echo "Configuring Tor routing logic with strict mode and routing rules..."

# Backup current Tor config
cp /etc/tor/torrc /etc/tor/torrc.bak

cat <<EOF > /etc/tor/torrc
# Use the default Tor configuration
SocksPort 9050
Log notice stdout
RunAsDaemon 1
ExitNodes {us}
StrictNodes 1
ControlPort 9051
CookieAuthentication 1
DataDirectory /var/lib/tor

# Ensure all traffic routes through Tor
TransPort 9040
DNSPort 53
AutomapHostsOnResolve 1
DNSExitNode 1
EOF

# Restart Tor service
systemctl restart tor

# Set up Unbound to forward DNS queries to Tor
echo "Configuring Unbound to use Tor for DNS queries..."

# Update Unbound config to route DNS queries through Tor
cat <<EOF >> /etc/unbound/unbound.conf.d/tor.conf
forward-zone:
  name: "."
  forward-addr: 127.0.0.1@9053
EOF

# Restart Unbound
systemctl restart unbound

# Configure logs for debugging
echo "Setting up logs for debugging..."

# Create log file for Unbound
touch /var/log/unbound.log
chmod 640 /var/log/unbound.log

# Create log file for Tor
touch /var/log/tor.log
chmod 640 /var/log/tor.log

# Create log file for NGINX
touch /var/log/nginx/access.log
touch /var/log/nginx/error.log
chmod 640 /var/log/nginx/*.log

# Enable services to start on boot
systemctl enable unbound
systemctl enable tor
systemctl enable nginx

# Output success message
echo "Configuration complete. Your Unbound DNSSEC server is now running with a CA-signed certificate and Tor routing enabled."
echo "Logs for debugging are available at /var/log/unbound.log, /var/log/tor.log, and /var/log/nginx/."

# Dynamically create DNS records for your domain via Cloudflare API (A record and DS record for DNSSEC)
echo "Creating DNS records for $DOMAIN..."

# Create A record for the domain
create_dns_record "A" "$DOMAIN" "$(curl -s ifconfig.me)" 3600

echo "DNS records created in Cloudflare. Please check your domain to confirm everything is set up."

NestedB2.sh

#!/bin/bash

# Ensure the script is running as root
if [ "$(id -u)" -ne 0 ]; then
  echo "This script must be run as root"
  exit 1
fi

# Update the system and install dependencies
apt update && apt upgrade -y
apt install -y unbound tor nginx certbot python3-certbot-nginx curl jq

# Set up Cloudflare API for DNS record management
CLOUDFLARE_API_TOKEN="your-cloudflare-api-token"
CLOUDFLARE_ZONE_ID="your-cloudflare-zone-id"
DOMAIN="yourdomain.com"

# Function to create DNS record in Cloudflare
create_dns_record() {
  local record_type=$1
  local record_name=$2
  local record_content=$3
  local ttl=$4

  curl -X POST "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records" \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data "{\"type\":\"$record_type\",\"name\":\"$record_name\",\"content\":\"$record_content\",\"ttl\":$ttl,\"proxied\":false}"
}

# Set up Unbound with DNSSEC and CA-signed certificate
echo "Configuring Unbound with DNSSEC and CA-signed certificate..."

# Backup current Unbound config
cp /etc/unbound/unbound.conf /etc/unbound/unbound.conf.bak

# Update Unbound config for DNSSEC
cat <<EOF > /etc/unbound/unbound.conf
server:
  verbosity: 1
  interface: 0.0.0.0
  access-control: 0.0.0.0/0 allow
  port: 53
  do-ip6: no
  root-hints: /var/lib/unbound/root.hints
  auto-trust-anchor-file: "/var/lib/unbound/root.key"
  logfile: "/var/log/unbound.log"
  log-time-ascii: yes
  use-syslog: yes
  log-level: 2
  cache-min-ttl: 3600
  cache-max-ttl: 86400
  edns-buffer-size: 1232
  prefetch: yes
  prefetch-key: yes
  trust-anchor-file: "/etc/unbound/trust-anchor.pem"
  include: /etc/unbound/unbound.conf.d/*.conf
EOF

# Fetch root hints and trust anchor
wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
touch /var/lib/unbound/root.key

# Dynamically fetch the CA DNSSEC trust anchor (example for Let's Encrypt)
curl -s https://letsencrypt.org/certificates/lets-encrypt-x3-cross-signed.pem > /etc/unbound/trust-anchor.pem

# Install certificate via Certbot
echo "Obtaining SSL certificate via Certbot..."

# Replace 'yourdomain.com' with your domain
certbot certonly --standalone -d $DOMAIN --agree-tos --no-eff-email --email [email protected]

# Configure NGINX to use SSL and serve Unbound DNSSEC
echo "Configuring NGINX for SSL..."

cat <<EOF > /etc/nginx/sites-available/unbound
server {
    listen 80;
    server_name $DOMAIN;

    location / {
        proxy_pass http://127.0.0.1:53;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}

server {
    listen 443 ssl;
    server_name $DOMAIN;

    ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:53;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    }
}
EOF

# Enable and start NGINX
ln -s /etc/nginx/sites-available/unbound /etc/nginx/sites-enabled/
systemctl restart nginx

# Set up Tor and configure strict routing (following script2 rules)
echo "Configuring Tor routing logic with strict mode and routing rules..."

# Backup current Tor config
cp /etc/tor/torrc /etc/tor/torrc.bak

cat <<EOF > /etc/tor/torrc
# Use the default Tor configuration
SocksPort 9050
Log notice stdout
RunAsDaemon 1
ExitNodes {us}
StrictNodes 1
ControlPort 9051
CookieAuthentication 1
DataDirectory /var/lib/tor

# Ensure all traffic routes through Tor
TransPort 9040
DNSPort 53
AutomapHostsOnResolve 1
DNSExitNode 1
EOF

# Restart Tor service
systemctl restart tor

# Set up Unbound to forward DNS queries to Tor
echo "Configuring Unbound to use Tor for DNS queries..."

# Update Unbound config to route DNS queries through Tor
cat <<EOF >> /etc/unbound/unbound.conf.d/tor.conf
forward-zone:
  name: "."
  forward-addr: 127.0.0.1@9053
EOF

# Restart Unbound
systemctl restart unbound

# Configure logs for debugging
echo "Setting up logs for debugging..."

# Create log file for Unbound
touch /var/log/unbound.log
chmod 640 /var/log/unbound.log

# Create log file for Tor
touch /var/log/tor.log
chmod 640 /var/log/tor.log

# Create log file for NGINX
touch /var/log/nginx/access.log
touch /var/log/nginx/error.log
chmod 640 /var/log/nginx/*.log

# Enable services to start on boot
systemctl enable unbound
systemctl enable tor
systemctl enable nginx

# Output success message
echo "Configuration complete. Your Unbound DNSSEC server is now running with a CA-signed certificate and Tor routing enabled."
echo "Logs for debugging are available at /var/log/unbound.log, /var/log/tor.log, and /var/log/nginx/."

# Dynamically create DNS records for your domain via Cloudflare API (A record and DS record for DNSSEC)
echo "Creating DNS records for $DOMAIN..."

# Create A record for the domain
create_dns_record "A" "$DOMAIN" "$(curl -s ifconfig.me)" 3600

# Create DS record for DNSSEC
DS_RECORD_CONTENT="your-ds-record-here"  # Replace with your actual DS record
create_dns_record "DS" "$DOMAIN" "$DS_RECORD_CONTENT" 3600

echo "DNS records created in Cloudflare. Please check your domain to confirm everything is set up."

NestedB3.sh

#!/bin/bash

# Ensure the script is running as root
if [ "$(id -u)" -ne 0 ]; then
  echo "This script must be run as root"
  exit 1
fi

# Update the system and install dependencies
apt update && apt upgrade -y
apt install -y unbound tor nginx certbot python3-certbot-nginx curl jq

# Set up Cloudflare API for DNS record management
CLOUDFLARE_API_TOKEN="your-cloudflare-api-token"
CLOUDFLARE_ZONE_ID="your-cloudflare-zone-id"
DOMAIN="yourdomain.com"

# Function to create DNS record in Cloudflare
create_dns_record() {
  local record_type=$1
  local record_name=$2
  local record_content=$3
  local ttl=$4

  curl -X POST "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records" \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data "{\"type\":\"$record_type\",\"name\":\"$record_name\",\"content\":\"$record_content\",\"ttl\":$ttl,\"proxied\":false}"
}

# Set up Unbound with DNSSEC and CA-signed certificate
echo "Configuring Unbound with DNSSEC and CA-signed certificate..."

# Backup current Unbound config
cp /etc/unbound/unbound.conf /etc/unbound/unbound.conf.bak

# Update Unbound config for DNSSEC
cat <<EOF > /etc/unbound/unbound.conf
server:
  verbosity: 1
  interface: 0.0.0.0
  access-control: 0.0.0.0/0 allow
  port: 53
  do-ip6: no
  root-hints: /var/lib/unbound/root.hints
  auto-trust-anchor-file: "/var/lib/unbound/root.key"
  logfile: "/var/log/unbound.log"
  log-time-ascii: yes
  use-syslog: yes
  log-level: 2
  cache-min-ttl: 3600
  cache-max-ttl: 86400
  edns-buffer-size: 1232
  prefetch: yes
  prefetch-key: yes
  trust-anchor-file: "/etc/unbound/trust-anchor.pem"
  include: /etc/unbound/unbound.conf.d/*.conf
EOF

# Fetch root hints and trust anchor
wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
touch /var/lib/unbound/root.key

# Dynamically fetch the CA DNSSEC trust anchor (example for Let's Encrypt)
curl -s https://letsencrypt.org/certificates/lets-encrypt-x3-cross-signed.pem > /etc/unbound/trust-anchor.pem

# Install certificate via Certbot
echo "Obtaining SSL certificate via Certbot..."

# Replace 'yourdomain.com' with your domain
certbot certonly --standalone -d $DOMAIN --agree-tos --no-eff-email --email [email protected]

# Configure NGINX to use SSL and serve Unbound DNSSEC
echo "Configuring NGINX for SSL..."

cat <<EOF > /etc/nginx/sites-available/unbound
server {
    listen 80;
    server_name $DOMAIN;

    location / {
        proxy_pass http://127.0.0.1:53;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}

server {
    listen 443 ssl;
    server_name $DOMAIN;

    ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:53;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    }
}
EOF

# Enable and start NGINX
ln -s /etc/nginx/sites-available/unbound /etc/nginx/sites-enabled/
systemctl restart nginx

# Set up Tor and configure strict routing (following script2 rules)
echo "Configuring Tor routing logic with strict mode and routing rules..."

# Backup current Tor config
cp /etc/tor/torrc /etc/tor/torrc.bak

cat <<EOF > /etc/tor/torrc
# Use the default Tor configuration
SocksPort 9050
Log notice stdout
RunAsDaemon 1
ExitNodes {us}
StrictNodes 1
ControlPort 9051
CookieAuthentication 1
DataDirectory /var/lib/tor

# Ensure all traffic routes through Tor
TransPort 9040
DNSPort 53
AutomapHostsOnResolve 1
DNSExitNode 1
EOF

# Restart Tor service
systemctl restart tor

# Set up Unbound to forward DNS queries to Tor
echo "Configuring Unbound to use Tor for DNS queries..."

# Update Unbound config to route DNS queries through Tor
cat <<EOF >> /etc/unbound/unbound.conf.d/tor.conf
forward-zone:
  name: "."
  forward-addr: 127.0.0.1@9053
EOF

# Restart Unbound
systemctl restart unbound

# Configure logs for debugging
echo "Setting up logs for debugging..."

# Create log file for Unbound
touch /var/log/unbound.log
chmod 640 /var/log/unbound.log

# Create log file for Tor
touch /var/log/tor.log
chmod 640 /var/log/tor.log

# Create log file for NGINX
touch /var/log/nginx/access.log
touch /var/log/nginx/error.log
chmod 640 /var/log/nginx/*.log

# Enable services to start on boot
systemctl enable unbound
systemctl enable tor
systemctl enable nginx

# Output success message
echo "Configuration complete. Your Unbound DNSSEC server is now running with a CA-signed certificate and Tor routing enabled."
echo "Logs for debugging are available at /var/log/unbound.log, /var/log/tor.log, and /var/log/nginx/."

# Dynamically create DNS records for your domain via Cloudflare API (A record and DS record for DNSSEC)
echo "Creating DNS records for $DOMAIN..."

# Create A record for the domain
create_dns_record "A" "$DOMAIN" "$(curl -s ifconfig.me)" 3600

# Create DS record for DNSSEC
DS_RECORD_CONTENT="your-ds-record-here"  # Replace with your actual DS record
create_dns_record "DS" "$DOMAIN" "$DS_RECORD_CONTENT" 3600

echo "DNS records created in Cloudflare. Please check your domain to confirm everything is set up."

NestedB4.sh

#!/bin/bash

# Ensure the script is running as root
if [ "$(id -u)" -ne 0 ]; then
  echo "This script must be run as root"
  exit 1
fi

# Update the system and install dependencies
apt update && apt upgrade -y
apt install -y unbound tor nginx certbot python3-certbot-nginx

# Set up Unbound with nested, ported DNSSEC (self-signed inside CA DNSSEC)
echo "Configuring Unbound with nested, encrypted DNSSEC..."

# Backup current Unbound config
cp /etc/unbound/unbound.conf /etc/unbound/unbound.conf.bak

# Update Unbound config for nested DNSSEC
cat <<EOF > /etc/unbound/unbound.conf
server:
  verbosity: 1
  interface: 0.0.0.0
  access-control: 0.0.0.0/0 allow
  port: 53
  do-ip6: no
  root-hints: /var/lib/unbound/root.hints
  auto-trust-anchor-file: "/var/lib/unbound/root.key"
  logfile: "/var/log/unbound.log"
  log-time-ascii: yes
  use-syslog: yes
  log-level: 2
  cache-min-ttl: 3600
  cache-max-ttl: 86400
  edns-buffer-size: 1232
  prefetch: yes
  prefetch-key: yes
  trust-anchor-file: "/etc/unbound/trust-anchor.pem"
  include: /etc/unbound/unbound.conf.d/*.conf

  # Local DNSSEC (Self-Signed, Encrypted and Tamper-Evident)
  # This is your local zone's DNSSEC setup, fully encrypted and tamper-evident.
  local-zone: "local." transparent
  local-data: "local. IN DS 12345 8 2 56789abcdef1234567890abcdef1234567890abcdef1234567890"
  local-data: "local. IN A 127.0.0.1"

  # Nested DNSSEC with CA Signed Setup
  # Forwarding DNS queries to Tor resolver (uses Tor's DNS port)
  forward-zone:
    name: "."
    forward-addr: 127.0.0.1@9053

  # Nested encrypted DNSSEC setup, nested into CA DNSSEC
  trust-anchor: "shp://root-anchors.dnssec"   # Here you specify your encrypted and tamper-evident DNSSEC anchor file for internal zones

EOF

# Fetch root hints and trust anchor
wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
touch /var/lib/unbound/root.key

# Install certificate via Certbot
echo "Obtaining SSL certificate via Certbot..."

# Replace 'yourdomain.com' with your domain
certbot certonly --standalone -d yourdomain.com --agree-tos --no-eff-email --email [email protected]

# Configure NGINX to use SSL and serve Unbound DNSSEC
echo "Configuring NGINX for SSL..."

cat <<EOF > /etc/nginx/sites-available/unbound
server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:53;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}

server {
    listen 443 ssl;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:53;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    }
}
EOF

# Enable and start NGINX
ln -s /etc/nginx/sites-available/unbound /etc/nginx/sites-enabled/
systemctl restart nginx

# Set up Tor and configure strict routing (following script2 rules)
echo "Configuring Tor routing logic with strict mode and routing rules..."

# Backup current Tor config
cp /etc/tor/torrc /etc/tor/torrc.bak

cat <<EOF > /etc/tor/torrc
# Use the default Tor configuration
SocksPort 9050
Log notice stdout
RunAsDaemon 1
ExitNodes {us}
StrictNodes 1
ControlPort 9051
CookieAuthentication 1
DataDirectory /var/lib/tor

# Ensure all traffic routes through Tor
TransPort 9040
DNSPort 53
AutomapHostsOnResolve 1
DNSExitNode 1
EOF

# Restart Tor service
systemctl restart tor

# Set up Unbound to forward DNS queries to Tor
echo "Configuring Unbound to use Tor for DNS queries..."

# Update Unbound config to route DNS queries through Tor
cat <<EOF >> /etc/unbound/unbound.conf.d/tor.conf
forward-zone:
  name: "."
  forward-addr: 127.0.0.1@9053
EOF

# Restart Unbound
systemctl restart unbound

# Configure logs for debugging
echo "Setting up logs for debugging..."

# Create log file for Unbound
touch /var/log/unbound.log
chmod 640 /var/log/unbound.log

# Create log file for Tor
touch /var/log/tor.log
chmod 640 /var/log/tor.log

# Create log file for NGINX
touch /var/log/nginx/access.log
touch /var/log/nginx/error.log
chmod 640 /var/log/nginx/*.log

# Enable services to start on boot
systemctl enable unbound
systemctl enable tor
systemctl enable nginx

# Output success message
echo "Configuration complete. Your Unbound DNSSEC server is now running with nested, encrypted DNSSEC and CA-signed DNSSEC enabled."
echo "Logs for debugging are available at /var/log/unbound.log, /var/log/tor.log, and /var/log/nginx/."