mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-09-14 20:34:19 +08:00
277 lines
10 KiB
Bash
Executable File
277 lines
10 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
. /usr/lib/hijpass/app-logger.sh
|
|
. /lib/functions/network.sh
|
|
|
|
log_debug "$0"
|
|
|
|
TPROXY_MARK=0x1
|
|
TPROXY_SHUNT_MARK=0x3
|
|
TPROXY_PROTO=$(uci -q get hijpass.@firewall[0].tproxy_proto)
|
|
TPROXY_SHUNT_PORT=$(uci -q get hijpass.@firewall[0].shunt_port)
|
|
TPROXY_PORT=$(uci -q get hijpass.@firewall[0].proxy_port)
|
|
DNS_FORWARD_SOURCE=$(uci -q get hijpass.@firewall[0].dns_forward || :)
|
|
DNS_SERVICE=$(uci -q get hijpass.@dns[0].dns_service || :)
|
|
DNS_FORWARD_PORT=
|
|
|
|
is_valid_port() {
|
|
[ "$1" -ge 1 ] 2>/dev/null && [ "$1" -le 65535 ] 2>/dev/null
|
|
}
|
|
|
|
case "$DNS_FORWARD_SOURCE" in
|
|
""|none)
|
|
;;
|
|
pre-routing)
|
|
if [ "$DNS_SERVICE" = "chinadns-ng" ]; then
|
|
DNS_FORWARD_PORT=$(uci -q get hijpass.@dns[0].cdg_port || :)
|
|
else
|
|
log_warn "Independent DNS forwarding target is unavailable"
|
|
fi
|
|
;;
|
|
routing)
|
|
if [ "$(uci -q get hijpass.@shunt[0].enabled || :)" != "0" ]; then
|
|
DNS_FORWARD_PORT=$(uci -q get hijpass.@shunt[0].dns_listen_port || :)
|
|
else
|
|
log_warn "Core DNS forwarding target is disabled"
|
|
fi
|
|
;;
|
|
*)
|
|
log_warn "Unknown DNS forwarding source: $DNS_FORWARD_SOURCE"
|
|
;;
|
|
esac
|
|
|
|
if [ -n "$DNS_FORWARD_PORT" ] && ! is_valid_port "$DNS_FORWARD_PORT"; then
|
|
log_warn "Invalid DNS forwarding port: $DNS_FORWARD_PORT"
|
|
DNS_FORWARD_PORT=
|
|
fi
|
|
|
|
if [ -z "$TPROXY_SHUNT_PORT" ] && [ -z "$TPROXY_PORT" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
RESOLV_FILE=$(uci -q get dhcp.@dnsmasq[0].resolvfile || :)
|
|
IP_DIRECT_CONF=$(uci -q get hijpass.@hijpass[0].ip_direct || :)
|
|
IP_PROXY_CONF=$(uci -q get hijpass.@hijpass[0].ip_proxy || :)
|
|
CHN_ROUTE_FILE=$(uci -q get hijpass.@hijpass[0].chn_route || :)
|
|
CHN_ROUTE6_FILE=$(uci -q get hijpass.@hijpass[0].chn_route6 || :)
|
|
ENABLE_CHN_ROUTE=$(uci -q get hijpass.@firewall[0].use_chnroute || :)
|
|
ENABLE_GFW_LIST=$(uci -q get hijpass.@dns[0].use_gfw || :)
|
|
ENABLE_CHN_LIST=$(uci -q get hijpass.@dns[0].use_chn || :)
|
|
PROXY_MAC=$(uci -q get hijpass.@firewall[0].proxy_mac_list || :)
|
|
PROXY_MAC_EXCLUDE=$(uci -q get hijpass.@firewall[0].proxy_mac_exclude_list || :)
|
|
PROXY_INTERFACE=$(uci -q get hijpass.@firewall[0].proxy_iface_list || :)
|
|
PROXY_INTERFACE_EXCLUDE=$(uci -q get hijpass.@firewall[0].proxy_iface_exclude_list || :)
|
|
ACL_DEFAULT_ALLOW=$(uci -q get hijpass.@firewall[0].acl_default_allow || :)
|
|
PROXY_LOCAL=$(uci -q get hijpass.@firewall[0].proxy_local || :)
|
|
|
|
LUA_SCRIPT="/usr/lib/hijpass/luci-utils.lua"
|
|
CONF_PATH="/etc/hijpass"
|
|
HIJPASS_USER="hijpass"
|
|
|
|
network_flush_cache
|
|
network_find_wan NET_IF
|
|
network_find_wan6 NET_IF6
|
|
network_get_physdev NET_L2D "${NET_IF}"
|
|
network_get_physdev NET_L2D6 "${NET_IF6}"
|
|
|
|
WAN_DEVICE_NAMES=
|
|
append_wan_device() {
|
|
local wan_device="$1"
|
|
[ -z "$wan_device" ] && return
|
|
case " $WAN_DEVICE_NAMES " in
|
|
*" $wan_device "*) return ;;
|
|
esac
|
|
WAN_DEVICE_NAMES="$WAN_DEVICE_NAMES $wan_device"
|
|
}
|
|
|
|
for wan_device in $(fw4 zone wan 2>/dev/null | sort -u); do
|
|
append_wan_device "$wan_device"
|
|
done
|
|
for wan_device in $NET_L2D $NET_L2D6; do
|
|
[ "$wan_device" = "br-lan" ] || append_wan_device "$wan_device"
|
|
done
|
|
|
|
INPUT_WAN_L2_DEV=
|
|
for wan_device in $WAN_DEVICE_NAMES; do
|
|
escaped_device=$(printf '%s' "$wan_device" | sed 's/\\/\\\\/g; s/"/\\"/g')
|
|
if [ -n "$INPUT_WAN_L2_DEV" ]; then
|
|
INPUT_WAN_L2_DEV="$INPUT_WAN_L2_DEV, "
|
|
fi
|
|
INPUT_WAN_L2_DEV="${INPUT_WAN_L2_DEV}\"${escaped_device}\""
|
|
done
|
|
|
|
FW4_TEMPLATE=$(cat "$CONF_PATH/fw4-template.nft")
|
|
|
|
log_debug "Generating fw4 rules with mark:$TPROXY_MARK proxy port:$TPROXY_PORT shunt port:$TPROXY_SHUNT_PORT proto:$TPROXY_PROTO"
|
|
|
|
IP_DIRECT_LIST=$([ -f "$IP_DIRECT_CONF" ] && cat "$IP_DIRECT_CONF" | grep -v -e '^\s*$' -e '^\s*#' || :)
|
|
IP_PROXY_LIST=$([ -f "$IP_PROXY_CONF" ] && cat "$IP_PROXY_CONF" | grep -v -e '^\s*$' -e '^\s*#' || :)
|
|
|
|
IP4_DIRECT_LIST=
|
|
IP6_DIRECT_LIST=
|
|
IP4_PROXY_LIST=
|
|
IP6_PROXY_LIST=
|
|
|
|
for ip in $IP_DIRECT_LIST; do
|
|
type=$(lua "$LUA_SCRIPT" "iptype" "$ip")
|
|
if [ "$type" = "4" ]; then
|
|
IP4_DIRECT_LIST="$IP4_DIRECT_LIST
|
|
$ip"
|
|
elif [ "$type" = "6" ]; then
|
|
IP6_DIRECT_LIST="$IP6_DIRECT_LIST
|
|
$ip"
|
|
else
|
|
log_warn "Invalid IP address: $ip"
|
|
fi
|
|
done
|
|
|
|
for ip in $IP_PROXY_LIST; do
|
|
type=$(lua "$LUA_SCRIPT" "iptype" "$ip")
|
|
if [ "$type" = "4" ]; then
|
|
IP4_PROXY_LIST="$IP4_PROXY_LIST
|
|
$ip"
|
|
elif [ "$type" = "6" ]; then
|
|
IP6_PROXY_LIST="$IP6_PROXY_LIST
|
|
$ip"
|
|
else
|
|
log_warn "Invalid IP address: $ip"
|
|
fi
|
|
done
|
|
|
|
DNS_V4=
|
|
DNS_V6=
|
|
|
|
if [ -f "$RESOLV_FILE" ]; then
|
|
DNS_V4=$(grep <"$RESOLV_FILE" -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | sort -u | grep -v 0.0.0.0 | grep -v 127.0.0.1)
|
|
DNS_V6=$(grep <"$RESOLV_FILE" -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | awk -F % '{print $1}' | awk -F " " '{print $2}' | sort -u | grep -v -Fx ::1 | grep -v -Fx ::)
|
|
fi
|
|
|
|
LOCAL_V4_CIDR=$(ip address | grep -w inet | awk '{print $2}')
|
|
LOCAL_V6_CIDR=$(ip address | grep -w inet6 | awk '{print $2}')
|
|
|
|
CHN_ROUTE=
|
|
CHN_ROUTE6=
|
|
|
|
if [ "$ENABLE_CHN_ROUTE" = "1" ]; then
|
|
CHN_ROUTE=$([ -f "$CHN_ROUTE_FILE" ] && cat "$CHN_ROUTE_FILE" | grep -v -e '^\s*$' -e '^\s*#' | sort -u | awk 'NF {printf "%s,\n", $0}' | sed '$ s/,$//' || :)
|
|
CHN_ROUTE6=$([ -f "$CHN_ROUTE6_FILE" ] && cat "$CHN_ROUTE6_FILE" | grep -v -e '^\s*$' -e '^\s*#' | sort -u | awk 'NF {printf "%s,\n", $0}' | sed '$ s/,$//' || :)
|
|
fi
|
|
|
|
IP4_DIRECT_NFT_LIST=$(echo "$DNS_V4
|
|
$IP4_DIRECT_LIST
|
|
$LOCAL_V4_CIDR
|
|
" | sort -u | awk 'NF {printf "%s,\n", $0}' | sed '$ s/,$//')
|
|
|
|
IP6_DIRECT_NFT_LIST=$(echo "$DNS_V6
|
|
$IP6_DIRECT_LIST
|
|
$LOCAL_V6_CIDR
|
|
" | sort -u | awk 'NF {printf "%s,\n", $0}' | sed '$ s/,$//')
|
|
|
|
IP4_PROXY_NFT_LIST=$(echo "$IP4_PROXY_LIST" | sort -u | awk 'NF {printf "%s,\n", $0}' | sed '$ s/,$//')
|
|
IP6_PROXY_NFT_LIST=$(echo "$IP6_PROXY_LIST" | sort -u | awk 'NF {printf "%s,\n", $0}' | sed '$ s/,$//')
|
|
|
|
[ -n "$PROXY_INTERFACE" ] && PROXY_INTERFACE="${PROXY_INTERFACE// /,}"
|
|
[ -n "$PROXY_INTERFACE_EXCLUDE" ] && PROXY_INTERFACE_EXCLUDE="${PROXY_INTERFACE_EXCLUDE// /,}"
|
|
[ -n "$PROXY_MAC" ] && PROXY_MAC="${PROXY_MAC// /,}"
|
|
[ -n "$PROXY_MAC_EXCLUDE" ] && PROXY_MAC_EXCLUDE="${PROXY_MAC_EXCLUDE// /,}"
|
|
|
|
fw_rules="
|
|
define DNS_FORWARD_PORT = $DNS_FORWARD_PORT
|
|
define HIJPASS_USER = $HIJPASS_USER
|
|
define TPROXY_MARK = $TPROXY_MARK
|
|
define TPROXY_PORT = $TPROXY_PORT
|
|
define TPROXY_SHUNT_MARK = $TPROXY_SHUNT_MARK
|
|
define TPROXY_SHUNT_PORT = $TPROXY_SHUNT_PORT
|
|
define TPROXY_PROTO = { $TPROXY_PROTO }
|
|
define WAN_DEV = { $INPUT_WAN_L2_DEV }
|
|
define IP4_DIRECT_NFT_LIST = { $IP4_DIRECT_NFT_LIST }
|
|
define IP6_DIRECT_NFT_LIST = { $IP6_DIRECT_NFT_LIST }
|
|
define IP4_PROXY_NFT_LIST = { $IP4_PROXY_NFT_LIST }
|
|
define IP6_PROXY_NFT_LIST = { $IP6_PROXY_NFT_LIST }
|
|
define IP4_CHNROUTE_LIST = { $CHN_ROUTE }
|
|
define IP6_CHNROUTE_LIST = { $CHN_ROUTE6 }
|
|
define PROXY_INTERFACE = { $PROXY_INTERFACE }
|
|
define PROXY_INTERFACE_EXCLUDE = { $PROXY_INTERFACE_EXCLUDE }
|
|
define PROXY_MAC = { $PROXY_MAC }
|
|
define PROXY_MAC_EXCLUDE = { $PROXY_MAC_EXCLUDE }
|
|
|
|
$FW4_TEMPLATE
|
|
"
|
|
|
|
if [ -z "$DNS_FORWARD_PORT" ]; then
|
|
fw_rules=$(echo "$fw_rules" | grep -v "DNS_FORWARD_")
|
|
fw_rules=$(echo "$fw_rules" | sed '/^ chain dns-forward {/,/^ }/d')
|
|
fw_rules=$(echo "$fw_rules" | sed '/^ chain dns-forward-output {/,/^ }/d')
|
|
elif [ "$PROXY_LOCAL" != "1" ]; then
|
|
fw_rules=$(echo "$fw_rules" | sed '/^ chain dns-forward-output {/,/^ }/d')
|
|
fi
|
|
|
|
if [ "$PROXY_LOCAL" != "1" ]; then
|
|
fw_rules=$(echo "$fw_rules" | sed '/^ chain out-route {/,/^ }/d')
|
|
fi
|
|
|
|
if [ -z "$INPUT_WAN_L2_DEV" ]; then
|
|
fw_rules=$(echo "$fw_rules" | grep -v 'define WAN_DEV =')
|
|
fw_rules=$(echo "$fw_rules" | grep -v 'iifname $WAN_DEV counter return')
|
|
fi
|
|
|
|
if [ -z "$TPROXY_SHUNT_PORT" ]; then
|
|
fw_rules=$(echo "$fw_rules" | grep -v "TPROXY_SHUNT_PORT")
|
|
fw_rules=$(echo "$fw_rules" | grep -v "shunt mark")
|
|
fw_rules=$(echo "$fw_rules" | grep -v "@chnroute")
|
|
fw_rules=$(echo "$fw_rules" | grep -Ev "@chn.list")
|
|
fi
|
|
|
|
if [ -z "$TPROXY_PORT" ]; then
|
|
fw_rules=$(echo "$fw_rules" | grep -v "TPROXY_PORT")
|
|
fi
|
|
|
|
if [ -z "$ENABLE_CHN_ROUTE" ]; then
|
|
fw_rules=$(echo "$fw_rules" | grep -v "@chnroute")
|
|
fw_rules=$(echo "$fw_rules" | sed '/set chnroute.list {/,/^ }/d')
|
|
fi
|
|
|
|
if [ -z "$ENABLE_GFW_LIST" ]; then
|
|
fw_rules=$(echo "$fw_rules" | grep -v "@gfw")
|
|
fw_rules=$(echo "$fw_rules" | sed '/set gfw.list {/,/^ }/d')
|
|
fi
|
|
|
|
if [ -z "$ENABLE_CHN_LIST" ]; then
|
|
fw_rules=$(echo "$fw_rules" | grep -Ev "@chn.list")
|
|
fw_rules=$(echo "$fw_rules" | sed '/set chn.list {/,/^ }/d')
|
|
fi
|
|
|
|
if [ "$DNS_SERVICE" = "custom" ]; then
|
|
fw_rules=$(echo "$fw_rules" | grep -Ev "@dns.*\dlist")
|
|
fw_rules=$(echo "$fw_rules" | sed '/set dns.*\dlist {/,/^ }/d')
|
|
fi
|
|
|
|
if [ "$ACL_DEFAULT_ALLOW" = "1" ]; then
|
|
# 默认全代理模式:移除 deny 模式规则和 proxy 集合
|
|
fw_rules=$(echo "$fw_rules" | grep -v "iif != @proxy_interface_list ether saddr != @proxy_mac_list")
|
|
fw_rules=$(echo "$fw_rules" | sed '/set proxy_mac_list {/,/^ }/d')
|
|
fw_rules=$(echo "$fw_rules" | sed '/set proxy_interface_list {/,/^ }/d')
|
|
fw_rules=$(echo "$fw_rules" | grep -v "define PROXY_INTERFACE =")
|
|
fw_rules=$(echo "$fw_rules" | grep -v "define PROXY_MAC =")
|
|
if [ -z "$PROXY_MAC_EXCLUDE" ]; then
|
|
fw_rules=$(echo "$fw_rules" | grep -v "ether saddr @proxy_mac_exclude_list")
|
|
fw_rules=$(echo "$fw_rules" | sed '/set proxy_mac_exclude_list {/,/^ }/d')
|
|
fw_rules=$(echo "$fw_rules" | grep -v "define PROXY_MAC_EXCLUDE =")
|
|
fi
|
|
if [ -z "$PROXY_INTERFACE_EXCLUDE" ]; then
|
|
fw_rules=$(echo "$fw_rules" | grep -v "iif @proxy_interface_exclude_list")
|
|
fw_rules=$(echo "$fw_rules" | sed '/set proxy_interface_exclude_list {/,/^ }/d')
|
|
fw_rules=$(echo "$fw_rules" | grep -v "define PROXY_INTERFACE_EXCLUDE =")
|
|
fi
|
|
else
|
|
# 默认不代理模式:移除 allow 模式规则和 exclude 集合
|
|
fw_rules=$(echo "$fw_rules" | grep -v "iif @proxy_interface_exclude_list")
|
|
fw_rules=$(echo "$fw_rules" | grep -v "ether saddr @proxy_mac_exclude_list")
|
|
fw_rules=$(echo "$fw_rules" | sed '/set proxy_mac_exclude_list {/,/^ }/d')
|
|
fw_rules=$(echo "$fw_rules" | sed '/set proxy_interface_exclude_list {/,/^ }/d')
|
|
fw_rules=$(echo "$fw_rules" | grep -v "define PROXY_MAC_EXCLUDE =")
|
|
fw_rules=$(echo "$fw_rules" | grep -v "define PROXY_INTERFACE_EXCLUDE =")
|
|
fi
|
|
|
|
echo "$fw_rules"
|