DNS Self Healing Setup Guide
How install DNS masq on Ubuntu
ssh connection
resolv.conf configuration
DNSmasq configuration
sudo vim /etc/dnsmasq.conf
# Listen on loopback and the physical interface
interface=lo
interface=eth0
local-service
# 2. Security & Leak Prevention
# Prevent ISP DNS from leaking in through /etc/resolv.conf
no-resolv
# Force dnsmasq to follow your rule order (vital for proxying)
strict-order
# 3. Performance
cache-size=5000
no-negcache
# Verify DNSSEC if your upstream supports it
proxy-dnssec
# 4. LAN & Domain logic
expand-hosts
domain=lan
no-hosts
# Logging (optional — logs go to journal/syslog by default)
log-queries
log-facility=/var/log/dnsmasq.log
# --- EXTERNAL CONFIGS ---
conf-dir=/etc/dnsmasq.d/,*.conf
## restarts DNSmasq and systemd-resolved
```bash
sudo systemctl restart systemd-resolved
sudo systemctl restart dnsmasq
Create the Split-DNS File
sudo vim /etc/dnsmasq.d/99-split-dns.conf
# --- STRATEGY A: High Security (Proxy via Cloudflared/Nekobox) ---
# Use this for blocked or restricted services
server=/youtube.com/127.0.0.1#5053
server=/googlevideo.com/127.0.0.1#5053
server=/ytimg.com/127.0.0.1#5053
server=/ggpht.com/127.0.0.1#5053
server=/gstatic.com/127.0.0.1#5053
server=/googleapis.com/127.0.0.1#5053
server=/instagram.com/1.0.0.1
server=/instagram.com/1.1.1.1
server=/static.cdninstagram.com/1.1.1.1
server=/scontent.cdninstagram.com/1.0.0.1
# --- STRATEGY B: Content Unblocking (Shecan/403.online) ---
# Use this for developer tools that block your IP (Docker/Copilot)
server=/shecan.ir/178.22.122.100
server=/docker.com/178.22.122.100
server=/githubcopilot.com/178.22.122.100
server=/notebooklm.google.com/178.22.122.100
server=/gemini.google.com/178.22.122.100
# --- STRATEGY C: Regional/Local (Direct) ---
# Use standard Google DNS for local .ir domains to ensure speed
server=/ir/8.8.8.8
server=/ir/8.8.4.4
# --- STRATEGY D: Global Fallback ---
# If no rule matches, try these in order
server=1.1.1.1
server=8.8.8.8
Disable systemd-resolved to avoid conflicts
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
sudo systemctl restart dnsmasq
UFW Firewall configuration
# Allow DNS over both UDP and TCP
sudo ufw allow 22/tcp
sudo ufw allow 53/tcp
sudo ufw reload
sudo ufw enable
sudo ufw reload
sudo ufw reload
sudo ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
53/tcp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
dynamic_redirects
for running DOH you need a VPN or Proxy like proxychains installed on your server. because cloudflare-dns.com is blocked in some countries.
sudo touch /etc/dnsmasq.d/dynamic_redirects.conf
#!/bin/bash
# Configuration
LOG_FILE="/var/log/dnsmasq.log"
CONF_FILE="/etc/dnsmasq.d/dynamic_redirects.conf"
TARGET_IP="10.10.34.35" # 10.10.34.36
# 1. Extract unique domains that resolved to the target IP from the log
DOMAINS=$(sudo grep "is $TARGET_IP" "$LOG_FILE" | awk '{print $6}' | sort -u)
if [ -z "$DOMAINS" ]; then
echo "No domains found resolving to $TARGET_IP in logs."
exit 0
fi
echo "Found domains to fix: "
echo "$DOMAINS"
echo "------------------------------"
# 2. Clear the dynamic config file or prepare it
# > "$CONF_FILE" # Uncomment if you want to wipe the file and start fresh each time
for DOMAIN in $DOMAINS; do
echo -n "Fetching real IP for $DOMAIN... "
# 3. Fetch real IP via DoH (using proxychains as per your setup)
RESPONSE=$(proxychains curl -H "accept: application/dns-json" "https://cloudflare-dns.com/dns-query?name=$DOMAIN&type=A")
# 4. Extract IP
REAL_IP=$(echo "$RESPONSE" | jq -r '.Answer[] | select(.type==1) | .data' | head -n 1)
if [ -n "$REAL_IP" ] && [ "$REAL_IP" != "null" ]; then
# 5. Update the dnsmasq config
# Remove old entry if it exists and append the new one
sudo sed -i "/address=\/$DOMAIN\//d" "$CONF_FILE" 2>/dev/null
echo "address=/$DOMAIN/$REAL_IP" | sudo tee -a "$CONF_FILE" > /dev/null
echo "DONE ($REAL_IP)"
else
echo "FAILED (No record found)"
fi
done
# 6. Reload dnsmasq
sudo systemctl restart dnsmasq
echo "------------------------------"
echo "Dnsmasq reloaded with real IP addresses."
DOH
1. Download and Install:
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb
2. Create a Manual Systemd Service:
Since we only need a DNS proxy (not a web tunnel), we create a custom service to listen on port 5053.
Paste the following:
[Unit]
Description=Cloudflare DNS over HTTPS Proxy (via Nekobox)
After=network.target
[Service]
# We remove proxychains and use environment variables instead
# Nekobox is listening on 127.0.0.1:2080 as an HTTP/SOCKS proxy
Environment="HTTPS_PROXY=http://127.0.0.1:2080"
Environment="HTTP_PROXY=http://127.0.0.1:2080"
# Note: We use the direct path to cloudflared without the proxychains prefix
ExecStart=/usr/local/bin/cloudflared proxy-dns --port 5053 --upstream https://1.1.1.1/dns-query --upstream https://8.8.8.8/dns-query
Restart=always
User=root
[Install]
WantedBy=multi-user.target
3. Start the Bridge:
sudo systemctl daemon-reload
sudo systemctl enable cloudflared-doh
sudo systemctl start cloudflared-doh
v2ray Config
{
"log": {
"loglevel": "warning",
"dnsLog": true
},
"dns": {
"tag": "dns-internal",
"servers": [
"tcp://YOUR_SERVER_IP:53"
]
},
"inbounds": [
{
"protocol": "socks",
"tag": "socks-in",
"port": 10808,
"listen": "0.0.0.0",
"settings": { "udp": true },
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct",
"settings": { "domainStrategy": "UseIP" }
},
{
"protocol": "dns",
"tag": "dns-out"
}
],
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"inboundTag": ["dns-internal"],
"outboundTag": "direct"
},
{
"type": "field",
"port": 53,
"outboundTag": "dns-out"
}
]
}
}
Tips
Enable DOH on chorome extensions settings for better results.