Files
Keenetic-Split-DNS/scripts/compile-config.sh
Андрей Бобырев bc9355fe40 Initial release: install, uninstall, SmartDNS, web UI
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 22:15:37 +03:00

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