diff --git a/luci-app-passwall/root/usr/share/passwall/app.sh b/luci-app-passwall/root/usr/share/passwall/app.sh index ba0bdadc8..8a18ffabb 100755 --- a/luci-app-passwall/root/usr/share/passwall/app.sh +++ b/luci-app-passwall/root/usr/share/passwall/app.sh @@ -328,6 +328,33 @@ lua_api() { echo $(lua -e "local api = require 'luci.passwall.api' print(api.${func})") } +parse_doh() { + local __doh=$1 __url_var=$2 __host_var=$3 __port_var=$4 __bootstrap_var=$5 + __doh=$(echo -e "$__doh" | tr -d ' \t\n') + local __url=${__doh%%,*} + local __bootstrap=${__doh#*,} + local __host_port=$(lua_api "get_domain_from_url(\"${__url}\")") + local __host __port + if echo "${__host_port}" | grep -q '^\[.*\]:[0-9]\+$'; then + __host=${__host_port%%]:*}] + __port=${__host_port##*:} + elif echo "${__host_port}" | grep -q ':[0-9]\+$'; then + __host=${__host_port%:*} + __port=${__host_port##*:} + else + __host=${__host_port} + __port=443 + fi + __host=${__host#[} + __host=${__host%]} + if [ "$(lua_api "is_ip(\"${__host}\")")" = "true" ]; then + __bootstrap=${__host} + fi + __bootstrap=${__bootstrap#[} + __bootstrap=${__bootstrap%]} + eval "${__url_var}='${__url}' ${__host_var}='${__host}' ${__port_var}='${__port}' ${__bootstrap_var}='${__bootstrap}'" +} + run_ipt2socks() { local flag proto tcp_tproxy local_port socks_address socks_port socks_username socks_password log_file local _extra_param="" @@ -422,15 +449,8 @@ run_singbox() { _extra_param="${_extra_param} -remote_dns_server ${_dns_address} -remote_dns_port ${_dns_port} -remote_dns_tcp_server tcp://${_dns}" ;; doh) - local _doh_url=$(echo $remote_dns_doh | awk -F ',' '{print $1}') - local _doh_host_port=$(lua_api "get_domain_from_url(\"${_doh_url}\")") - #local _doh_host_port=$(echo $_doh_url | sed "s/https:\/\///g" | awk -F '/' '{print $1}') - local _doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}') - local is_ip=$(lua_api "is_ip(\"${_doh_host}\")") - local _doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}') - [ -z "${_doh_port}" ] && _doh_port=443 - local _doh_bootstrap=$(echo $remote_dns_doh | cut -d ',' -sf 2-) - [ "${is_ip}" = "true" ] && _doh_bootstrap=${_doh_host} + local _doh_url _doh_host _doh_port _doh_bootstrap + parse_doh "$remote_dns_doh" _doh_url _doh_host _doh_port _doh_bootstrap [ -n "$_doh_bootstrap" ] && _extra_param="${_extra_param} -remote_dns_server ${_doh_bootstrap}" _extra_param="${_extra_param} -remote_dns_port ${_doh_port} -remote_dns_doh_url ${_doh_url} -remote_dns_doh_host ${_doh_host}" ;; @@ -481,15 +501,8 @@ run_xray() { _extra_param="${_extra_param} -remote_dns_tcp_server ${_dns_address} -remote_dns_tcp_port ${_dns_port}" } [ -n "${remote_dns_doh}" ] && { - local _doh_url=$(echo $remote_dns_doh | awk -F ',' '{print $1}') - local _doh_host_port=$(lua_api "get_domain_from_url(\"${_doh_url}\")") - #local _doh_host_port=$(echo $_doh_url | sed "s/https:\/\///g" | awk -F '/' '{print $1}') - local _doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}') - local is_ip=$(lua_api "is_ip(\"${_doh_host}\")") - local _doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}') - [ -z "${_doh_port}" ] && _doh_port=443 - local _doh_bootstrap=$(echo $remote_dns_doh | cut -d ',' -sf 2-) - [ "${is_ip}" = "true" ] && _doh_bootstrap=${_doh_host} + local _doh_url _doh_host _doh_port _doh_bootstrap + parse_doh "$remote_dns_doh" _doh_url _doh_host _doh_port _doh_bootstrap [ -n "$_doh_bootstrap" ] && _extra_param="${_extra_param} -remote_dns_doh_ip ${_doh_bootstrap}" _extra_param="${_extra_param} -remote_dns_doh_port ${_doh_port} -remote_dns_doh_url ${_doh_url} -remote_dns_doh_host ${_doh_host}" } @@ -1436,16 +1449,9 @@ start_dns() { _args="${_args} remote_dns_doh=${remote_dns_doh}" echolog " - Sing-Box DNS(${TUN_DNS}) -> ${remote_dns_doh}" - local _doh_url=$(echo $remote_dns_doh | awk -F ',' '{print $1}') - local _doh_host_port=$(lua_api "get_domain_from_url(\"${_doh_url}\")") - local _doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}') - local _is_ip=$(lua_api "is_ip(\"${_doh_host}\")") - local _doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}') - [ -z "${_doh_port}" ] && _doh_port=443 - local _doh_bootstrap=$(echo $remote_dns_doh | cut -d ',' -sf 2-) - [ "${_is_ip}" = "true" ] && _doh_bootstrap=${_doh_host} - [ -n "${_doh_bootstrap}" ] && REMOTE_DNS=${_doh_bootstrap}:${_doh_port} - unset _doh_url _doh_host_port _doh_host _is_ip _doh_port _doh_bootstrap + local _doh_url _doh_host _doh_port _doh_bootstrap + parse_doh "$remote_dns_doh" _doh_url _doh_host _doh_port _doh_bootstrap + [ -n "${_doh_bootstrap}" ] && REMOTE_DNS="${_doh_bootstrap}#${_doh_port}" ;; esac _args="${_args} dns_socks_address=127.0.0.1 dns_socks_port=${tcp_node_socks_port}" @@ -1473,16 +1479,9 @@ start_dns() { _args="${_args} remote_dns_doh=${remote_dns_doh}" echolog " - Xray DNS(${TUN_DNS}) -> (${remote_dns_doh})(A/AAAA) + tcp://${REMOTE_DNS}" - local _doh_url=$(echo $remote_dns_doh | awk -F ',' '{print $1}') - local _doh_host_port=$(lua_api "get_domain_from_url(\"${_doh_url}\")") - local _doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}') - local _is_ip=$(lua_api "is_ip(\"${_doh_host}\")") - local _doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}') - [ -z "${_doh_port}" ] && _doh_port=443 - local _doh_bootstrap=$(echo $remote_dns_doh | cut -d ',' -sf 2-) - [ "${_is_ip}" = "true" ] && _doh_bootstrap=${_doh_host} - [ -n "${_doh_bootstrap}" ] && REMOTE_DNS=${REMOTE_DNS},${_doh_bootstrap}:${_doh_port} - unset _doh_url _doh_host_port _doh_host _is_ip _doh_port _doh_bootstrap + local _doh_url _doh_host _doh_port _doh_bootstrap + parse_doh "$remote_dns_doh" _doh_url _doh_host _doh_port _doh_bootstrap + [ -n "${_doh_bootstrap}" ] && REMOTE_DNS="${REMOTE_DNS},${_doh_bootstrap}#${_doh_port}" else echolog " - Xray DNS(${TUN_DNS}) -> tcp://${REMOTE_DNS}" fi diff --git a/luci-app-passwall/root/usr/share/passwall/iptables.sh b/luci-app-passwall/root/usr/share/passwall/iptables.sh index 4ae56cb9e..c77084d5b 100755 --- a/luci-app-passwall/root/usr/share/passwall/iptables.sh +++ b/luci-app-passwall/root/usr/share/passwall/iptables.sh @@ -1011,18 +1011,29 @@ add_firewall_rule() { if [ "$TCP_NODE" != "nil" ]; then _proxy_tcp_access() { [ -n "${2}" ] || return 0 - ipset -q test $IPSET_LANLIST ${2} - [ $? -eq 0 ] && { - echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 TCP 代理转发对该服务器 TCP/${3} 端口的访问" - return 0 - } - if [ -z "${is_tproxy}" ]; then - $ipt_n -I PSW_OUTPUT -p tcp -d ${2} --dport ${3} $(REDIRECT $TCP_REDIR_PORT) + if echo "${2}" | grep -q -v ':'; then + ipset -q test $IPSET_LANLIST ${2} + [ $? -eq 0 ] && { + echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 TCP 代理转发对该服务器 TCP/${3} 端口的访问" + return 0 + } + if [ -z "${is_tproxy}" ]; then + $ipt_n -I PSW_OUTPUT -p tcp -d ${2} --dport ${3} $(REDIRECT $TCP_REDIR_PORT) + else + $ipt_m -I PSW_OUTPUT -p tcp -d ${2} --dport ${3} -j PSW_RULE + $ipt_m -I PSW $(comment "本机") -p tcp -i lo -d ${2} --dport ${3} $(REDIRECT $TCP_REDIR_PORT TPROXY) + fi + echolog " - [$?]将上游 DNS 服务器 ${2}:${3} 加入到路由器自身代理的 TCP 转发链" else - $ipt_m -I PSW_OUTPUT -p tcp -d ${2} --dport ${3} -j PSW_RULE - $ipt_m -I PSW $(comment "本机") -p tcp -i lo -d ${2} --dport ${3} $(REDIRECT $TCP_REDIR_PORT TPROXY) + ipset -q test $IPSET_LANLIST6 ${2} + [ $? -eq 0 ] && { + echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 TCP 代理转发对该服务器 TCP/${3} 端口的访问" + return 0 + } + $ip6t_m -I PSW_OUTPUT -p tcp -d ${2} --dport ${3} -j PSW_RULE + $ip6t_m -I PSW $(comment "本机") -p tcp -i lo -d ${2} --dport ${3} $(REDIRECT $TCP_REDIR_PORT TPROXY) + echolog " - [$?]将上游 DNS 服务器 [${2}]:${3} 加入到路由器自身代理的 TCP 转发链,请确保您的节点支持IPv6,并开启IPv6透明代理!" fi - echolog " - [$?]将上游 DNS 服务器 ${2}:${3} 加入到路由器自身代理的 TCP 转发链" } [ "$use_tcp_node_resolve_dns" == 1 ] && hosts_foreach REMOTE_DNS _proxy_tcp_access 53 @@ -1087,14 +1098,25 @@ add_firewall_rule() { if [ "$UDP_NODE" != "nil" -o "$TCP_UDP" = "1" ]; then _proxy_udp_access() { [ -n "${2}" ] || return 0 - ipset -q test $IPSET_LANLIST ${2} - [ $? == 0 ] && { - echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 UDP 代理转发对该服务器 UDP/${3} 端口的访问" - return 0 - } - $ipt_m -I PSW_OUTPUT -p udp -d ${2} --dport ${3} -j PSW_RULE - $ipt_m -I PSW $(comment "本机") -p udp -i lo -d ${2} --dport ${3} $(REDIRECT $UDP_REDIR_PORT TPROXY) - echolog " - [$?]将上游 DNS 服务器 ${2}:${3} 加入到路由器自身代理的 UDP 转发链" + if echo "${2}" | grep -q -v ':'; then + ipset -q test $IPSET_LANLIST ${2} + [ $? == 0 ] && { + echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 UDP 代理转发对该服务器 UDP/${3} 端口的访问" + return 0 + } + $ipt_m -I PSW_OUTPUT -p udp -d ${2} --dport ${3} -j PSW_RULE + $ipt_m -I PSW $(comment "本机") -p udp -i lo -d ${2} --dport ${3} $(REDIRECT $UDP_REDIR_PORT TPROXY) + echolog " - [$?]将上游 DNS 服务器 ${2}:${3} 加入到路由器自身代理的 UDP 转发链" + else + ipset -q test $IPSET_LANLIST6 ${2} + [ $? == 0 ] && { + echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 UDP 代理转发对该服务器 UDP/${3} 端口的访问" + return 0 + } + $ip6t_m -I PSW_OUTPUT -p udp -d ${2} --dport ${3} -j PSW_RULE + $ip6t_m -I PSW $(comment "本机") -p udp -i lo -d ${2} --dport ${3} $(REDIRECT $UDP_REDIR_PORT TPROXY) + echolog " - [$?]将上游 DNS 服务器 [${2}]:${3} 加入到路由器自身代理的 UDP 转发链,请确保您的节点支持IPv6,并开启IPv6透明代理!" + fi } [ "$use_udp_node_resolve_dns" == 1 ] && hosts_foreach REMOTE_DNS _proxy_udp_access 53 diff --git a/luci-app-passwall/root/usr/share/passwall/nftables.sh b/luci-app-passwall/root/usr/share/passwall/nftables.sh index bb4387420..e30b79a80 100755 --- a/luci-app-passwall/root/usr/share/passwall/nftables.sh +++ b/luci-app-passwall/root/usr/share/passwall/nftables.sh @@ -1088,18 +1088,29 @@ add_firewall_rule() { if [ "$TCP_NODE" != "nil" ]; then _proxy_tcp_access() { [ -n "${2}" ] || return 0 - nft "get element $NFTABLE_NAME $NFTSET_LANLIST {${2}}" &>/dev/null - [ $? -eq 0 ] && { - echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 TCP 代理转发对该服务器 TCP/${3} 端口的访问" - return 0 - } - if [ -z "${is_tproxy}" ]; then - nft insert rule $NFTABLE_NAME PSW_OUTPUT_NAT ip protocol tcp ip daddr ${2} tcp dport ${3} $(REDIRECT $TCP_REDIR_PORT) + if echo "${2}" | grep -q -v ':'; then + nft "get element $NFTABLE_NAME $NFTSET_LANLIST {${2}}" &>/dev/null + [ $? -eq 0 ] && { + echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 TCP 代理转发对该服务器 TCP/${3} 端口的访问" + return 0 + } + if [ -z "${is_tproxy}" ]; then + nft insert rule $NFTABLE_NAME PSW_OUTPUT_NAT ip protocol tcp ip daddr ${2} tcp dport ${3} $(REDIRECT $TCP_REDIR_PORT) + else + nft insert rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol tcp ip daddr ${2} tcp dport ${3} counter jump PSW_RULE + nft insert rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp iif lo tcp dport ${3} ip daddr ${2} $(REDIRECT $TCP_REDIR_PORT TPROXY4) comment \"本机\" + fi + echolog " - [$?]将上游 DNS 服务器 ${2}:${3} 加入到路由器自身代理的 TCP 转发链" else - nft insert rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol tcp ip daddr ${2} tcp dport ${3} counter jump PSW_RULE - nft insert rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp iif lo tcp dport ${3} ip daddr ${2} $(REDIRECT $TCP_REDIR_PORT TPROXY4) comment \"本机\" + nft "get element $NFTABLE_NAME $NFTSET_LANLIST6 {${2}}" &>/dev/null + [ $? -eq 0 ] && { + echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 TCP 代理转发对该服务器 TCP/${3} 端口的访问" + return 0 + } + nft "insert rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr ${2} tcp dport ${3} counter jump PSW_RULE" + nft "insert rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp iif lo tcp dport ${3} ip6 daddr ${2} $(REDIRECT $TCP_REDIR_PORT TPROXY6) comment \"本机\"" + echolog " - [$?]将上游 DNS 服务器 [${2}]:${3} 加入到路由器自身代理的 TCP 转发链,请确保您的节点支持IPv6,并开启IPv6透明代理!" fi - echolog " - [$?]将上游 DNS 服务器 ${2}:${3} 加入到路由器自身代理的 TCP 转发链" } [ "$use_tcp_node_resolve_dns" == 1 ] && hosts_foreach REMOTE_DNS _proxy_tcp_access 53 @@ -1163,14 +1174,25 @@ add_firewall_rule() { if [ "$UDP_NODE" != "nil" -o "$TCP_UDP" = "1" ]; then _proxy_udp_access() { [ -n "${2}" ] || return 0 - nft "get element $NFTABLE_NAME $NFTSET_LANLIST {${2}}" &>/dev/null - [ $? == 0 ] && { - echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 UDP 代理转发对该服务器 UDP/${3} 端口的访问" - return 0 - } - nft "insert rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr ${2} udp dport ${3} counter jump PSW_RULE" - nft "insert rule $NFTABLE_NAME PSW_MANGLE ip protocol udp iif lo ip daddr ${2} $(REDIRECT $UDP_REDIR_PORT TPROXY4) comment \"本机\"" - echolog " - [$?]将上游 DNS 服务器 ${2}:${3} 加入到路由器自身代理的 UDP 转发链" + if echo "${2}" | grep -q -v ':'; then + nft "get element $NFTABLE_NAME $NFTSET_LANLIST {${2}}" &>/dev/null + [ $? == 0 ] && { + echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 UDP 代理转发对该服务器 UDP/${3} 端口的访问" + return 0 + } + nft "insert rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr ${2} udp dport ${3} counter jump PSW_RULE" + nft "insert rule $NFTABLE_NAME PSW_MANGLE ip protocol udp iif lo ip daddr ${2} $(REDIRECT $UDP_REDIR_PORT TPROXY4) comment \"本机\"" + echolog " - [$?]将上游 DNS 服务器 ${2}:${3} 加入到路由器自身代理的 UDP 转发链" + else + nft "get element $NFTABLE_NAME $NFTSET_LANLIST6 {${2}}" &>/dev/null + [ $? == 0 ] && { + echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 UDP 代理转发对该服务器 UDP/${3} 端口的访问" + return 0 + } + nft "insert rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr ${2} udp dport ${3} counter jump PSW_RULE" + nft "insert rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp iif lo ip6 daddr ${2} $(REDIRECT $UDP_REDIR_PORT TPROXY6) comment \"本机\"" + echolog " - [$?]将上游 DNS 服务器 [${2}]:${3} 加入到路由器自身代理的 UDP 转发链,请确保您的节点支持IPv6,并开启IPv6透明代理!" + fi } [ "$use_udp_node_resolve_dns" == 1 ] && hosts_foreach REMOTE_DNS _proxy_udp_access 53 [ -n "${LOCALHOST_UDP_PROXY_MODE}" ] && {