mirror of
https://github.com/andrey271192/Keenetic-Split-DNS.git
synced 2026-09-20 11:55:36 +00:00
149 lines
4.3 KiB
Bash
Executable File
149 lines
4.3 KiB
Bash
Executable File
#!/bin/sh
|
|
# YAML config -> SmartDNS conf + domain sets + lighttpd bind
|
|
|
|
set -e
|
|
|
|
KSD_ETC="${KSD_ETC:-/opt/etc/keenetic-split-dns}"
|
|
KSD_SHARE="${KSD_SHARE:-/opt/share/keenetic-split-dns}"
|
|
CONFIG="${KSD_ETC}/config.yaml"
|
|
OUT_SMART="${KSD_ETC}/smartdns.conf"
|
|
OUT_LIGHT="${KSD_ETC}/lighttpd.conf"
|
|
DOMAIN_DIR="${KSD_ETC}/domain-sets"
|
|
HEAD="${KSD_SHARE}/smartdns/smartdns.conf.head"
|
|
|
|
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname "$0")" && pwd)"
|
|
DETECT="${SCRIPT_DIR}/detect-lan.sh"
|
|
|
|
[ -f "$CONFIG" ] || { echo "Missing $CONFIG" >&2; exit 1; }
|
|
mkdir -p "$DOMAIN_DIR" "$(dirname "$OUT_SMART")"
|
|
|
|
# --- simple YAML getters (key: value / nested under upstreams:) ---
|
|
yaml_val() {
|
|
key="$1"
|
|
awk -v k="$key" '
|
|
$0 ~ "^" k ": " {
|
|
v = $0; sub("^" k ": ", "", v)
|
|
gsub(/^["'\'']|["'\'']$/, "", v)
|
|
print v; exit
|
|
}
|
|
' "$CONFIG"
|
|
}
|
|
|
|
yaml_upstream_field() {
|
|
uid="$1"
|
|
field="$2"
|
|
awk -v id="$uid" -v f="$field" '
|
|
$0 ~ "^ " id ":$" { inb=1; next }
|
|
inb && $0 ~ "^ [a-zA-Z0-9_-]+:$" { exit }
|
|
inb && $0 ~ "^ " f ": " {
|
|
v=$0; sub("^ " f ": ", "", v)
|
|
gsub(/^["'\'']|["'\'']$/, "", v)
|
|
print v; exit
|
|
}
|
|
' "$CONFIG"
|
|
}
|
|
|
|
yaml_group_field() {
|
|
gid="$1"
|
|
field="$2"
|
|
awk -v id="$gid" -v f="$field" '
|
|
$0 ~ "^ " id ":$" { inb=1; next }
|
|
inb && $0 ~ "^ [a-zA-Z0-9_-]+:$" { exit }
|
|
inb && $0 ~ "^ " f ": " {
|
|
v=$0; sub("^ " f ": ", "", v)
|
|
gsub(/^["'\'']|["'\'']$/, "", v)
|
|
print v; exit
|
|
}
|
|
' "$CONFIG"
|
|
}
|
|
|
|
LAN_IP="$(yaml_val lan_ip)"
|
|
[ -n "$LAN_IP" ] || LAN_IP="$("$DETECT" lan)"
|
|
WEB_PORT="$(yaml_val web_port)"
|
|
[ -n "$WEB_PORT" ] || WEB_PORT="3200"
|
|
DNS_PORT="$(yaml_val dns_port)"
|
|
[ -n "$DNS_PORT" ] || DNS_PORT="53"
|
|
DNS_LISTEN="$(yaml_val dns_listen)"
|
|
[ -n "$DNS_LISTEN" ] || DNS_LISTEN="0.0.0.0"
|
|
CACHE_TTL="$(yaml_val cache_ttl_max)"
|
|
[ -n "$CACHE_TTL" ] || CACHE_TTL="3600"
|
|
DEFAULT_UP="$(yaml_val default_upstream)"
|
|
[ -n "$DEFAULT_UP" ] || DEFAULT_UP="isp-default"
|
|
LOG_Q="$(yaml_val log_queries)"
|
|
|
|
# --- SmartDNS header ---
|
|
{
|
|
[ -f "$HEAD" ] && cat "$HEAD"
|
|
echo "bind ${DNS_LISTEN}:${DNS_PORT}"
|
|
echo "cache-persist no"
|
|
echo "rr-ttl-max ${CACHE_TTL}"
|
|
if [ "$LOG_Q" = "true" ] || [ "$LOG_Q" = "1" ]; then
|
|
echo "log-file /opt/var/log/keenetic-split-dns/smartdns.log"
|
|
echo "log-size 256k"
|
|
fi
|
|
echo ""
|
|
} > "$OUT_SMART"
|
|
|
|
# --- upstream servers ---
|
|
list_upstream_ids() {
|
|
awk '/^upstreams:$/,/^[^ ]/ { if ($0 ~ /^ [a-zA-Z0-9_-]+:$/) { gsub(/:$/,"",$1); print substr($1,3) } }' "$CONFIG" | head -20
|
|
}
|
|
|
|
for uid in $(list_upstream_ids); do
|
|
typ="$(yaml_upstream_field "$uid" type)"
|
|
addr="$(yaml_upstream_field "$uid" address)"
|
|
port="$(yaml_upstream_field "$uid" port)"
|
|
sni="$(yaml_upstream_field "$uid" sni)"
|
|
[ -n "$port" ] || port="53"
|
|
|
|
case "$typ" in
|
|
dot)
|
|
host="${sni:-$addr}"
|
|
echo "server-tls ${host} -address ${addr}:${port} -host-name ${host} -group ${uid} -no-check-certificate" >> "$OUT_SMART"
|
|
;;
|
|
doh)
|
|
url="$(yaml_upstream_field "$uid" url)"
|
|
[ -n "$url" ] || url="https://${addr}/dns-query"
|
|
echo "server-https ${url} -group ${uid}" >> "$OUT_SMART"
|
|
;;
|
|
*)
|
|
if [ "$addr" = "auto" ]; then
|
|
addr="$("$DETECT" isp)"
|
|
fi
|
|
echo "server ${addr}:${port} -group ${uid}" >> "$OUT_SMART"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
echo "" >> "$OUT_SMART"
|
|
|
|
# --- domain groups ---
|
|
list_group_ids() {
|
|
awk '/^domain_groups:$/,/^[^ ]/ { if ($0 ~ /^ [a-zA-Z0-9_-]+:$/) { gsub(/:$/,"",$1); print substr($1,3) } }' "$CONFIG"
|
|
}
|
|
|
|
for gid in $(list_group_ids); do
|
|
upstream="$(yaml_group_field "$gid" upstream)"
|
|
dset="$(yaml_group_field "$gid" domain_set)"
|
|
[ -n "$dset" ] || dset="${gid}.txt"
|
|
dpath="${DOMAIN_DIR}/${dset}"
|
|
if [ ! -f "$dpath" ] && [ -f "${KSD_SHARE}/domain-sets/${dset}" ]; then
|
|
cp "${KSD_SHARE}/domain-sets/${dset}" "$dpath"
|
|
fi
|
|
[ -f "$dpath" ] || continue
|
|
echo "domain-set -name ${gid} -file ${dpath}" >> "$OUT_SMART"
|
|
echo "domain-rules /domain-set:${gid}/ -nameserver ${upstream} -speed-check-mode none" >> "$OUT_SMART"
|
|
done
|
|
|
|
echo "nameserver ${DEFAULT_UP}" >> "$OUT_SMART"
|
|
echo "default-nameserver ${DEFAULT_UP}" >> "$OUT_SMART"
|
|
|
|
# --- lighttpd ---
|
|
LIGHT_SRC="${KSD_SHARE}/lighttpd/lighttpd.conf"
|
|
if [ -f "$LIGHT_SRC" ]; then
|
|
sed "s/LAN_IP_PLACEHOLDER/${LAN_IP}/g; s/server.port = 3200/server.port = ${WEB_PORT}/" "$LIGHT_SRC" > "$OUT_LIGHT"
|
|
fi
|
|
|
|
echo "Compiled: $OUT_SMART"
|
|
exit 0
|