Merge pull request #1317 from pluswave/localdns

Feat: 增加局域网内部域名直接解析功能。
This commit is contained in:
juewuy
2026-10-24 10:25:54 +08:00
committed by GitHub
6 changed files with 186 additions and 2 deletions
+13
View File
@@ -0,0 +1,13 @@
#LAN域名 - 局域网常见域名后缀
*.lan
*.local
*.localdomain
*.home
*.internal
*.home.arpa
*.localnet
#私有网络域名示例
router.lan
nas.lan
*.home.lan
+18
View File
@@ -65,3 +65,21 @@ DNS_ADD_FAIL="添加失败"
DNS_NOW="当前DNS:"
DNS_INPUT_NEW="请直接输入新的DNS地址"
DNS_INPUT_RESET="或输入 r 重置DNS地址"
#=====直连域名=====
DNS_DIRECT_MENU="管理直连域名列表"
DNS_DIRECT_DESC="用于在 mix/route 模式下指定特定域名使用直连 DNS 解析"
DNS_DIRECT_TIP="适用于局域网域名、内网服务域名等需要本地 DNS 解析的场景"
DNS_DIRECT_EXAMPLE="示例格式:\n*.lan\n*.local\nnas.home"
DNS_DIRECT_EXIST="已添加的直连域名:"
DNS_DIRECT_EMPTY="当前尚未添加任何自定义直连域名"
DNS_DIRECT_EDIT="输入序号删除,输入 a 添加域名,输入 r 加载预设,输入 t 测试域名"
DNS_DIRECT_ADD_LAN="添加局域网域名"
DNS_DIRECT_LOAD_PRESET="加载预设局域网域名列表"
DNS_DIRECT_LOAD_OK="已加载预设局域网域名列表"
DNS_DIRECT_INPUT_HINT="请输入需要直连解析的域名(支持通配符 *.lan)"
DNS_DIRECT_TEST="测试域名解析"
DNS_DIRECT_TEST_INPUT="请输入要测试的域名"
DNS_DIRECT_TEST_RESULT="解析结果:"
DNS_DIRECT_TEST_IN_LIST="✓ 该域名已配置为直连解析"
DNS_DIRECT_TEST_NOT_IN_LIST="✗ 该域名未在直连列表中"
+18
View File
@@ -67,3 +67,21 @@ DNS_ADD_FAIL="Add failed"
DNS_NOW="Current DNS: "
DNS_INPUT_NEW="Please input a new DNS address"
DNS_INPUT_RESET="or input r to reset the DNS address"
#===== Direct DNS Domains =====
DNS_DIRECT_MENU="Manage Direct DNS Domains"
DNS_DIRECT_DESC="Specify domains to use direct DNS resolution in mix/route mode"
DNS_DIRECT_TIP="Useful for LAN domains, intranet services, etc."
DNS_DIRECT_EXAMPLE="Examples:\n*.lan\n*.local\nnas.home"
DNS_DIRECT_EXIST="Added direct DNS domains:"
DNS_DIRECT_EMPTY="No custom direct DNS domains added"
DNS_DIRECT_EDIT="Enter number to delete, 'a' to add, 'r' to load preset, 't' to test"
DNS_DIRECT_ADD_LAN="Add LAN Domain"
DNS_DIRECT_LOAD_PRESET="Load Preset LAN Domains"
DNS_DIRECT_LOAD_OK="Preset LAN domains loaded successfully"
DNS_DIRECT_INPUT_HINT="Enter domain for direct DNS resolution (supports wildcards like *.lan)"
DNS_DIRECT_TEST="Test DNS Resolution"
DNS_DIRECT_TEST_INPUT="Enter domain to test"
DNS_DIRECT_TEST_RESULT="Resolution result:"
DNS_DIRECT_TEST_IN_LIST="✓ This domain is configured for direct DNS resolution"
DNS_DIRECT_TEST_NOT_IN_LIST="✗ This domain is not in the direct DNS list"
+99
View File
@@ -25,6 +25,8 @@ set_dns_mod() {
[ "$dns_mod" = "mix" ] &&
content_line "8) \033[33m$DNS_FAKEIP_MENU\033[0m"
content_line "9) \033[36m$DNS_ADV_MENU\033[0m"
[ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ] &&
content_line "a) \033[32m$DNS_DIRECT_MENU\033[0m"
content_line ""
content_line "0) $COMMON_BACK"
separator_line "="
@@ -116,6 +118,13 @@ set_dns_mod() {
9)
set_dns_adv
;;
a)
if [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ]; then
dns_direct_domains
else
msg_alert "\033[33m直连域名功能仅在 mix/route 模式下可用!\033[0m"
fi
;;
*)
errornum
;;
@@ -172,6 +181,96 @@ fake_ip_filter() {
done
}
# 直连域名管理
dns_direct_domains() {
while true; do
comp_box "\033[32m$DNS_DIRECT_DESC\033[0m" \
"\033[36m$DNS_DIRECT_TIP\033[0m" \
"$DNS_DIRECT_EXAMPLE"
if [ -s "$CRASHDIR/configs/dns_direct_domains" ]; then
content_line "\033[33m$DNS_DIRECT_EXIST\033[0m"
content_line ""
awk '{print NR") "$1}' "$CRASHDIR/configs/dns_direct_domains" |
while IFS= read -r line; do
content_line "$line"
done
else
content_line "\033[33m$DNS_DIRECT_EMPTY\033[0m"
fi
btm_box "" \
"a) $DNS_DIRECT_ADD_LAN" \
"r) $DNS_DIRECT_LOAD_PRESET" \
"t) $DNS_DIRECT_TEST" \
"0) $COMMON_BACK"
read -r -p "$DNS_DIRECT_EDIT> " input
case "$input" in
"" | 0)
break
;;
a)
comp_box "$DNS_DIRECT_INPUT_HINT"
btm_box "1) $DNS_CONFIRM_OK" \
"0) $COMMON_BACK"
read -r -p "$DNS_INPUT> " domain
case "$domain" in
0)
continue
;;
*)
if echo "$domain" >>"$CRASHDIR/configs/dns_direct_domains"; then
msg_alert "\033[32m$DNS_ADD_OK\033[0m"
else
msg_alert "\033[31m$DNS_ADD_FAIL\033[0m"
fi
;;
esac
;;
r)
if [ -s "$CRASHDIR/public/dns_direct_domains.list" ]; then
cat "$CRASHDIR/public/dns_direct_domains.list" >>"$CRASHDIR/configs/dns_direct_domains"
msg_alert "\033[32m$DNS_DIRECT_LOAD_OK\033[0m"
else
msg_alert "\033[31m预设文件不存在!\033[0m"
fi
;;
t)
comp_box "$DNS_DIRECT_TEST_INPUT"
btm_box "1) $DNS_CONFIRM_OK" \
"0) $COMMON_BACK"
read -r -p "$DNS_INPUT> " test_domain
case "$test_domain" in
0)
continue
;;
*)
# 使用本地 DNS 解析
result=$(nslookup "$test_domain" 127.0.0.1:$dns_port 2>&1 || echo "解析失败")
comp_box "$DNS_DIRECT_TEST_RESULT" \
"$result"
# 判断是否在直连列表中
if [ -f "$CRASHDIR/configs/dns_direct_domains" ] && grep -qF "$test_domain" "$CRASHDIR/configs/dns_direct_domains"; then
content_line "\033[32m$DNS_DIRECT_TEST_IN_LIST\033[0m"
else
content_line "\033[33m$DNS_DIRECT_TEST_NOT_IN_LIST\033[0m"
fi
btm_box "0) $COMMON_BACK"
read -r -p "$COMMON_INPUT> " res
;;
esac
;;
*)
if [ "$input" -ge 1 ] 2>/dev/null; then
if sed -i "${input}d" "$CRASHDIR/configs/dns_direct_domains"; then
msg_alert "\033[32m$DNS_REMOVE_OK\033[0m"
else
msg_alert "\033[31m$DNS_REMOVE_FAIL\033[0m"
fi
fi
;;
esac
done
}
# DNS详细设置
set_dns_adv() {
while true; do
+17 -2
View File
@@ -48,12 +48,27 @@ EOF
fi
#mix模式fakeip绕过cn
[ "$dns_mod" = "mix" ] && echo ' - "rule-set:cn"' >>"$TMPDIR"/dns.yaml
#mix和route模式插入用户自定义直连域名
if [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ]; then
if [ -s "$CRASHDIR/configs/dns_direct_domains" ]; then
cat "$CRASHDIR/configs/dns_direct_domains" | grep -v '^#' | sed "s/^/ - '/" | sed "s/$/'/" >>"$TMPDIR"/dns.yaml
fi
fi
#mix模式和route模式插入分流设置
if [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ]; then
[ "$dns_protect" != "OFF" ] && dns_final="$dns_fallback" || dns_final="$dns_nameserver"
# 构建nameserver-policy
echo " respect-rules: true" >>"$TMPDIR"/dns.yaml
echo " nameserver-policy:" >>"$TMPDIR"/dns.yaml
# 添加用户自定义直连域名
if [ -s "$CRASHDIR/configs/dns_direct_domains" ]; then
cat "$CRASHDIR/configs/dns_direct_domains" | grep -v '^#' | while read domain; do
[ -n "$domain" ] && echo " '$domain': [ $dns_nameserver ]" >>"$TMPDIR"/dns.yaml
done
fi
# 添加CN规则集
echo " 'rule-set:cn': [ $dns_nameserver ]" >>"$TMPDIR"/dns.yaml
cat >>"$TMPDIR"/dns.yaml <<EOF
respect-rules: true
nameserver-policy: {'rule-set:cn': [ $dns_nameserver ]}
proxy-server-nameserver : [ $dns_proxy_server ]
nameserver: [ $dns_final ]
EOF
+21
View File
@@ -158,6 +158,15 @@ gen_dns() {
[ -n "$fake_ip_filter_domain" ] && fake_ip_filter_domain="{ \"domain\": [$fake_ip_filter_domain], \"server\": \"dns_direct\" },"
[ -n "$fake_ip_filter_suffix" ] && fake_ip_filter_suffix="{ \"domain_suffix\": [$fake_ip_filter_suffix], \"server\": \"dns_direct\" },"
[ -n "$fake_ip_filter_regex" ] && fake_ip_filter_regex="{ \"domain_regex\": [$fake_ip_filter_regex], \"server\": \"dns_direct\" },"
# 用户自定义直连域名
if [ -s "$CRASHDIR/configs/dns_direct_domains" ]; then
custom_direct_domain=$(cat "$CRASHDIR/configs/dns_direct_domains" | grep -Ev '#|\*|\+' | sed '/^\s*$/d' | awk '{printf "\"%s\", ",$1}' | sed 's/, $//')
custom_direct_suffix=$(cat "$CRASHDIR/configs/dns_direct_domains" | grep '\*' | grep -v '.\*' | sed 's/\*\.//' | awk '{printf "\"%s\", ",$1}' | sed 's/, $//')
custom_direct_regex=$(cat "$CRASHDIR/configs/dns_direct_domains" | grep '.\*' | sed 's/\./\\\\./g' | sed 's/\*/.\*/' | awk '{printf "\"%s\", ",$1}' | sed 's/, $//')
[ -n "$custom_direct_domain" ] && custom_direct_domain_rule="{ \"domain\": [$custom_direct_domain], \"server\": \"dns_direct\" },"
[ -n "$custom_direct_suffix" ] && custom_direct_suffix_rule="{ \"domain_suffix\": [$custom_direct_suffix], \"server\": \"dns_direct\" },"
[ -n "$custom_direct_regex" ] && custom_direct_regex_rule="{ \"domain_regex\": [$custom_direct_regex], \"server\": \"dns_direct\" },"
fi
proxy_dns='{ "query_type": ["A", "AAAA"], "server": "dns_fakeip", "rewrite_ttl": 1 }'
#mix模式插入fakeip过滤规则
[ "$dns_mod" = "mix" ] && direct_dns='{ "rule_set": ["cn"], "server": "dns_direct" },'
@@ -165,6 +174,15 @@ gen_dns() {
[ "$dns_mod" = "route" ] && {
global_dns=dns_proxy
direct_dns='{ "rule_set": ["cn"], "server": "dns_direct" }'
# 用户自定义直连域名
if [ -s "$CRASHDIR/configs/dns_direct_domains" ]; then
custom_direct_domain=$(cat "$CRASHDIR/configs/dns_direct_domains" | grep -Ev '#|\*|\+' | sed '/^\s*$/d' | awk '{printf "\"%s\", ",$1}' | sed 's/, $//')
custom_direct_suffix=$(cat "$CRASHDIR/configs/dns_direct_domains" | grep '\*' | grep -v '.\*' | sed 's/\*\.//' | awk '{printf "\"%s\", ",$1}' | sed 's/, $//')
custom_direct_regex=$(cat "$CRASHDIR/configs/dns_direct_domains" | grep '.\*' | sed 's/\./\\\\./g' | sed 's/\*/.\*/' | awk '{printf "\"%s\", ",$1}' | sed 's/, $//')
[ -n "$custom_direct_domain" ] && custom_direct_domain_rule="{ \"domain\": [$custom_direct_domain], \"server\": \"dns_direct\" },"
[ -n "$custom_direct_suffix" ] && custom_direct_suffix_rule="{ \"domain_suffix\": [$custom_direct_suffix], \"server\": \"dns_direct\" },"
[ -n "$custom_direct_regex" ] && custom_direct_regex_rule="{ \"domain_regex\": [$custom_direct_regex], \"server\": \"dns_direct\" },"
fi
}
#防泄露设置
[ "$dns_protect" = "OFF" ] && sed -i 's/"server": "dns_proxy"/"server": "dns_direct"/g' "$TMPDIR"/jsons/route.json
@@ -228,6 +246,9 @@ EOF
$fake_ip_filter_domain
$fake_ip_filter_suffix
$fake_ip_filter_regex
$custom_direct_domain_rule
$custom_direct_suffix_rule
$custom_direct_regex_rule
{ "clash_mode": "Global", "query_type": ["A", "AAAA"], "server": "$global_dns", "rewrite_ttl": 1 },
$direct_dns
$proxy_dns