diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile index 4999e6e86..6f0dd05cc 100644 --- a/luci-app-passwall/Makefile +++ b/luci-app-passwall/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall PKG_VERSION:=26.10.4 -PKG_RELEASE:=320 +PKG_RELEASE:=321 PKG_PO_VERSION:=$(PKG_VERSION) PKG_CONFIG_DEPENDS:= \ diff --git a/luci-app-passwall/luasrc/controller/passwall.lua b/luci-app-passwall/luasrc/controller/passwall.lua index 6744b5af0..ae4ad8f87 100644 --- a/luci-app-passwall/luasrc/controller/passwall.lua +++ b/luci-app-passwall/luasrc/controller/passwall.lua @@ -514,7 +514,7 @@ function urltest_node() local id = http.formvalue("id") local e = {} e.index = index - local result = luci.sys.exec(string.format("/usr/share/passwall/test.sh url_test_node %s %s", id, "urltest_node")) + local result = luci.sys.exec("/usr/share/passwall/test.sh url_test_node " .. util.shellquote(id or "")) local code = tonumber(luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $1}'") or "0") if code ~= 0 then local use_time_str = luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $2}'") diff --git a/luci-app-passwall/root/usr/share/passwall/app.sh b/luci-app-passwall/root/usr/share/passwall/app.sh index 847982c48..ac0268bf0 100755 --- a/luci-app-passwall/root/usr/share/passwall/app.sh +++ b/luci-app-passwall/root/usr/share/passwall/app.sh @@ -72,16 +72,26 @@ check_run_environment() { } run_ipt2socks() { - local flag tcp_tproxy local_port socks_address socks_port socks_username socks_password log_file - local _extra_param="" - eval_set_val "$@" + local flag tcp_tproxy local_port socks_address socks_port socks_username socks_password log_file param + for param in "$@"; do + case "$param" in + flag=*) flag="${param#*=}" ;; + tcp_tproxy=*) tcp_tproxy="${param#*=}" ;; + local_port=*) local_port="${param#*=}" ;; + socks_address=*) socks_address="${param#*=}" ;; + socks_port=*) socks_port="${param#*=}" ;; + socks_username=*) socks_username="${param#*=}" ;; + socks_password=*) socks_password="${param#*=}" ;; + log_file=*) log_file="${param#*=}" ;; + esac + done [ -n "$log_file" ] || log_file="/dev/null" - socks_address=$(get_host_ip "ipv4" ${socks_address}) - [ -n "$socks_username" ] && [ -n "$socks_password" ] && _extra_param="${_extra_param} -a $socks_username -k $socks_password" - [ -n "$tcp_tproxy" ] || _extra_param="${_extra_param} -R" + socks_address=$(get_host_ip "ipv4" "$socks_address") + set -- -o 60 -n 65535 -v + [ -n "$socks_username" ] && [ -n "$socks_password" ] && set -- "$@" -a "$socks_username" -k "$socks_password" + [ -n "$tcp_tproxy" ] || set -- "$@" -R flag="${flag}_TCP_UDP" - _extra_param="${_extra_param} -o 60 -n 65535 -v" - ln_run "$(first_type ipt2socks)" "ipt2socks_${flag}" $log_file -l $local_port -b 0.0.0.0 -B :: -s $socks_address -p $socks_port ${_extra_param} + ln_run "$(first_type ipt2socks)" "ipt2socks_${flag}" "$log_file" -l "$local_port" -b 0.0.0.0 -B :: -s "$socks_address" -p "$socks_port" "$@" } run_singbox() { @@ -504,6 +514,7 @@ run_socks() { # http to socks [ -z "$http_flag" ] && [ "$http_port" != "0" ] && [ -n "$http_config_file" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && [ "$type" != "socks" ] && { + local http_type json_init json_add_string "local_http_address" "$bind" json_add_string "local_http_port" "$http_port" @@ -513,17 +524,17 @@ run_socks() { json_add_string "server_username" "$_username" json_add_string "server_password" "$_password" if [ -n "${SINGBOX_BIN}" ]; then - type="sing-box" + http_type="sing-box" local bin="${SINGBOX_BIN}" local util="${UTIL_SINGBOX}" elif [ -n "${XRAY_BIN}" ]; then - type="xray" + http_type="xray" local bin="${XRAY_BIN}" local util="${UTIL_XRAY}" fi [ -n "${bin}" ] && [ -n "${util}" ] && { lua ${util} gen_proto_config "$(json_dump)" > $http_config_file - [ -n "$no_run" ] || ln_run "$bin" $type /dev/null run -c "$http_config_file" + [ -n "$no_run" ] || ln_run "$bin" "$http_type" /dev/null run -c "$http_config_file" } unset bin util } @@ -605,7 +616,9 @@ start_global() { local _config_file="global_${NODE}_socks.json" _socks_address="127.0.0.1" _socks_port=$GLOBAL_SOCKS_port - run_socks flag="global" node=$NODE bind=${node_socks_bind} socks_port=${_socks_port} config_file=${_config_file} + run_socks flag="global" node=$NODE bind=${node_socks_bind} socks_port=${_socks_port} config_file=${_config_file} http_port=${GLOBAL_HTTP_port} http_config_file=${GLOBAL_ACL_PATH}/global_socks_http.json + node_socks_flag=1 + [ "$on_node_http" = "1" ] && node_http_flag=1 unset _socks_username unset _socks_password } @@ -822,7 +835,7 @@ start_global() { if [ -n "${_socks_flag}" ]; then local _socks_tproxy="" [ "${TCP_PROXY_WAY}" = "tproxy" ] && _socks_tproxy="1" - run_ipt2socks flag=default tcp_tproxy=${_socks_tproxy} local_port=${REDIR_PORT} socks_address=${_socks_address} socks_port=${_socks_port} socks_username=${_socks_username} socks_password=${_socks_password} log_file=${log_file} + run_ipt2socks flag=default tcp_tproxy="${_socks_tproxy}" local_port="${REDIR_PORT}" socks_address="${_socks_address}" socks_port="${_socks_port}" socks_username="${_socks_username}" socks_password="${_socks_password}" log_file="${log_file}" fi [ -z "$node_socks_flag" ] && { @@ -866,7 +879,7 @@ start_socks() { local log=$(config_n_get $id log 1) [ "$log" = "0" ] && log_file="" local http_port=$(config_n_get $id http_port 0) - local http_config_file="${flag}_http.json" + local http_config_file="${id}_http.json" local enable_autoswitch=$(config_n_get $id enable_autoswitch 0) local no_rec=0 [ "$enable_autoswitch" = "1" ] && no_rec=1 @@ -911,9 +924,10 @@ socks_node_switch() { local http_config_file="${flag}_http.json" LOG_FILE="/dev/null" run_socks flag=$flag node=$new_node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file + sleep 2s + [ "$(check_port_exists "$port" tcp)" = "0" ] && return 1 set_cache_var "${flag}" "$new_node" - local USE_TABLES=$(get_cache_var "USE_TABLES") - [ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh filter_direct_node_list + return 0 } } @@ -961,8 +975,10 @@ start_crontab() { h="$t" m=0 fi - h=$(printf '%d' "$h") - m=$(printf '%d' "$m") + h=$(printf '%s' "$h" | sed 's/^0*//') + m=$(printf '%s' "$m" | sed 's/^0*//') + h=$(printf '%d' "${h:-0}") + m=$(printf '%d' "${m:-0}") local expr="$m $h * * $w" [ "$w" = "7" ] && expr="$m $h * * *" echo "$expr" @@ -1514,7 +1530,7 @@ acl_app() { } } - local dns_cache_str="${dns_mode}_${v2ray_dns_mode}_${remote_dns}_${remote_dns_doh}_${remote_dns_client_ip}_${remote_fakedns}_${remote_rewrite_ttl}" + local dns_cache_str="${dns_mode}_${v2ray_dns_mode}_${remote_dns}_${remote_dns_doh}_${remote_dns_client_ip}_${remote_fakedns}_${remote_rewrite_ttl}_${filter_proxy_ipv6}" dns_cache_key="$(echo -n "${dns_cache_str}" | md5sum | cut -d " " -f1)" if [ "$remote_fakedns" = "1" ] || ([ "$protocol" = "_shunt" ] && [ "$(config_n_get $node fakedns)" = "1" ]); then @@ -1541,7 +1557,7 @@ acl_app() { } run_${type} flag=acl_${sid} type=$dns_mode dns_socks_address=127.0.0.1 dns_socks_port=$socks_port dns_listen_port=$dns_fwd_port \ remote_dns_protocol=${v2ray_dns_mode} remote_dns_udp_server=${remote_dns} remote_dns_tcp_server=${remote_dns} remote_dns_doh="${remote_dns_doh}" \ - remote_dns_query_strategy=${remote_dns_query_strategy} remote_dns_client_ip=${remote_dns_client_ip} config_file=$config_file + remote_dns_query_strategy=${remote_dns_query_strategy} remote_dns_client_ip=${remote_dns_client_ip} remote_rewrite_ttl=${remote_rewrite_ttl:-30} config_file=$config_file fi set_cache_var "node_${node}_${dns_cache_key}" "$dns_fwd_port" } @@ -1670,7 +1686,7 @@ acl_app() { } unset enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports use_global_config node use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode filter_proxy_ipv6 dns_mode remote_dns v2ray_dns_mode remote_dns_doh remote_dns_client_ip unset _ip _mac _iprange _ipset _ip_or_mac source_list node_port config_file _extra_param dns_cache_key log loglevel log_chinadns_ng - unset _china_ng_listen _chinadns_local_dns _direct_dns_mode chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6 remote_fakedns force_https_soa use_fakedns remote_rewrite_ttl + unset _china_ng_listen _chinadns_local_dns _direct_dns_mode chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6 remote_fakedns force_https_soa use_fakedns remote_rewrite_ttl dns_shunt use_default_dns done unset socks_port redir_port dns_port dnsmasq_port chinadns_port [ -n "${has_enabled}" ] || { diff --git a/luci-app-passwall/root/usr/share/passwall/iptables.sh b/luci-app-passwall/root/usr/share/passwall/iptables.sh index aa6330037..15564644f 100755 --- a/luci-app-passwall/root/usr/share/passwall/iptables.sh +++ b/luci-app-passwall/root/usr/share/passwall/iptables.sh @@ -255,7 +255,7 @@ load_acl() { [ "${use_global_config}" = "1" ] && { if [ "$(config_get_type $NODE)" = "socks" ]; then - node_remark="Socks 配置($(config_n_get $NODE} port) 端口)" + node_remark="Socks 配置($(config_n_get "$NODE" port) 端口)" else node_remark=$(config_n_get $NODE remarks) fi @@ -368,6 +368,8 @@ load_acl() { black6_set_name="psw_${sid}_black6" ipset -! create $black_set_name nethash maxelem 1048576 timeout 172800 ipset -! create $black6_set_name nethash family inet6 maxelem 1048576 timeout 172800 + ipset save "$IPSET_BLACK" | awk -v set="$black_set_name" '$1 == "add" && $4 == "timeout" && $5 == "0" { print "add", set, $3, "timeout", 0 }' | ipset -! -R + ipset save "$IPSET_BLACK6" | awk -v set="$black6_set_name" '$1 == "add" && $4 == "timeout" && $5 == "0" { print "add", set, $3, "timeout", 0 }' | ipset -! -R } } [ "${use_gfw_list}" = "1" ] && { @@ -632,7 +634,7 @@ load_acl() { [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK) -j MARK --set-mark 88" [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_GFW) -j MARK --set-mark 88" [ "${CHN_LIST}" != "0" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_CHN) $(get_jump_ipt ${CHN_LIST} "-j MARK --set-mark 88")" - [ "${USE_SHUNT_NODE}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS $(dst $IPSET_SHUNT) "-j MARK --set-mark 88" + [ "${USE_SHUNT_NODE}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_SHUNT) -j MARK --set-mark 88" [ "${TCP_PROXY_MODE}" != "disable" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "-j MARK --set-mark 88" echolog " - ${msg}屏蔽代理 TCP 端口[${TCP_PROXY_DROP_PORTS}]" } @@ -928,8 +930,8 @@ add_firewall_rule() { for acl_section in $(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do [ "$(config_n_get $acl_section enabled)" != "1" ] && continue [ "$(config_n_get $acl_section use_global_config 0)" != "1" ] && { - [ "$(config_n_get $acl_section use_direct_list 1)" = "1" ] && USE_PROXY_LIST_ALL=1 - [ "$(config_n_get $acl_section use_proxy_list 1)" = "1" ] && USE_DIRECT_LIST_ALL=1 + [ "$(config_n_get $acl_section use_direct_list 1)" = "1" ] && USE_DIRECT_LIST_ALL=1 + [ "$(config_n_get $acl_section use_proxy_list 1)" = "1" ] && USE_PROXY_LIST_ALL=1 [ "$(config_n_get $acl_section use_block_list 1)" = "1" ] && USE_BLOCK_LIST_ALL=1 } done @@ -1061,6 +1063,8 @@ add_firewall_rule() { $ipt_f -I FORWARD $(comment "PSW_REJECT") -m mark --mark 88 -p tcp -j REJECT --reject-with tcp-reset $ipt_f -I FORWARD $(comment "PSW_REJECT") -m mark --mark 88 -p udp -j REJECT + $ipt_f -I OUTPUT $(comment "PSW_REJECT") -m mark --mark 88 -p tcp -j REJECT --reject-with tcp-reset + $ipt_f -I OUTPUT $(comment "PSW_REJECT") -m mark --mark 88 -p udp -j REJECT $ipt_n -N PSW $ipt_n -A PSW $(dst $IPSET_LAN) -j RETURN @@ -1090,6 +1094,7 @@ add_firewall_rule() { $ipt_m -A PSW_DIVERT -j ACCEPT $ipt_m -N PSW_RULE + $ipt_m -A PSW_RULE -m mark --mark 88 -j RETURN $ipt_m -A PSW_RULE -j CONNMARK --restore-mark $ipt_m -A PSW_RULE -m mark --mark ${FWMARK} -j RETURN $ipt_m -A PSW_RULE -p tcp -m tcp --syn -j MARK --set-xmark ${FWMARK} @@ -1110,6 +1115,10 @@ add_firewall_rule() { $ipt_m -N PSW_OUTPUT $ipt_m -A PSW_OUTPUT $(dst $IPSET_LAN) -j RETURN $ipt_m -A PSW_OUTPUT $(dst $IPSET_VPS) -j RETURN + $ip6t_m -N PSW_OUTPUT + $ip6t_m -A PSW_OUTPUT -m mark --mark 0xff/0xff -j RETURN + $ip6t_m -A PSW_OUTPUT $(dst $IPSET_LAN6) -j RETURN + $ip6t_m -A PSW_OUTPUT $(dst $IPSET_VPS6) -j RETURN [ -n "$IPT_APPEND_DNS" ] && { local local_dns dns_address dns_port for local_dns in $(echo $IPT_APPEND_DNS | tr ',' ' '); do @@ -1118,6 +1127,7 @@ add_firewall_rule() { if echo "$dns_address" | grep -q -v ':'; then $ipt_m -A PSW_OUTPUT -p udp -d ${dns_address} --dport ${dns_port:-53} -j RETURN $ipt_m -A PSW_OUTPUT -p tcp -d ${dns_address} --dport ${dns_port:-53} -j RETURN + [ -z "${is_tproxy}" ] && $ipt_n -A PSW_OUTPUT -p tcp -d ${dns_address} --dport ${dns_port:-53} -j RETURN echolog " - [$?]追加直连DNS到iptables:${dns_address}:${dns_port:-53}" else $ip6t_m -A PSW_OUTPUT -p udp -d ${dns_address} --dport ${dns_port:-53} -j RETURN @@ -1161,6 +1171,7 @@ add_firewall_rule() { $ip6t_m -A PSW_DIVERT -j ACCEPT $ip6t_m -N PSW_RULE + $ip6t_m -A PSW_RULE -m mark --mark 88 -j RETURN $ip6t_m -A PSW_RULE -j CONNMARK --restore-mark $ip6t_m -A PSW_RULE -m mark --mark ${FWMARK} -j RETURN $ip6t_m -A PSW_RULE -p tcp -m tcp --syn -j MARK --set-xmark ${FWMARK} @@ -1169,6 +1180,8 @@ add_firewall_rule() { $ip6t_f -I FORWARD $(comment "PSW_REJECT") -m mark --mark 88 -p tcp -j REJECT --reject-with tcp-reset $ip6t_f -I FORWARD $(comment "PSW_REJECT") -m mark --mark 88 -p udp -j REJECT + $ip6t_f -I OUTPUT $(comment "PSW_REJECT") -m mark --mark 88 -p tcp -j REJECT --reject-with tcp-reset + $ip6t_f -I OUTPUT $(comment "PSW_REJECT") -m mark --mark 88 -p udp -j REJECT $ip6t_m -N PSW $ip6t_m -A PSW $(dst $IPSET_LAN6) -j RETURN @@ -1181,10 +1194,6 @@ add_firewall_rule() { # Only TCP, UDP Invalid. insert_rule_before "$ip6t_m" "PREROUTING" "PSW" "-p tcp -m socket --transparent -j PSW_DIVERT" - $ip6t_m -N PSW_OUTPUT - $ip6t_m -A PSW_OUTPUT -m mark --mark 0xff/0xff -j RETURN - $ip6t_m -A PSW_OUTPUT $(dst $IPSET_LAN6) -j RETURN - $ip6t_m -A PSW_OUTPUT $(dst $IPSET_VPS6) -j RETURN [ "${USE_BLOCK_LIST}" = "1" ] && $ip6t_m -A PSW_OUTPUT $(dst $IPSET_BLOCK6) -j MARK --set-mark 88 [ "${USE_DIRECT_LIST}" = "1" ] && $ip6t_m -A PSW_OUTPUT $(dst $IPSET_WHITE6) -j RETURN $ip6t_m -A PSW_OUTPUT -m conntrack --ctdir REPLY -j RETURN @@ -1235,6 +1244,14 @@ add_firewall_rule() { [ -n "${LOCALHOST_TCP_PROXY_MODE}" ] || [ -n "${LOCALHOST_UDP_PROXY_MODE}" ] && { [ "$TCP_PROXY_DROP_PORTS" != "disable" ] && { + [ "$PROXY_IPV6" = "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "-d $FAKE_IP_6 -j MARK --set-mark 88" + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK6) -j MARK --set-mark 88" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_GFW6) -j MARK --set-mark 88" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_CHN6) $(get_jump_ipt ${CHN_LIST} "-j MARK --set-mark 88")" + [ "${USE_SHUNT_NODE}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_SHUNT6) -j MARK --set-mark 88" + [ "${LOCALHOST_TCP_PROXY_MODE}" != "disable" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "-j MARK --set-mark 88" + } [ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "-d $FAKE_IP -j MARK --set-mark 88" [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK) -j MARK --set-mark 88" [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_GFW) -j MARK --set-mark 88" @@ -1245,6 +1262,14 @@ add_firewall_rule() { } [ "$UDP_PROXY_DROP_PORTS" != "disable" ] && { + [ "$PROXY_IPV6" = "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "-d $FAKE_IP_6 -j MARK --set-mark 88" + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK6) -j MARK --set-mark 88" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_GFW6) -j MARK --set-mark 88" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_CHN6) $(get_jump_ipt ${CHN_LIST} "-j MARK --set-mark 88")" + [ "${USE_SHUNT_NODE}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_SHUNT6) -j MARK --set-mark 88" + [ "${LOCALHOST_UDP_PROXY_MODE}" != "disable" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "-j MARK --set-mark 88" + } [ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "-d $FAKE_IP -j MARK --set-mark 88" [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK) -j MARK --set-mark 88" [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_GFW) -j MARK --set-mark 88" @@ -1484,7 +1509,7 @@ gen_include() { [ -z "${_ipt}" ] && return echo "*$2" - ${_ipt}-save -t $2 | grep "PSW" | grep -v "\-j PSW$" | grep -v "mangle\-OUTPUT\-PSW" | grep -v "\-m socket .*\-j PSW_DIVERT$" | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" + ${_ipt}-save -t $2 | grep "PSW" | grep -v "\-j PSW$" | grep -v "mangle\-OUTPUT\-PSW" | grep -v "\-m socket .*\-j PSW_DIVERT$" | sed -e "s/^-A \(OUTPUT\|PREROUTING\|FORWARD\)/-I \1 1/" echo 'COMMIT' } local __ipt="" @@ -1498,6 +1523,7 @@ gen_include() { $ipt-restore -n <<-EOT $(extract_rules 4 nat) $(extract_rules 4 mangle) + $(extract_rules 4 filter) EOT echo "\${mangle_output_psw}" | while read line; do @@ -1520,6 +1546,7 @@ gen_include() { $ip6t-restore -n <<-EOT $(extract_rules 6 nat) $(extract_rules 6 mangle) + $(extract_rules 6 filter) EOT echo "\${mangle_output_psw}" | while read line; do diff --git a/luci-app-passwall/root/usr/share/passwall/monitor.sh b/luci-app-passwall/root/usr/share/passwall/monitor.sh index 7c0cf4a03..76f7095c6 100755 --- a/luci-app-passwall/root/usr/share/passwall/monitor.sh +++ b/luci-app-passwall/root/usr/share/passwall/monitor.sh @@ -8,30 +8,22 @@ MAX_RESTART_COUNT=10 RESTART_STATS_DIR="${TMP_PATH}/script_rstats" mkdir -p "$RESTART_STATS_DIR" -ENABLED=$(config_n_get @global[0] enabled 0) -[ "$ENABLED" != 1 ] && return 1 +[ "$(get_cache_var "ENABLED_DEFAULT_ACL")" != 1 ] && [ "$(get_cache_var "ENABLED_ACLS")" != 1 ] && exit 1 ENABLED=$(config_n_get @global_delay[0] start_daemon 0) -[ "$ENABLED" != 1 ] && return 1 -sleep 58s +[ "$ENABLED" != 1 ] && exit 1 +exec 9>"$LOCK_FILE" +flock -n 9 || exit 0 +sleep 58s 9>&- last_cleanup_date=$(date +%Y%m%d) while [ "$ENABLED" -eq 1 ]; do - [ -f "$LOCK_FILE" ] && { - sleep 6s - continue - } - touch $LOCK_FILE - for file in "$TMP_SCRIPT_FUNC_PATH"/*; do [ -f "$file" ] || continue - IFS= read -r cmd < "$file" + { + IFS= read -r pid + IFS= read -r start_time + } < "$file" + cmd=$(sed '1,2d' "$file") [ -z "$cmd" ] && continue - cmd_check=$(printf '%s' "$cmd" | sed 's/>.*$//;s/[[:space:]]*$//') - - case "$cmd_check" in - *dns2socks*) cmd_check=${cmd_check//:/ } ;; - esac - - cmd_check=$(printf '%s' "$cmd_check" | sed 's/[^a-zA-Z0-9 ]/\\&/g') filename=$(basename "$file") stats_file="${RESTART_STATS_DIR}/${filename}.count" @@ -44,12 +36,17 @@ while [ "$ENABLED" -eq 1 ]; do # 检查是否超过最大重启次数 [ "$restart_count" -ge "$MAX_RESTART_COUNT" ] && continue - if ! busybox pgrep -f "${cmd_check}" >/dev/null; then + current_start_time=$(get_process_start_time "$pid") + if [ -z "$current_start_time" ] || [ "$current_start_time" != "$start_time" ]; then restart_count=$((restart_count + 1)) echo "$restart_count" > "$stats_file" #echo "${cmd} 进程挂掉,重启" >> /tmp/log/passwall.log - sh -c "nohup ${cmd} 2>&1 &" - sleep 1 + pid=$(sh -c "nohup ${cmd} & echo \$!" 9>&-) + { + printf '%s\n' "$pid" "$(get_process_start_time "$pid")" + printf '%s\n' "$cmd" + } > "$file" + sleep 1 9>&- fi done @@ -60,6 +57,5 @@ while [ "$ENABLED" -eq 1 ]; do last_cleanup_date="$current_date" fi - rm -f $LOCK_FILE - sleep 58s + sleep 58s 9>&- done diff --git a/luci-app-passwall/root/usr/share/passwall/nftables.sh b/luci-app-passwall/root/usr/share/passwall/nftables.sh index 5ef636e3a..210a6e990 100755 --- a/luci-app-passwall/root/usr/share/passwall/nftables.sh +++ b/luci-app-passwall/root/usr/share/passwall/nftables.sh @@ -111,12 +111,10 @@ insert_rule_after() { if [ -z "${_index}" ] && [ "${default_index}" = "0" ]; then nft "add rule $table_name $chain_name $rule" else - if [ -n "${_index}" ]; then - _index=$((_index + 1)) - else + if [ -z "${_index}" ]; then _index=${default_index} fi - nft "insert rule $table_name $chain_name position $_index $rule" + nft "add rule $table_name $chain_name position $_index $rule" fi } @@ -183,9 +181,10 @@ nft_rule_dual() { local match_condition="${2}" local target_set="${3}" local final_action="${4}" - + # 第5个参数是为 ACL 复用 NFTSET_BLACK_STATIC 准备的 nft "add rule $NFTABLE_NAME $chain_name $match_condition @${target_set} ${final_action}" - nft "add rule $NFTABLE_NAME $chain_name $match_condition @${target_set}_static ${final_action}" + local static_set="${5:-${target_set}_static}" + nft "add rule $NFTABLE_NAME $chain_name $match_condition @${static_set} ${final_action}" } insert_nftset() { @@ -328,9 +327,7 @@ load_acl() { use_shunt_node=${USE_SHUNT_NODE} dns_redirect_port=${DNS_REDIRECT_PORT} black_set_name=${NFTSET_BLACK} - black_set_name_static=${NFTSET_BLACK_STATIC} black6_set_name=${NFTSET_BLACK6} - black6_set_name_static=${NFTSET_BLACK6_STATIC} gfw_set_name=${NFTSET_GFW} gfw6_set_name=${NFTSET_GFW6} shunt_set_name=${NFTSET_SHUNT} @@ -418,13 +415,9 @@ load_acl() { [ "${use_proxy_list}" = "1" ] && { [ "${use_global_config}" = "0" ] && { black_set_name="psw_${sid}_black" - black_set_name_static="psw_${sid}_black_static" black6_set_name="psw_${sid}_black6" - black6_set_name_static="psw_${sid}_black6_static" gen_nftset $black_set_name ipv4_addr "2d" - gen_nftset $black_set_name_static ipv4_addr 0 gen_nftset $black6_set_name ipv6_addr "2d" - gen_nftset $black6_set_name_static ipv6_addr 0 } } [ "${use_gfw_list}" = "1" ] && { @@ -493,14 +486,14 @@ load_acl() { [ "$tcp_proxy_drop_ports" != "disable" ] && { [ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && { [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr $FAKE_IP_6 counter reject comment \"$remarks\"" 2>/dev/null - [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr" "$black6_set_name" "counter reject comment \"$remarks\"" 2>/dev/null + [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr" "$black6_set_name" "counter reject comment \"$remarks\"" "$NFTSET_BLACK6_STATIC" 2>/dev/null [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr @$gfw6_set_name counter reject comment \"$remarks\"" 2>/dev/null [ "${chn_list}" != "0" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr" "$NFTSET_CHN6" "$(get_jump_nft ${chn_list} "counter reject") comment \"$remarks\"" 2>/dev/null [ "${use_shunt_node}" = "1" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr" "$shunt6_set_name" "counter reject comment \"$remarks\"" 2>/dev/null [ "${tcp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") counter reject comment \"$remarks\"" 2>/dev/null } [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip daddr $FAKE_IP counter reject comment \"$remarks\"" - [ "${use_proxy_list}" = "1" ] && nft_rule_dual "$nft_prerouting_chain" "ip protocol tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip daddr" "$black_set_name" "counter reject comment \"$remarks\"" + [ "${use_proxy_list}" = "1" ] && nft_rule_dual "$nft_prerouting_chain" "ip protocol tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip daddr" "$black_set_name" "counter reject comment \"$remarks\"" "$NFTSET_BLACK_STATIC" [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip daddr @$gfw_set_name counter reject comment \"$remarks\"" [ "${chn_list}" != "0" ] && nft_rule_dual "$nft_prerouting_chain" "ip protocol tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip daddr" "$NFTSET_CHN" "$(get_jump_nft ${chn_list} "counter reject") comment \"$remarks\"" [ "${use_shunt_node}" = "1" ] && nft_rule_dual "$nft_prerouting_chain" "ip protocol tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip daddr" "$shunt_set_name" "counter reject comment \"$remarks\"" @@ -511,14 +504,14 @@ load_acl() { [ "$udp_proxy_drop_ports" != "disable" ] && { [ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && { [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr $FAKE_IP_6 counter reject comment \"$remarks\"" 2>/dev/null - [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr" "$black6_set_name" "counter reject comment \"$remarks\"" 2>/dev/null + [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr" "$black6_set_name" "counter reject comment \"$remarks\"" "$NFTSET_BLACK6_STATIC" 2>/dev/null [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr @$gfw6_set_name counter reject comment \"$remarks\"" 2>/dev/null [ "${chn_list}" != "0" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr" "$NFTSET_CHN6" "$(get_jump_nft ${chn_list} "counter reject") comment \"$remarks\"" 2>/dev/null [ "${use_shunt_node}" = "1" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr" "$shunt6_set_name" "counter reject comment \"$remarks\"" 2>/dev/null [ "${udp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") counter reject comment \"$remarks\"" 2>/dev/null } [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip daddr $FAKE_IP counter reject comment \"$remarks\"" 2>/dev/null - [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_MANGLE" "ip protocol udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip daddr" "$black_set_name" "counter reject comment \"$remarks\"" 2>/dev/null + [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_MANGLE" "ip protocol udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip daddr" "$black_set_name" "counter reject comment \"$remarks\"" "$NFTSET_BLACK_STATIC" 2>/dev/null [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip daddr @$gfw_set_name counter reject comment \"$remarks\"" 2>/dev/null [ "${chn_list}" != "0" ] && nft_rule_dual "PSW_MANGLE" "ip protocol udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip daddr" "$NFTSET_CHN" "$(get_jump_nft ${chn_list} "counter reject") comment \"$remarks\"" 2>/dev/null [ "${use_shunt_node}" = "1" ] && nft_rule_dual "PSW_MANGLE" "ip protocol udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip daddr" "$shunt_set_name" "counter reject comment \"$remarks\"" 2>/dev/null @@ -543,7 +536,7 @@ load_acl() { [ "$accept_icmp" = "1" ] && { [ "${use_direct_list}" = "1" ] && nft_rule_dual "PSW_ICMP_REDIRECT" "ip protocol icmp ${_ipt_source} ip daddr" "$NFTSET_WHITE" "counter return comment \"$remarks\"" [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr $FAKE_IP $(REDIRECT) comment \"$remarks\"" - [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_ICMP_REDIRECT" "ip protocol icmp ${_ipt_source} ip daddr" "$black_set_name" "$(REDIRECT) comment \"$remarks\"" + [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_ICMP_REDIRECT" "ip protocol icmp ${_ipt_source} ip daddr" "$black_set_name" "$(REDIRECT) comment \"$remarks\"" "$NFTSET_BLACK_STATIC" [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr @$gfw_set_name $(REDIRECT) comment \"$remarks\"" [ "${chn_list}" != "0" ] && nft_rule_dual "PSW_ICMP_REDIRECT" "ip protocol icmp ${_ipt_source} ip daddr" "$NFTSET_CHN" "$(get_jump_nft ${chn_list}) comment \"$remarks\"" [ "${use_shunt_node}" = "1" ] && nft_rule_dual "PSW_ICMP_REDIRECT" "ip protocol icmp ${_ipt_source} ip daddr" "$shunt_set_name" "$(REDIRECT) comment \"$remarks\"" @@ -554,7 +547,7 @@ load_acl() { [ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && { [ "${use_direct_list}" = "1" ] && nft_rule_dual "PSW_ICMP_REDIRECT" "meta l4proto icmpv6 ${_ipt_source} ip6 daddr" "$NFTSET_WHITE6" "counter return comment \"$remarks\"" 2>/dev/null [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr $FAKE_IP_6 $(REDIRECT) comment \"$remarks\"" 2>/dev/null - [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_ICMP_REDIRECT" "meta l4proto icmpv6 ${_ipt_source} ip6 daddr" "$black6_set_name" "$(REDIRECT) comment \"$remarks\"" 2>/dev/null + [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_ICMP_REDIRECT" "meta l4proto icmpv6 ${_ipt_source} ip6 daddr" "$black6_set_name" "$(REDIRECT) comment \"$remarks\"" "$NFTSET_BLACK6_STATIC" 2>/dev/null [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr @$gfw6_set_name $(REDIRECT) comment \"$remarks\"" 2>/dev/null [ "${chn_list}" != "0" ] && nft_rule_dual "PSW_ICMP_REDIRECT" "meta l4proto icmpv6 ${_ipt_source} ip6 daddr" "$NFTSET_CHN6" "$(get_jump_nft ${chn_list}) comment \"$remarks\"" 2>/dev/null [ "${use_shunt_node}" = "1" ] && nft_rule_dual "PSW_ICMP_REDIRECT" "meta l4proto icmpv6 ${_ipt_source} ip6 daddr" "$shunt6_set_name" "$(REDIRECT) comment \"$remarks\"" 2>/dev/null @@ -563,7 +556,7 @@ load_acl() { } [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} ip daddr $FAKE_IP ${nft_j} comment \"$remarks\"" - [ "${use_proxy_list}" = "1" ] && nft_rule_dual "$nft_chain" "ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip daddr" "$black_set_name" "${nft_j} comment \"$remarks\"" + [ "${use_proxy_list}" = "1" ] && nft_rule_dual "$nft_chain" "ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip daddr" "$black_set_name" "${nft_j} comment \"$remarks\"" "$NFTSET_BLACK_STATIC" [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip daddr @$gfw_set_name ${nft_j} comment \"$remarks\"" [ "${chn_list}" != "0" ] && nft_rule_dual "$nft_chain" "ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip daddr" "$NFTSET_CHN" "$(get_jump_nft ${chn_list} "${nft_j}") comment \"$remarks\"" [ "${use_shunt_node}" = "1" ] && nft_rule_dual "$nft_chain" "ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip daddr" "$shunt_set_name" "${nft_j} comment \"$remarks\"" @@ -572,7 +565,7 @@ load_acl() { [ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && { [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW_RULE comment \"$remarks\"" - [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip6 daddr" "$black6_set_name" "counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null + [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip6 daddr" "$black6_set_name" "counter jump PSW_RULE comment \"$remarks\"" "$NFTSET_BLACK6_STATIC" 2>/dev/null [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip6 daddr @$gfw6_set_name counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null [ "${chn_list}" != "0" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip6 daddr" "$NFTSET_CHN6" "$(get_jump_nft ${chn_list} "counter jump PSW_RULE") comment \"$remarks\"" 2>/dev/null [ "${use_shunt_node}" = "1" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip6 daddr" "$shunt6_set_name" "counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null @@ -594,7 +587,7 @@ load_acl() { msg2="${msg2}(TPROXY:${udp_port})" [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} ip daddr $FAKE_IP counter jump PSW_RULE comment \"$remarks\"" - [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_MANGLE" "ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip daddr" "$black_set_name" "counter jump PSW_RULE comment \"$remarks\"" + [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_MANGLE" "ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip daddr" "$black_set_name" "counter jump PSW_RULE comment \"$remarks\"" "$NFTSET_BLACK_STATIC" [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip daddr @$gfw_set_name counter jump PSW_RULE comment \"$remarks\"" [ "${chn_list}" != "0" ] && nft_rule_dual "PSW_MANGLE" "ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip daddr" "$NFTSET_CHN" "$(get_jump_nft ${chn_list} "counter jump PSW_RULE") comment \"$remarks\"" [ "${use_shunt_node}" = "1" ] && nft_rule_dual "PSW_MANGLE" "ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip daddr" "$shunt_set_name" "counter jump PSW_RULE comment \"$remarks\"" @@ -603,7 +596,7 @@ load_acl() { [ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && { [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW_RULE comment \"$remarks\"" - [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip6 daddr" "$black6_set_name" "counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null + [ "${use_proxy_list}" = "1" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip6 daddr" "$black6_set_name" "counter jump PSW_RULE comment \"$remarks\"" "$NFTSET_BLACK6_STATIC" 2>/dev/null [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip6 daddr @$gfw6_set_name counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null [ "${chn_list}" != "0" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip6 daddr" "$NFTSET_CHN6" "$(get_jump_nft ${chn_list} "counter jump PSW_RULE") comment \"$remarks\"" 2>/dev/null [ "${use_shunt_node}" = "1" ] && nft_rule_dual "PSW_MANGLE_V6" "meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip6 daddr" "$shunt6_set_name" "counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null @@ -1034,8 +1027,8 @@ add_firewall_rule() { for acl_section in $(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do [ "$(config_n_get $acl_section enabled)" != "1" ] && continue [ "$(config_n_get $acl_section use_global_config 0)" != "1" ] && { - [ "$(config_n_get $acl_section use_direct_list 1)" = "1" ] && USE_PROXY_LIST_ALL=1 - [ "$(config_n_get $acl_section use_proxy_list 1)" = "1" ] && USE_DIRECT_LIST_ALL=1 + [ "$(config_n_get $acl_section use_direct_list 1)" = "1" ] && USE_DIRECT_LIST_ALL=1 + [ "$(config_n_get $acl_section use_proxy_list 1)" = "1" ] && USE_PROXY_LIST_ALL=1 [ "$(config_n_get $acl_section use_block_list 1)" = "1" ] && USE_BLOCK_LIST_ALL=1 } done @@ -1221,7 +1214,7 @@ add_firewall_rule() { } #icmp ipv6-icmp redirect - if [ "$accept_icmp" = "1" ]; then + if [ "$accept_icmp" = "1" ] || [ "$accept_icmpv6" = "1" ]; then nft "add chain $NFTABLE_NAME PSW_ICMP_REDIRECT" nft "flush chain $NFTABLE_NAME PSW_ICMP_REDIRECT" nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip daddr @$NFTSET_LAN counter return" @@ -1232,8 +1225,14 @@ add_firewall_rule() { nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip6 daddr @$NFTSET_VPS6 counter return" } - nft "add rule $NFTABLE_NAME dstnat meta l4proto {icmp,icmpv6} counter jump PSW_ICMP_REDIRECT" - nft "add rule $NFTABLE_NAME nat_output meta l4proto {icmp,icmpv6} counter jump PSW_ICMP_REDIRECT" + [ "$accept_icmp" = "1" ] && { + nft "add rule $NFTABLE_NAME dstnat meta l4proto icmp counter jump PSW_ICMP_REDIRECT" + nft "add rule $NFTABLE_NAME nat_output meta l4proto icmp counter jump PSW_ICMP_REDIRECT" + } + [ "$accept_icmpv6" = "1" ] && { + nft "add rule $NFTABLE_NAME dstnat meta l4proto icmpv6 counter jump PSW_ICMP_REDIRECT" + nft "add rule $NFTABLE_NAME nat_output meta l4proto icmpv6 counter jump PSW_ICMP_REDIRECT" + } fi #ipv4 wan_ip @@ -1267,6 +1266,7 @@ add_firewall_rule() { if echo "$dns_address" | grep -q -v ':'; then nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr ${dns_address} $(factor ${dns_port:-53} "udp dport") counter return" nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol tcp ip daddr ${dns_address} $(factor ${dns_port:-53} "tcp dport") counter return" + [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_NAT ip protocol tcp ip daddr ${dns_address} $(factor ${dns_port:-53} "tcp dport") counter return" echolog " - [$?]追加直连DNS到nftables:${dns_address}:${dns_port:-53}" else nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr ${dns_address} $(factor ${dns_port:-53} "udp dport") counter return" @@ -1321,6 +1321,14 @@ add_firewall_rule() { [ -n "${LOCALHOST_TCP_PROXY_MODE}" ] || [ -n "${LOCALHOST_UDP_PROXY_MODE}" ] && { [ "$TCP_PROXY_DROP_PORTS" != "disable" ] && { + [ "$PROXY_IPV6" = "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter reject + [ "${USE_PROXY_LIST}" = "1" ] && nft_rule_dual "PSW_OUTPUT_MANGLE_V6" "meta l4proto tcp ip6 daddr" "$NFTSET_BLACK6" "$(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter reject" + [ "${USE_GFW_LIST}" = "1" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr @$NFTSET_GFW6 $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter reject + [ "${CHN_LIST}" != "0" ] && nft_rule_dual "PSW_OUTPUT_MANGLE_V6" "meta l4proto tcp ip6 daddr" "$NFTSET_CHN6" "$(factor $TCP_PROXY_DROP_PORTS "tcp dport") $(get_jump_nft ${CHN_LIST} "counter reject")" + [ "${USE_SHUNT_NODE}" = "1" ] && nft_rule_dual "PSW_OUTPUT_MANGLE_V6" "meta l4proto tcp ip6 daddr" "$NFTSET_SHUNT6" "$(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter reject" + [ "${LOCALHOST_TCP_PROXY_MODE}" != "disable" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter reject + } [ "${USE_FAKEDNS}" = "1" ] && nft add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp ip daddr $FAKE_IP $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter reject [ "${USE_PROXY_LIST}" = "1" ] && nft_rule_dual "$nft_output_chain" "ip protocol tcp ip daddr" "$NFTSET_BLACK" "$(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter reject" [ "${USE_GFW_LIST}" = "1" ] && nft add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp ip daddr @$NFTSET_GFW $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter reject @@ -1331,6 +1339,14 @@ add_firewall_rule() { } [ "$UDP_PROXY_DROP_PORTS" != "disable" ] && { + [ "$PROXY_IPV6" = "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 $(factor $UDP_PROXY_DROP_PORTS "udp dport") counter reject + [ "${USE_PROXY_LIST}" = "1" ] && nft_rule_dual "PSW_OUTPUT_MANGLE_V6" "meta l4proto udp ip6 daddr" "$NFTSET_BLACK6" "$(factor $UDP_PROXY_DROP_PORTS "udp dport") counter reject" + [ "${USE_GFW_LIST}" = "1" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr @$NFTSET_GFW6 $(factor $UDP_PROXY_DROP_PORTS "udp dport") counter reject + [ "${CHN_LIST}" != "0" ] && nft_rule_dual "PSW_OUTPUT_MANGLE_V6" "meta l4proto udp ip6 daddr" "$NFTSET_CHN6" "$(factor $UDP_PROXY_DROP_PORTS "udp dport") $(get_jump_nft ${CHN_LIST} "counter reject")" + [ "${USE_SHUNT_NODE}" = "1" ] && nft_rule_dual "PSW_OUTPUT_MANGLE_V6" "meta l4proto udp ip6 daddr" "$NFTSET_SHUNT6" "$(factor $UDP_PROXY_DROP_PORTS "udp dport") counter reject" + [ "${LOCALHOST_UDP_PROXY_MODE}" != "disable" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") counter reject + } [ "${USE_FAKEDNS}" = "1" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr $FAKE_IP $(factor $UDP_PROXY_DROP_PORTS "udp dport") counter reject [ "${USE_PROXY_LIST}" = "1" ] && nft_rule_dual "PSW_OUTPUT_MANGLE" "ip protocol udp ip daddr" "$NFTSET_BLACK" "$(factor $UDP_PROXY_DROP_PORTS "udp dport") counter reject" [ "${USE_GFW_LIST}" = "1" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr @$NFTSET_GFW $(factor $UDP_PROXY_DROP_PORTS "udp dport") counter reject diff --git a/luci-app-passwall/root/usr/share/passwall/socks_auto_switch.sh b/luci-app-passwall/root/usr/share/passwall/socks_auto_switch.sh index e062c8930..882b56173 100755 --- a/luci-app-passwall/root/usr/share/passwall/socks_auto_switch.sh +++ b/luci-app-passwall/root/usr/share/passwall/socks_auto_switch.sh @@ -3,11 +3,9 @@ . /usr/share/passwall/utils.sh APP_FILE=${APP_PATH}/app.sh -flag=0 - check_process() { while busybox pgrep -af "${CONFIG}/" | grep -E 'app\.sh.*(start|stop)|nftables\.sh|iptables\.sh|subscribe\.lua' >/dev/null; do - sleep 6s + sleep 6s 8>&- 9>&- done } @@ -25,19 +23,21 @@ test_url() { fi [ "$curl_retry_all_errors" = "1" ] && extra_params="--retry-all-errors ${extra_params}" - local max_time=$((timeout * (try + 1) + try + 3)) + local max_time=$((timeout + 3)) + local retry_max_time=$((max_time * (try + 1) + try)) curl_test() { - /usr/bin/curl -skIL -o /dev/null ${extra_params} --max-time ${max_time} --connect-timeout ${timeout} --retry ${try} --retry-delay 1 -w "%{http_code}" "$url" + /usr/bin/curl -skIL -o /dev/null ${extra_params} --max-time ${max_time} --connect-timeout ${timeout} --retry ${try} --retry-delay 1 --retry-max-time ${retry_max_time} -w "%{http_code}" "$url" 8>&- 9>&- } - local status=$(curl_test) + local status + status=$(curl_test) || status=000 [ "$status" = "204" ] && status=200 if [ "$status" = "200" ] && [ "$repeat" = "1" ]; then - sleep 3s - status=$(curl_test) + sleep 3s 8>&- 9>&- + status=$(curl_test) || status=000 [ "$status" = "204" ] && status=200 fi - echo $status + printf '%s' "$status" } test_proxy() { @@ -51,7 +51,7 @@ test_proxy() { result=1 else result=2 - ping -c 3 -W 1 223.5.5.5 > /dev/null 2>&1 + ping -c 3 -W 1 223.5.5.5 > /dev/null 2>&1 8>&- 9>&- [ $? -eq 0 ] && { result=1 } @@ -62,24 +62,31 @@ test_proxy() { test_node() { local node_id=$1 - local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z') - [ -n "${_type}" ] && { - check_process - local _tmp_port=$(get_new_port 48800 tcp,udp) - NO_REC_PROCESS=1 $APP_FILE run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json - sleep 2s - local curlx="socks5h://127.0.0.1:${_tmp_port}" - local _proxy_status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x $curlx" 1) - # 结束 SS 插件进程 - local pid_file="${TMP_PATH}/test_node_${node_id}_plugin.pid" - [ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1 - busybox pgrep -af "test_node_${node_id}" | awk '! /socks_auto_switch\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1 - rm -rf ${TMP_PATH}/test_node_${node_id}*.* - if [ "${_proxy_status}" -eq 200 ]; then - return 0 - fi - } - return 1 + local test_flag="test_node_${id}_${node_id}" + local _type _tmp_port curlx _proxy_status pid_file + ( + exec 9>&- + exec 8>"${LOCK_PATH}/${CONFIG}_socks_auto_switch_test.lock" + flock -x 8 || exit 1 + _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z') + [ -n "${_type}" ] && { + check_process + _tmp_port=$(get_new_port 48800 tcp,udp) || exit 1 + NO_REC_PROCESS=1 "$APP_FILE" run_socks flag="$test_flag" node="$node_id" bind=127.0.0.1 socks_port="$_tmp_port" config_file="${test_flag}.json" 8>&- 9>&- + sleep 2s 8>&- 9>&- + curlx="socks5h://127.0.0.1:${_tmp_port}" + _proxy_status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x $curlx" 1) + # 结束 SS 插件进程 + pid_file="${TMP_PATH}/${test_flag}_plugin.pid" + [ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1 + busybox pgrep -af "${TMP_PATH}/${test_flag}[._]" | awk '! /socks_auto_switch\.sh/{print $1}' | xargs -r kill -9 >/dev/null 2>&1 + rm -f "$TMP_PATH/${test_flag}"*.* + if [ "${_proxy_status}" -eq 200 ]; then + exit 0 + fi + } + exit 1 + ) } try_switch_backup() { @@ -122,23 +129,23 @@ try_switch_backup() { if test_node ${new_node}; then check_process echolog "Socks切换检测:端口[${socks_port}]【${node_type}:[$node_remarks]】正常,切换到此节点!" - NO_REC_PROCESS=1 $APP_FILE socks_node_switch flag=${id} new_node=${new_node} - [ $? -eq 0 ] && { + if NO_REC_PROCESS=1 "$APP_FILE" socks_node_switch flag="$id" new_node="$new_node" 9>&-; then echolog "Socks切换检测:端口[${socks_port}] 节点切换完毕!" - } - return 0 + return 0 + fi + echolog "Socks切换检测:端口[${socks_port}] 节点切换失败,继续尝试其他节点!" + else + echolog "Socks切换检测:端口[${socks_port}]【${node_type}:[$node_remarks]】异常。" fi - echolog "Socks切换检测:端口[${socks_port}]【${node_type}:[$node_remarks]】异常。" now_node="$new_node" tried=$((tried + 1)) done - echolog "Socks切换检测:端口[${socks_port}] 所有节点均不可用!" + echolog "Socks切换检测:端口[${socks_port}] 所有节点均不可用或切换失败!" return 1 } test_auto_switch() { - flag=$((flag + 1)) local b_nodes=$1 local now_node=$2 [ -z "$now_node" ] && { @@ -150,9 +157,7 @@ test_auto_switch() { fi } - [ $flag -le 1 ] && main_node=$now_node - - local status=$(test_proxy) + local status=$(test_proxy 9>&-) if [ "$status" = "2" ]; then echolog "Socks切换检测:无法连接到网络,请检查网络是否正常!" return 2 @@ -164,9 +169,12 @@ test_auto_switch() { [ $? -eq 0 ] && { check_process echolog "Socks切换检测:端口[${socks_port}] 主节点【$(config_n_get $main_node type):[$(config_n_get $main_node remarks)]】正常,切换到主节点!" - NO_REC_PROCESS=1 $APP_FILE socks_node_switch flag=${id} new_node=${main_node} - [ $? -eq 0 ] && echolog "Socks切换检测:端口[${socks_port}] 节点切换完毕!" - return 0 + if NO_REC_PROCESS=1 "$APP_FILE" socks_node_switch flag="$id" new_node="$main_node" 9>&-; then + echolog "Socks切换检测:端口[${socks_port}] 节点切换完毕!" + return 0 + fi + echolog "Socks切换检测:端口[${socks_port}] 恢复主节点失败!" + status=1 } fi @@ -183,6 +191,8 @@ test_auto_switch() { start() { id=$1 LOCK_FILE=${LOCK_PATH}/${CONFIG}_socks_auto_switch_${id}.lock + exec 9>"$LOCK_FILE" + flock -n 9 || return 0 main_node=$(config_n_get $id node) socks_port=$(config_n_get $id port 0) delay=$(config_n_get $id autoswitch_testing_time 30) @@ -198,7 +208,10 @@ start() { [ "$main_node" = "$backup_node" ] && return elif [ "$backup_node_num" -gt 1 ]; then [ "$restore_switch" != "1" ] && { - [ -z "$(echo $backup_node | grep -F "$main_node")" ] && backup_node="${backup_node} ${main_node}" + case " $backup_node " in + *" $main_node "*) ;; + *) backup_node="${backup_node} ${main_node}" ;; + esac } fi else @@ -206,15 +219,9 @@ start() { return fi while [ -n "$backup_node" ]; do - [ -f "$LOCK_FILE" ] && { - sleep 6s - continue - } check_process - touch $LOCK_FILE test_auto_switch "$backup_node" - rm -f $LOCK_FILE - sleep ${delay} + sleep ${delay} 9>&- done } diff --git a/luci-app-passwall/root/usr/share/passwall/test.sh b/luci-app-passwall/root/usr/share/passwall/test.sh index 48c7096d9..656c700b6 100755 --- a/luci-app-passwall/root/usr/share/passwall/test.sh +++ b/luci-app-passwall/root/usr/share/passwall/test.sh @@ -9,16 +9,19 @@ test_url() { local timeout=2 [ -n "$3" ] && timeout=$3 local extra_params=$4 + local status + local max_time=$((timeout + 3)) + local retry_max_time=$((max_time * (try + 1) + try)) curl --help all | grep "\-\-retry-all-errors" > /dev/null [ $? == 0 ] && extra_params="--retry-all-errors ${extra_params}" - status=$(/usr/bin/curl -I -o /dev/null -skL $extra_params --connect-timeout ${timeout} --retry ${try} -w %{http_code} "$url") + status=$(/usr/bin/curl -I -o /dev/null -skL $extra_params --connect-timeout ${timeout} --max-time ${max_time} --retry ${try} --retry-delay 1 --retry-max-time ${retry_max_time} -w %{http_code} "$url") || status=000 case "$status" in 204|\ 200) status=200 ;; esac - echo $status + printf '%s' "$status" } test_proxy() { @@ -42,43 +45,53 @@ test_proxy() { } url_test_node() { - result=0 + local result=0 local node_id=$1 - local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z') + local test_flag="url_test_${node_id}_$$" + local _address _port curlx _username _password _tmp_port probeUrl pid_file + local _type=$(config_n_get "$node_id" type | tr 'A-Z' 'a-z') + + set -- [ -n "${_type}" ] && { if [ "${_type}" == "socks" ]; then - local _address=$(config_n_get ${node_id} address) - local _port=$(config_n_get ${node_id} port) - [ -n "${_address}" ] && [ -n "${_port}" ] && { - local curlx="socks5h://${_address}:${_port}" - local _username=$(config_n_get ${node_id} username) - local _password=$(config_n_get ${node_id} password) - [ -n "${_username}" ] && [ -n "${_password}" ] && curlx="socks5h://${_username}:${_password}@${_address}:${_port}" - } + # 防止socks节点密码包含 #、% 等字符,将地址和认证信息分开传递 + _address=$(config_n_get "$node_id" address) + _port=$(config_n_get "$node_id" port) + [ -n "$_address" ] && [ -n "$_port" ] || { echo 0; return 1; } + case "$_address" in + \[*\]) ;; + *:*) _address="[$_address]" ;; + esac + curlx="socks5h://${_address}:${_port}" + _username=$(config_n_get "$node_id" username) + _password=$(config_n_get "$node_id" password) + [ -n "${_username}" ] && [ -n "${_password}" ] && set -- --proxy-user "${_username}:${_password}" else - local _tmp_port=$(get_new_port 48900 tcp,udp) - NO_REC_PROCESS=1 /usr/share/${CONFIG}/app.sh run_socks flag="url_test_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=url_test_${node_id}.json - local curlx="socks5h://127.0.0.1:${_tmp_port}" + _tmp_port=$(get_new_port $((48900 + $$ % 201)) tcp,udp) || { echo 0; return 1; } + NO_REC_PROCESS=1 /usr/share/${CONFIG}/app.sh run_socks flag="$test_flag" node="$node_id" bind=127.0.0.1 socks_port="$_tmp_port" config_file="${test_flag}.json" + curlx="socks5h://127.0.0.1:${_tmp_port}" fi sleep 2s - local probeUrl=$(config_n_get @global_other[0] url_test_url https://www.google.com/generate_204) - result=$(curl --connect-timeout 3 --max-time 5 -o /dev/null -I -skL -w "%{http_code}:%{time_pretransfer}" -x ${curlx} "${probeUrl}") + probeUrl=$(config_n_get @global_other[0] url_test_url https://www.google.com/generate_204) + result=$(curl --connect-timeout 3 --max-time 5 -o /dev/null -I -skL -w "%{http_code}:%{time_pretransfer}" "$@" -x "$curlx" "${probeUrl}") # 结束 SS 插件进程 - local pid_file="${TMP_PATH}/url_test_${node_id}_plugin.pid" - [ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1 - busybox pgrep -af "url_test_${node_id}" | awk '! /test\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1 - rm -rf ${TMP_PATH}/*url_test_${node_id}*.* + if [ "$_type" != "socks" ]; then + pid_file="${TMP_PATH}/${test_flag}_plugin.pid" + [ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1 + busybox pgrep -af "${TMP_PATH}/${test_flag}[._]" | awk '! /test\.sh/{print $1}' | xargs -r kill -9 >/dev/null 2>&1 + rm -f "$TMP_PATH/${test_flag}".* "$TMP_PATH/${test_flag}"_*.* + fi } - echo $result + printf '%s' "$result" } arg1=$1 shift case $arg1 in test_url) - test_url $@ + test_url "$@" ;; url_test_node) - url_test_node $@ + url_test_node "$@" ;; esac diff --git a/luci-app-passwall/root/usr/share/passwall/utils.sh b/luci-app-passwall/root/usr/share/passwall/utils.sh index fdc72d49b..3fb52dfa0 100755 --- a/luci-app-passwall/root/usr/share/passwall/utils.sh +++ b/luci-app-passwall/root/usr/share/passwall/utils.sh @@ -47,25 +47,24 @@ clean_log() { config_get_type() { local ret=$(uci -q get "${CONFIG}.${1}" 2>/dev/null) - echo "${ret:=$2}" + printf '%s' "${ret:=$2}" } config_n_get() { local ret=$(uci -q get "${CONFIG}.${1}.${2}" 2>/dev/null) - echo "${ret:=$3}" + printf '%s' "${ret:=$3}" } config_t_get() { local index=${4:-0} local ret=$(uci -q get "${CONFIG}.@${1}[${index}].${2}" 2>/dev/null) - echo "${ret:=${3}}" + printf '%s' "${ret:=${3}}" } eval_set_val() { - for i in $@; do - for j in $i; do - eval $j - done + local param + for param in "$@"; do + eval "${param%%=*}=\${param#*=}" done } @@ -87,13 +86,13 @@ lua_api() { } eval_cache_var() { - [ -s "$TMP_PATH/var" ] && eval $(cat "$TMP_PATH/var") + [ -s "$TMP_PATH/var" ] && . "$TMP_PATH/var" } del_cache_var() { local key="${1}" [ -n "${key}" ] && [ -f "${TMP_PATH}/var" ] && { - sed -i "/${key}=/d" $TMP_PATH/var >/dev/null 2>&1 + sed -i "/^${key}=/d" "$TMP_PATH/var" >/dev/null 2>&1 } } @@ -105,17 +104,17 @@ set_cache_var() { local val="$@" [ -n "${val}" ] && { [ ! -d $TMP_PATH ] && mkdir -p $TMP_PATH - echo "${key}=\"${val}\"" >> $TMP_PATH/var - eval ${key}=\"${val}\" + printf '%s=%s\n' "$key" "$(shell_quote "$val")" >> "$TMP_PATH/var" + eval "$key=\$val" } } } get_cache_var() { - local key="${1}" - [ -n "${key}" ] && [ -s "$TMP_PATH/var" ] && { - echo $(cat $TMP_PATH/var | grep "^${key}=" | awk -F '=' '{print $2}' | tail -n 1 | awk -F'"' '{print $2}') - } + [ -n "$1" ] && [ -s "$TMP_PATH/var" ] && ( + . "$TMP_PATH/var" + eval "printf '%s' \"\${$1-}\"" + ) } first_type() { @@ -157,18 +156,18 @@ get_host_ip() { local isip="" local ip="" if [ "$1" = "ipv6" ]; then - isip=$(echo $host | grep -Eo "$IPv6_REGEX") - if [ -n "$isip" ]; then - ip=$(echo "$host" | tr -d '[]') - fi + host=${host#[} + host=${host%]} + isip=$(printf '%s' "$host" | grep -E "^($IPv6_REGEX)$") + [ -n "$isip" ] && ip=$isip else - isip=$(echo $host | grep -Eo "$IPv4_REGEX") + isip=$(printf '%s' "$host" | grep -E "^($IPv4_REGEX)$") [ -n "$isip" ] && ip=$isip fi [ -z "$isip" ] && { local t=4 [ "$1" = "ipv6" ] && t=6 - local vpsrip=$(resolveip -$t -t $count $host | awk 'NR==1{print}') + local vpsrip=$(resolveip -$t -t "$count" "$host" | awk 'NR==1{print}') ip=$vpsrip } [ -n "$ip" ] && echo "$ip" @@ -192,19 +191,20 @@ get_ip_port_from() { local __portv=${1}; shift 1 local __ucipriority=${1}; shift 1 - local val1 val2 - val2=$(echo "$__host" | sed -n ' - s/^[^#]*[#]\([0-9]*\)$/\1/p; t; - s/^\(\[[^]]*\]\)[:]\([0-9]*\)$/\2/p; t; - s/^.*[:#]\([0-9]*\)$/\1/p - ') + local val1="$__host" val2 + case "$__host" in + *\#*) val1=${__host%#*}; val2=${__host##*#} ;; + \[*\]:*) val1=${__host%\]:*}; val2=${__host##*:} ;; + *:*:*) ;; + *:*) val1=${__host%:*}; val2=${__host##*:} ;; + esac if [ -n "${__ucipriority}" ]; then - val2=$(config_n_get ${__host} port "${val2}") - val1=$(config_n_get ${__host} address "${__host%%${val2:+[:#]${val2}*}}") - else - val1="${__host%%${val2:+[:#]${val2}*}}" + val2=$(config_n_get "$__host" port "$val2") + val1=$(config_n_get "$__host" address "$val1") fi - eval "${__ipv}=\"$val1\"; ${__portv}=\"$val2\"" + val1=${val1#[} + val1=${val1%]} + eval "${__ipv}=\$val1; ${__portv}=\$val2" } parse_doh() { @@ -237,20 +237,14 @@ parse_doh() { host_from_url(){ local f="${1}" - - ## Remove protocol part of url ## - f="${f##http://}" - f="${f##https://}" - f="${f##ftp://}" - f="${f##sftp://}" - - ## Remove username and/or username:password part of URL ## - f="${f##*:*@}" - f="${f##*@}" - - ## Remove rest of urls ## - f="${f%%/*}" - echo "${f%%:*}" + f=${f#*://} + f=${f%%[/?#]*} + f=${f##*@} + case "$f" in + \[*\]*) f=${f#\[}; f=${f%%\]*} ;; + *) f=${f%%:*} ;; + esac + printf '%s' "$f" } hosts_foreach() { @@ -268,6 +262,7 @@ hosts_foreach() { __ret=$? [ ${__ret} -ge ${ERROR_NO_CATCH:-1} ] && return ${__ret} done + return 0 } check_host() { @@ -354,6 +349,7 @@ get_new_port() { fi fi ([ "$port" -lt "$min_port" ] || [ "$port" -gt "$max_port" ]) && port=$default_start_port + local start_port=$port while :; do local result=$(check_port_exists "$port" "$protocol") if [ "$is_auto" = "1" ] && [ -n "$(get_cache_var "get_port_${port}")" ]; then @@ -364,13 +360,10 @@ get_new_port() { if [ "$port" -lt "$max_port" ]; then # If the port is smaller than the maximum port, increment by 1 and continue. port=$(expr "$port" + 1) - elif [ "$port" -gt "$min_port" ]; then - # If the port is greater than the minimum port, decrement by 1 and continue. - port=$(expr "$port" - 1) else - # Otherwise, reassign the default starting port. - port=$default_start_port + port=$min_port fi + [ "$port" -eq "$start_port" ] && return 1 done if [ "$is_auto" = "1" ]; then # Set cache to prevent the port from being allocated again. @@ -432,11 +425,16 @@ add_ip2route() { [ -z "${device}" ] && device="$2" if [ -n "${gateway}" ]; then - route add -host ${ip} gw ${gateway} dev ${device} >/dev/null 2>&1 - echo "$ip" >> $TMP_ROUTE_PATH/${device} - echolog " - [${remarks}]添加到接口[${device}]路由表成功!" + if route add -host "$ip" gw "$gateway" dev "$device" >/dev/null 2>&1; then + printf '%s\n' "$ip" >> "$TMP_ROUTE_PATH/$device" + echolog " - [${remarks}]添加到接口[${device}]路由表成功!" + else + echolog " - [${remarks}]添加到接口[${device}]路由表失败!" + return 1 + fi else - echolog " - [${remarks}]添加到接口[${device}]路由表失功!原因是找不到[${device}]网关。" + echolog " - [${remarks}]添加到接口[${device}]路由表失败!原因是找不到[${device}]网关。" + return 1 fi } @@ -451,12 +449,26 @@ delete_ip2route() { } } +shell_quote() { + printf "'" + printf '%s' "$1" | sed "s/'/'\\\\''/g" + printf "'" +} + +get_process_start_time() { + sed 's/.*) //' "/proc/$1/stat" 2>/dev/null | awk '{print $20}' +} + ln_run() { local file_func=${1} local ln_name=${2} local output=${3} shift 3; + case "$ln_name" in + dnsmasq*) set -- -k "$@" ;; + haproxy) set -- -db "$@" ;; + esac if [ "${file_func%%/*}" != "${file_func}" ]; then [ ! -L "${file_func}" ] && { ln -s "${file_func}" "${TMP_BIN_PATH}/${ln_name}" >/dev/null 2>&1 @@ -470,12 +482,20 @@ ln_run() { return 1 } - ${file_func:-echolog " - ${ln_name}"} "$@" >${output} 2>&1 & + "$file_func" "$@" >"$output" 2>&1 & + local pid=$! [ "$NO_REC_PROCESS" = "1" ] && return - process_count=$(ls $TMP_SCRIPT_FUNC_PATH | wc -l) - process_count=$((process_count + 1)) - echo "${file_func:-echolog " - ${ln_name}"} $@ >${output}" > $TMP_SCRIPT_FUNC_PATH/$process_count + local process_file=$(mktemp "$TMP_SCRIPT_FUNC_PATH/XXXXXX") + local arg + { + printf '%s\n' "$pid" "$(get_process_start_time "$pid")" + printf '%s' "$(shell_quote "$file_func")" + for arg in "$@"; do + printf ' %s' "$(shell_quote "$arg")" + done + printf ' >%s 2>&1\n' "$(shell_quote "$output")" + } > "$process_file" } kill_all() { @@ -504,26 +524,24 @@ gen_lanlist_6() { get_wan_ips() { local family="$1" local NET_ADDR - local iface + local iface addr addrs local INTERFACES=$(ubus call network.interface dump | jsonfilter -e \ - '@.interface[!(@.interface ~ /lan/) && !(@.l3_device ~ /\./) && @.route[0]].interface') + '@.interface[!(@.interface ~ /lan/) && @.route[0]].interface') for iface in $INTERFACES; do - local addr if [ "$family" = "ip6" ]; then - network_get_ipaddr6 addr "$iface" - case "$addr" in - ""|fe80*) continue ;; - esac + network_get_ipaddrs6 addrs "$iface" else - network_get_ipaddr addr "$iface" - case "$addr" in - ""|"0.0.0.0") continue ;; - esac + network_get_ipaddrs addrs "$iface" fi - case " $NET_ADDR " in - *" $addr "*) ;; - *) NET_ADDR="${NET_ADDR:+$NET_ADDR }$addr" ;; - esac + for addr in $addrs; do + case "$addr" in + ""|0.0.0.0|::|fe80:*) continue ;; + esac + case " $NET_ADDR " in + *" $addr "*) ;; + *) NET_ADDR="${NET_ADDR:+$NET_ADDR }$addr" ;; + esac + done done echo "$NET_ADDR" }