diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..39c17642 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# Operating system files +.DS_Store +.DS_Store? +._* +Thumbs.db +Desktop.ini +$RECYCLE.BIN/ +*.stackdump + +# Editor temporary files +*.swp +*.swo +*~ +.#* + +# Workflow temporary files +bin/dashboard/.tmp/ diff --git a/public/dns_direct_domains.list b/public/dns_direct_domains.list new file mode 100644 index 00000000..5bce6e3a --- /dev/null +++ b/public/dns_direct_domains.list @@ -0,0 +1,13 @@ +#LAN域名 - 局域网常见域名后缀 +*.lan +*.local +*.localdomain +*.home +*.internal +*.home.arpa +*.localnet + +#私有网络域名示例 +router.lan +nas.lan +*.home.lan \ No newline at end of file diff --git a/scripts/lang/chs/2_settings.lang b/scripts/lang/chs/2_settings.lang index 16de3adc..5d96bd65 100644 --- a/scripts/lang/chs/2_settings.lang +++ b/scripts/lang/chs/2_settings.lang @@ -10,6 +10,7 @@ SET_MENU_SKIP_CERT="跳过证书验证:" SET_MENU_SNIFFER="启用域名嗅探:" SET_MENU_ADV_PORT="自定义端口及密钥" SET_MENU_IPV6="IPv6设置: " +SET_MENU_UDP_BUFFER="提高UDP缓冲上限(16 MiB):" SET_MENU_RESET="重置/备份/还原脚本设置" SET_MENU_LANG="多语言切换" SET_MENU_UI="UI切换" @@ -26,6 +27,9 @@ SET_SNIFFER_LOCKED="当前内核与DNS模式组合下,域名嗅探无法关闭 SET_CORE_RUNNING="检测到服务正在运行,需要先停止服务!" SET_CORE_STOP_CONFIRM="是否确认停止服务?" +SET_UDP_BUFFER_ON="已启用UDP缓冲上限优化!" +SET_UDP_BUFFER_OFF="已禁用UDP缓冲上限优化,现有系统值不会被降低。" +SET_UDP_BUFFER_RESTART="重启服务后对新连接生效。" # ================================================= # Backup / Restore / Reset diff --git a/scripts/lang/chs/dns.lang b/scripts/lang/chs/dns.lang index 2ab7aa99..6ff0bf09 100644 --- a/scripts/lang/chs/dns.lang +++ b/scripts/lang/chs/dns.lang @@ -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="✗ 该域名未在直连列表中" diff --git a/scripts/lang/en/2_settings.lang b/scripts/lang/en/2_settings.lang index 863809cc..7e69cedd 100644 --- a/scripts/lang/en/2_settings.lang +++ b/scripts/lang/en/2_settings.lang @@ -10,6 +10,7 @@ SET_MENU_SKIP_CERT="Skip Cert Verify:" SET_MENU_SNIFFER="Enable Sniff:" SET_MENU_ADV_PORT="Custom Ports and Secrets" SET_MENU_IPV6="IPv6 Settings:" +SET_MENU_UDP_BUFFER="Raise UDP Buffer Limit (16 MiB):" SET_MENU_RESET="Reset / Backup / Restore Script Settings" SET_MENU_LANG="Language" SET_MENU_UI="UI Switch" @@ -26,6 +27,9 @@ SET_SNIFFER_LOCKED="Domain sniffing cannot be disabled with the current core and SET_CORE_RUNNING="Service is currently running and must be stopped first!" SET_CORE_STOP_CONFIRM="Do you want to stop the service?" +SET_UDP_BUFFER_ON="UDP buffer limit optimization is now enabled!" +SET_UDP_BUFFER_OFF="UDP buffer limit optimization is now disabled. Existing system values will not be lowered." +SET_UDP_BUFFER_RESTART="Restart the service to apply it to new connections." # ================================================= # Backup / Restore / Reset diff --git a/scripts/lang/en/dns.lang b/scripts/lang/en/dns.lang index 4793b4e5..4e4ea6ac 100644 --- a/scripts/lang/en/dns.lang +++ b/scripts/lang/en/dns.lang @@ -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" diff --git a/scripts/libs/core_tools.sh b/scripts/libs/core_tools.sh index a0ea7e7f..684ca55d 100644 --- a/scripts/libs/core_tools.sh +++ b/scripts/libs/core_tools.sh @@ -6,10 +6,10 @@ #$1=裸二进制字节数。仅当$TMPDIR在内存(tmpfs)时裸存才省RAM; #再按$BINDIR文件系统估算裸二进制落盘体积(透明压缩fs约2:1),需留有余量($raw_margin,默认8M) store_raw_worth_it(){ - case "$(df -T "$TMPDIR" 2>/dev/null | awk 'END{print $2}')" in tmpfs|ramfs) ;; *) return 1 ;; esac - rom_free=$(df -k "$BINDIR" 2>/dev/null | awk 'END{print $4}') #KB + case "$(df -P -T "$TMPDIR" 2>/dev/null | awk 'END{print $2}')" in tmpfs|ramfs) ;; *) return 1 ;; esac + rom_free=$(df -P -k "$BINDIR" 2>/dev/null | awk 'END{print $4}') #KB [ -z "$rom_free" ] && return 1 - case "$(df -T "$BINDIR" 2>/dev/null | awk 'END{print $2}')" in + case "$(df -P -T "$BINDIR" 2>/dev/null | awk 'END{print $2}')" in squashfs|ubifs|overlay|overlayfs) est=$(( ${1:-0}/1024/2 )) ;; #透明压缩,约2:1 *) est=$(( ${1:-0}/1024 )) ;; #无压缩,全量 esac diff --git a/scripts/menus/2_settings.sh b/scripts/menus/2_settings.sh index 05758c4d..e73f45f0 100644 --- a/scripts/menus/2_settings.sh +++ b/scripts/menus/2_settings.sh @@ -16,6 +16,7 @@ settings() { echo "$crashcore" | grep -q 'singbox' && sniffer=ON } [ -z "$dns_mod" ] && dns_mod='redir_host' + [ -z "$udp_buffer" ] && udp_buffer=OFF comp_box "\033[30;47m$SET_MENU_TITLE\033[0m" content_line "1) $SET_MENU_REDIR\t\033[36m$redir_mod$MENU_MOD\033[0m" @@ -27,6 +28,7 @@ settings() { content_line "6) $SET_MENU_ADV_PORT" } content_line "7) $SET_MENU_IPV6\t\033[36m$ipv6_redir\033[0m" + content_line "8) $SET_MENU_UDP_BUFFER\t\033[36m$udp_buffer\033[0m" btm_box "" \ "a) \033[31m$SET_MENU_RESET\033[0m" \ "b) \033[36m$SET_MENU_LANG\033[0m" \ @@ -143,6 +145,18 @@ settings() { 7) set_ipv6 ;; + 8) + if [ "$udp_buffer" = "ON" ]; then + udp_buffer=OFF + msg_alert "\033[33m$SET_UDP_BUFFER_OFF\033[0m" \ + "$SET_UDP_BUFFER_RESTART" + else + udp_buffer=ON + msg_alert "\033[32m$SET_UDP_BUFFER_ON\033[0m" \ + "$SET_UDP_BUFFER_RESTART" + fi + setconfig udp_buffer "$udp_buffer" + ;; a) BACK_TAR="$CRASHDIR/configs.tar.gz" comp_box "1) $SET_BACKUP" \ diff --git a/scripts/menus/dns.sh b/scripts/menus/dns.sh index 72b0491a..b2464d44 100644 --- a/scripts/menus/dns.sh +++ b/scripts/menus/dns.sh @@ -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 diff --git a/scripts/starts/bfstart.sh b/scripts/starts/bfstart.sh index ce8450f8..1d0fe229 100644 --- a/scripts/starts/bfstart.sh +++ b/scripts/starts/bfstart.sh @@ -23,6 +23,24 @@ [ -z "$redir_mod" ] && firewall_area='4' routing_mark=$((fwmark + 2)) +set_udp_buffer_limit() { + [ "$udp_buffer" = "ON" ] || return 0 + + udp_buffer_limit=16777216 + #同时提高上限与默认值:部分Mihomo/quic-go构建不显式setsockopt,仅继承default + for udp_buffer_file in /proc/sys/net/core/rmem_max /proc/sys/net/core/wmem_max \ + /proc/sys/net/core/rmem_default /proc/sys/net/core/wmem_default; do + [ -w "$udp_buffer_file" ] || continue + udp_buffer_current=$(cat "$udp_buffer_file" 2>/dev/null) + case "$udp_buffer_current" in + '' | *[!0-9]*) continue ;; + esac + [ "$udp_buffer_current" -lt "$udp_buffer_limit" ] && + printf '%s\n' "$udp_buffer_limit" >"$udp_buffer_file" + done + unset udp_buffer_limit udp_buffer_file udp_buffer_current +} + makehtml() { #生成面板跳转文件 cat >"$BINDIR"/ui/index.html < @@ -78,6 +96,8 @@ EOF [ "$network_check" != "OFF" ] && [ ! -f "$TMPDIR"/crash_start_time ] && ckcmd ping && . "$CRASHDIR"/starts/check_network.sh && check_network [ ! -d "$BINDIR"/ui ] && mkdir -p "$BINDIR"/ui [ -z "$crashcore" ] && crashcore=meta +#按需提高UDP套接字缓冲上限,改善Hysteria2等QUIC协议的吞吐 +set_udp_buffer_limit #执行条件任务 [ -s "$TASKCFGDIR"/bfstart ] && . "$TASKCFGDIR"/bfstart #检查内核配置文件 diff --git a/scripts/starts/clash_modify.sh b/scripts/starts/clash_modify.sh index 493c0e20..b67a0330 100644 --- a/scripts/starts/clash_modify.sh +++ b/scripts/starts/clash_modify.sh @@ -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 <