mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-29 20:05:13 +08:00
💐 Sync 2026-10-06 12:33:44
This commit is contained in:
1 parent
8be03ce939
commit
7fe69dbb3a
246 files changed
+50330
-3414
No files matched your search
@@ -3,7 +3,7 @@ config flowproxy 'global'
|
||||
option tcp_enabled '1'
|
||||
option udp_enabled '1'
|
||||
option proxy_server_ip_addr ''
|
||||
option interface 'br-lan'
|
||||
option interface 'auto'
|
||||
option traffic_mark '0x666'
|
||||
option routing_table '888'
|
||||
option rule_priority '1000'
|
||||
|
||||
@@ -6,7 +6,20 @@
|
||||
enabled=$(uci -q get flowproxy.global.enabled || echo 0)
|
||||
[ "$enabled" = "1" ] || exit 0
|
||||
|
||||
target_iface=$(uci -q get flowproxy.global.interface || echo "br-lan")
|
||||
proxy_ip=$(uci -q get flowproxy.global.proxy_server_ip_addr)
|
||||
[ -n "$proxy_ip" ] || exit 0
|
||||
|
||||
target_iface=""
|
||||
if [ -f "/var/run/flowproxy.mark" ]; then
|
||||
target_iface=$(cut -d':' -f4 /var/run/flowproxy.mark 2>/dev/null)
|
||||
fi
|
||||
if [ -z "$target_iface" ]; then
|
||||
target_iface=$(uci -q get flowproxy.global.interface)
|
||||
if [ -z "$target_iface" ] || [ "$target_iface" = "auto" ]; then
|
||||
target_iface=$(ip route get "$proxy_ip" 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="dev") {print $(i+1); exit}}')
|
||||
fi
|
||||
fi
|
||||
target_iface="${target_iface:-br-lan}"
|
||||
|
||||
if [ "$DEVICE" = "$target_iface" ] || [ "$INTERFACE" = "$target_iface" ]; then
|
||||
[ -x /etc/init.d/flowproxy ] && /etc/init.d/flowproxy add_route
|
||||
|
||||
@@ -126,10 +126,14 @@ apply_nft_rules() {
|
||||
FLOWPROXY_LOG_LEVEL="$conf_level" "$GENERATE_SCRIPT" >/dev/null 2> "$err_file"
|
||||
local ret=$?
|
||||
|
||||
# 将脚本的输出记录到日志
|
||||
# 将脚本的输出记录到日志:成功时按 debug 输出,失败时按 error 输出
|
||||
if [ -s "$err_file" ]; then
|
||||
while read -r line; do
|
||||
log_msg debug "Script: $line"
|
||||
if [ $ret -eq 0 ]; then
|
||||
log_msg debug "Script: $line"
|
||||
else
|
||||
log_msg error "Generator: $line"
|
||||
fi
|
||||
done < "$err_file"
|
||||
rm -f "$err_file"
|
||||
fi
|
||||
@@ -138,14 +142,16 @@ apply_nft_rules() {
|
||||
log_msg info "Applying nftables rules from $NFT_CONF"
|
||||
# 确保内核支持 inet 表
|
||||
nft delete table inet flowproxy 2>/dev/null
|
||||
if nft -f "$NFT_CONF"; then
|
||||
local nft_err
|
||||
nft_err=$(nft -f "$NFT_CONF" 2>&1)
|
||||
if [ $? -eq 0 ]; then
|
||||
return 0
|
||||
else
|
||||
log_msg error "nftables rules application failed (syntax error)"
|
||||
log_msg error "nftables rules application failed: $nft_err"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_msg error "Failed to generate nftables config"
|
||||
log_msg error "Failed to generate nftables config (exit code: $ret)"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
@@ -154,12 +160,26 @@ apply_nft_rules() {
|
||||
fi
|
||||
}
|
||||
|
||||
get_proxy_interface() {
|
||||
local proxy_ip="$1"
|
||||
local cfg_iface=$(uci -q get "$UCI_CONFIG.global.interface")
|
||||
if [ -n "$cfg_iface" ] && [ "$cfg_iface" != "auto" ]; then
|
||||
echo "$cfg_iface"
|
||||
return
|
||||
fi
|
||||
|
||||
local auto_dev=""
|
||||
if [ -n "$proxy_ip" ]; then
|
||||
auto_dev=$(ip route get "$proxy_ip" 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="dev") {print $(i+1); exit}}')
|
||||
fi
|
||||
echo "${auto_dev:-br-lan}"
|
||||
}
|
||||
|
||||
add_route() {
|
||||
check_config || return 1
|
||||
|
||||
local proxy_server_ip_addr=$(uci -q get "$UCI_CONFIG.global.proxy_server_ip_addr")
|
||||
local interface=$(uci -q get "$UCI_CONFIG.global.interface")
|
||||
interface="${interface:-br-lan}"
|
||||
local interface=$(get_proxy_interface "$proxy_server_ip_addr")
|
||||
local traffic_mark=$(uci -q get "$UCI_CONFIG.global.traffic_mark")
|
||||
traffic_mark="${traffic_mark:-0x666}"
|
||||
local routing_table=$(uci -q get "$UCI_CONFIG.global.routing_table")
|
||||
@@ -170,23 +190,30 @@ add_route() {
|
||||
# 1. 先尝试用旧记录清理一次,防止由于配置变更导致的残留
|
||||
delete_route "quiet"
|
||||
|
||||
log_msg info "Setting up routing table $routing_table and rule for mark $traffic_mark with priority $rule_priority..."
|
||||
log_msg info "Setting up routing table $routing_table (dev: $interface) and rule for mark $traffic_mark with priority $rule_priority..."
|
||||
|
||||
# 2. 记录当前使用的标记值、路由表 ID 和优先级
|
||||
echo "$traffic_mark:$routing_table:$rule_priority" > "/var/run/flowproxy.mark"
|
||||
# 2. 记录当前使用的标记值、路由表 ID、优先级和实际出口网卡
|
||||
echo "$traffic_mark:$routing_table:$rule_priority:$interface" > "/var/run/flowproxy.mark"
|
||||
|
||||
# 3. 再次确保新标记和表的规则是干净的
|
||||
while ip rule del fwmark "$traffic_mark" lookup "$routing_table" 2>/dev/null; do :; done
|
||||
ip route flush table "$routing_table" 2>/dev/null
|
||||
|
||||
# 4. 添加路由和策略
|
||||
local err
|
||||
ip route add default via "$proxy_server_ip_addr" dev "$interface" table "$routing_table" 2>/dev/null
|
||||
err=$(ip rule add fwmark "$traffic_mark" lookup "$routing_table" priority "$rule_priority" 2>&1)
|
||||
local route_err rule_err
|
||||
route_err=$(ip route add default via "$proxy_server_ip_addr" dev "$interface" table "$routing_table" 2>&1)
|
||||
if [ $? -ne 0 ]; then
|
||||
log_msg error "Failed to add default route to table $routing_table via $proxy_server_ip_addr (dev: $interface): $route_err"
|
||||
log_msg error "Proxy server IP $proxy_server_ip_addr is unreachable or has no valid route on interface $interface"
|
||||
return 1
|
||||
fi
|
||||
|
||||
rule_err=$(ip rule add fwmark "$traffic_mark" lookup "$routing_table" priority "$rule_priority" 2>&1)
|
||||
if [ $? -eq 0 ]; then
|
||||
log_msg info "Route added: via $proxy_server_ip_addr dev $interface table $routing_table for mark $traffic_mark with priority $rule_priority"
|
||||
else
|
||||
log_msg error "Failed to add ip rule: $err"
|
||||
log_msg error "Failed to add ip rule: $rule_err"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 5. 禁用目标网卡的 ICMP 重定向通告,防止客户端绕行或 TCP 连接挂起
|
||||
@@ -201,12 +228,13 @@ delete_route() {
|
||||
local quiet="$1"
|
||||
|
||||
# 1. 获取两组清理目标:旧值(记录文件) 和 新值(当前UCI)
|
||||
local old_mark="" old_table="" old_prio=""
|
||||
local old_mark="" old_table="" old_prio="" old_iface=""
|
||||
if [ -f "/var/run/flowproxy.mark" ]; then
|
||||
local saved_val=$(cat "/var/run/flowproxy.mark")
|
||||
old_mark=$(echo "$saved_val" | cut -d':' -f1)
|
||||
old_table=$(echo "$saved_val" | cut -d':' -f2)
|
||||
old_prio=$(echo "$saved_val" | cut -d':' -f3)
|
||||
old_iface=$(echo "$saved_val" | cut -d':' -f4)
|
||||
[ "$quiet" != "quiet" ] && rm -f "/var/run/flowproxy.mark"
|
||||
fi
|
||||
|
||||
@@ -216,8 +244,7 @@ delete_route() {
|
||||
curr_table="${curr_table:-888}"
|
||||
local curr_prio=$(uci -q get "$UCI_CONFIG.global.rule_priority")
|
||||
curr_prio="${curr_prio:-1000}"
|
||||
local curr_iface=$(uci -q get "$UCI_CONFIG.global.interface")
|
||||
curr_iface="${curr_iface:-br-lan}"
|
||||
local curr_iface=$(get_proxy_interface "$(uci -q get "$UCI_CONFIG.global.proxy_server_ip_addr")")
|
||||
|
||||
[ "$quiet" != "quiet" ] && log_msg info "Cleaning up FlowProxy routes (Atomic Mode)..."
|
||||
|
||||
@@ -249,9 +276,10 @@ delete_route() {
|
||||
safe_del_rule "$curr_mark" "$curr_table" "$curr_prio"
|
||||
|
||||
# 恢复 ICMP 重定向通告
|
||||
if [ -d "/proc/sys/net/ipv4/conf/$curr_iface" ]; then
|
||||
[ -n "$old_iface" ] && [ -d "/proc/sys/net/ipv4/conf/$old_iface" ] && \
|
||||
sysctl -w "net.ipv4.conf.$old_iface.send_redirects=1" >/dev/null 2>&1
|
||||
[ -n "$curr_iface" ] && [ "$curr_iface" != "$old_iface" ] && [ -d "/proc/sys/net/ipv4/conf/$curr_iface" ] && \
|
||||
sysctl -w "net.ipv4.conf.$curr_iface.send_redirects=1" >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
delete_nft() {
|
||||
@@ -320,10 +348,14 @@ start_service() {
|
||||
|
||||
if [ "$enabled" -eq 0 ]; then
|
||||
log_msg info "FlowProxy is disabled, ensuring service is stopped"
|
||||
[ -x /etc/init.d/flowproxy ] && /etc/init.d/flowproxy disable 2>/dev/null
|
||||
stop_service
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 状态自愈:当 enabled=1 时,确保服务已在 rc.d 中 enable,防止 luci-reload 因未启用而静默跳过执行
|
||||
[ -x /etc/init.d/flowproxy ] && /etc/init.d/flowproxy enable 2>/dev/null
|
||||
|
||||
log_msg info "Starting FlowProxy..."
|
||||
|
||||
check_env || return 1
|
||||
@@ -331,11 +363,15 @@ start_service() {
|
||||
|
||||
local proxy_server_ip_addr=$(uci -q get "$UCI_CONFIG.global.proxy_server_ip_addr")
|
||||
local proxy_server_dns_port=$(uci -q get "$UCI_CONFIG.global.proxy_server_dns_port" || echo 5353)
|
||||
local interface=$(uci -q get "$UCI_CONFIG.global.interface" || echo "br-lan")
|
||||
local interface=$(get_proxy_interface "$proxy_server_ip_addr")
|
||||
probe_proxy_server "$proxy_server_ip_addr" "$proxy_server_dns_port" "$interface"
|
||||
|
||||
apply_nft_rules || return 1
|
||||
add_route
|
||||
if ! add_route; then
|
||||
log_msg error "Routing setup failed, aborting and cleaning up service..."
|
||||
stop_service
|
||||
return 1
|
||||
fi
|
||||
setup_dns
|
||||
|
||||
touch "$STATE_FILE"
|
||||
@@ -344,6 +380,10 @@ start_service() {
|
||||
|
||||
stop_service() {
|
||||
log_msg info "Stopping FlowProxy..."
|
||||
local enabled=$(uci -q get "$UCI_CONFIG.global.enabled" || echo 0)
|
||||
if [ "$enabled" -eq 0 ]; then
|
||||
[ -x /etc/init.d/flowproxy ] && /etc/init.d/flowproxy disable 2>/dev/null
|
||||
fi
|
||||
# 强制先移除标记,防止状态误报
|
||||
rm -f "$STATE_FILE"
|
||||
delete_route
|
||||
@@ -368,7 +408,11 @@ service_triggers() {
|
||||
procd_add_reload_trigger "$UCI_CONFIG"
|
||||
# 监听防火墙重载事件,防止规则被 fw4 清空后无法自动恢复
|
||||
procd_add_reload_trigger "firewall"
|
||||
# 监听网络接口事件
|
||||
local iface=$(uci -q get "$UCI_CONFIG.global.interface" || echo "br-lan")
|
||||
procd_add_reload_interface_trigger "$iface"
|
||||
# 监听网络接口事件(procd trigger 需接收 UCI 逻辑网络名,如 lan/wan)
|
||||
local dev=$(get_proxy_interface "$(uci -q get "$UCI_CONFIG.global.proxy_server_ip_addr")")
|
||||
local net_name=""
|
||||
if command -v ubus >/dev/null 2>&1 && [ -n "$dev" ]; then
|
||||
net_name=$(ubus call network.interface dump 2>/dev/null | jsonfilter -e "@.interface[@.device=\"$dev\"].interface" -e "@.interface[@.l3_device=\"$dev\"].interface" 2>/dev/null | head -n 1)
|
||||
fi
|
||||
procd_add_reload_interface_trigger "${net_name:-lan}"
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
[ ! -f "/usr/share/ucitrack/luci-app-flowproxy.json" ] && {
|
||||
cat > /usr/share/ucitrack/luci-app-flowproxy.json << EEOF
|
||||
{
|
||||
"config": "flowproxy",
|
||||
"init": "flowproxy"
|
||||
}
|
||||
EEOF
|
||||
}
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@flowproxy[-1]
|
||||
add ucitrack flowproxy
|
||||
set ucitrack.@flowproxy[-1].init=flowproxy
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
/etc/init.d/flowproxy enabled || /etc/init.d/flowproxy enable 2>/dev/null
|
||||
|
||||
rm -f /tmp/luci-indexcache* 2>/dev/null
|
||||
rm -f /tmp/luci-modulecache/* 2>/dev/null
|
||||
|
||||
exit 0
|
||||
@@ -178,14 +178,63 @@ TCP_ENABLED=$(uci -q get "$CONFIG.global.tcp_enabled" || echo "1")
|
||||
UDP_ENABLED=$(uci -q get "$CONFIG.global.udp_enabled" || echo "1")
|
||||
TRAFFIC_MARK=$(uci -q get "$CONFIG.global.traffic_mark" || echo "0x666")
|
||||
PROXY_SERVER_IP_ADDR=$(uci -q get "$CONFIG.global.proxy_server_ip_addr")
|
||||
INTERFACE=$(uci -q get "$CONFIG.global.interface")
|
||||
[ -z "$INTERFACE" ] && INTERFACE="br-lan"
|
||||
get_lan_devices() {
|
||||
local dev="" devs="" nets=""
|
||||
local z_idx=0
|
||||
while :; do
|
||||
local z_name=$(uci -q get firewall.@zone[$z_idx].name)
|
||||
[ -z "$z_name" ] && break
|
||||
if [ "$z_name" = "lan" ]; then
|
||||
nets=$(uci -q get firewall.@zone[$z_idx].network)
|
||||
break
|
||||
fi
|
||||
z_idx=$((z_idx + 1))
|
||||
done
|
||||
|
||||
[ -z "$nets" ] && nets="lan"
|
||||
|
||||
for net in $nets; do
|
||||
dev=""
|
||||
if command -v ubus >/dev/null 2>&1; then
|
||||
dev=$(ubus call network.interface."$net" status 2>/dev/null | jsonfilter -e "@.l3_device" 2>/dev/null)
|
||||
[ -z "$dev" ] && dev=$(ubus call network.interface."$net" status 2>/dev/null | jsonfilter -e "@.device" 2>/dev/null)
|
||||
fi
|
||||
[ -z "$dev" ] && dev=$(uci -q get network."$net".device || uci -q get network."$net".device)
|
||||
if [ -n "$dev" ]; then
|
||||
case " $devs " in
|
||||
*" $dev "*) ;;
|
||||
*) devs="${devs}${devs:+ }$dev" ;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
|
||||
echo "${devs:-br-lan}"
|
||||
}
|
||||
|
||||
render_nft_lan_filter() {
|
||||
local devs="$1"
|
||||
set -- $devs
|
||||
local count=$#
|
||||
if [ "$count" -le 1 ]; then
|
||||
echo " iifname != \"$1\" return"
|
||||
else
|
||||
local set_str=""
|
||||
for d in "$@"; do
|
||||
[ -n "$set_str" ] && set_str="${set_str}, "
|
||||
set_str="${set_str}\"${d}\""
|
||||
done
|
||||
echo " iifname != { $set_str } return"
|
||||
fi
|
||||
}
|
||||
|
||||
LAN_DEVICES=$(get_lan_devices)
|
||||
LAN_NFT_FILTER=$(render_nft_lan_filter "$LAN_DEVICES")
|
||||
|
||||
if [ "$TCP_ENABLED" = "1" ]; then
|
||||
cat >> "$OUTPUT_FILE" << EOF
|
||||
chain LAN_MARKFLOW_TCP {
|
||||
type filter hook prerouting priority mangle; policy accept;
|
||||
iifname != "$INTERFACE" return
|
||||
$LAN_NFT_FILTER
|
||||
fib daddr type { unspec, local, anycast, multicast } counter return
|
||||
EOF
|
||||
if [ -n "$PROXY_SERVER_IP_ADDR" ]; then
|
||||
@@ -201,7 +250,7 @@ if [ "$UDP_ENABLED" = "1" ]; then
|
||||
cat >> "$OUTPUT_FILE" << EOF
|
||||
chain LAN_MARKFLOW_UDP {
|
||||
type filter hook prerouting priority mangle; policy accept;
|
||||
iifname != "$INTERFACE" return
|
||||
$LAN_NFT_FILTER
|
||||
fib daddr type { unspec, local, anycast, multicast } counter return
|
||||
EOF
|
||||
if [ -n "$PROXY_SERVER_IP_ADDR" ]; then
|
||||
|
||||
Reference in new issue
Block a user