Created
August 13, 2025 02:00
-
-
Save Bryan2333/e3ddba94c129029c881c537130487504 to your computer and use it in GitHub Desktop.
sing-box tproxy脚本
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
[[ "$EUID" -eq 0 ]] || { echo "This script must be run as root!"; exit 1; } | |
## 网卡 | |
INTERFACE=$(ip route show default | awk '/default/ {print $5}') | |
INTERFACE="${INTERFACE:-wlan0}" | |
## TProxy流量标记 | |
TPROXY_MARK="0x1" | |
## TProxy路由表ID | |
TPROXY_ROUTE_TABLE="200" | |
## 绕开的用户 | |
BYPASS_USERS="sing-box, naiveproxy" | |
## sing-box的透明代理端口 | |
TPROXY_PORT="7894" | |
## 需要代理的协议类型 | |
TPROXY_L4PROTO="tcp, udp" | |
## 常用端口 | |
COMMON_PORTS="22, 53, 80, 143, 194, 443, 465, 587, 853, 993, 995, 5222, 8080, 8443" | |
function wait_online() { | |
until ping -c2 -W1 baidu.com &>/dev/null | |
do | |
sleep 1 | |
done | |
} | |
function update_public_ipv6() { | |
local count=0 | |
while (( count < 5 )) | |
do | |
ping -6 -c1 -W1 test6.ustc.edu.cn &>/dev/null && break | |
(( count++ )) | |
sleep 1 | |
done | |
(( count >= 5 )) && return | |
local public_ipv6 | |
public_ipv6=$(ip -6 addr show scope global | awk '/inet6/{print $2}' \ | |
| grep -Eiv '(^::1/|^fc[0-9a-f]|^fd[0-9a-f]|^fe80)' \ | |
| sort -u) | |
[[ -z $public_ipv6 ]] && return | |
nft flush set inet singbox MY_PUBLIC_IPv6 | |
for ip in $public_ipv6 | |
do | |
nft add element inet singbox MY_PUBLIC_IPv6 \{ "$ip" \} | |
done | |
} | |
function start_proxy() { | |
systemctl is-active --quiet naiveproxy || systemctl start naiveproxy | |
systemctl is-active --quiet sing-box || systemctl start sing-box | |
} | |
function clear_firewall_rules() { | |
{ | |
ip rule del fwmark "$TPROXY_MARK" table "$TPROXY_ROUTE_TABLE" | |
ip route del local default dev "$INTERFACE" table "$TPROXY_ROUTE_TABLE" | |
ip -6 rule del fwmark "$TPROXY_MARK" table "$TPROXY_ROUTE_TABLE" | |
ip -6 route del local default dev "$INTERFACE" table "$TPROXY_ROUTE_TABLE" | |
nft delete table inet singbox | |
} > /dev/null 2>&1 | |
} | |
function set_firewall_rules() { | |
{ | |
ip rule add fwmark "$TPROXY_MARK" lookup "$TPROXY_ROUTE_TABLE" | |
ip route add local default dev "$INTERFACE" table "$TPROXY_ROUTE_TABLE" | |
ip -6 rule add fwmark "$TPROXY_MARK" lookup "$TPROXY_ROUTE_TABLE" | |
ip -6 route add local default dev "$INTERFACE" table "$TPROXY_ROUTE_TABLE" | |
} > /dev/null 2>&1 | |
nft -f - <<EOF | |
table inet singbox { | |
## 保留IPv4地址 | |
set BYPASS_IPv4 { | |
type ipv4_addr | |
flags interval | |
auto-merge | |
elements = { | |
0.0.0.0/8, | |
10.0.0.0/8, | |
100.64.0.0/10, | |
127.0.0.0/8, | |
169.254.0.0/16, | |
172.16.0.0/12, | |
192.168.0.0/16, | |
224.0.0.0/4, | |
240.0.0.0/4, | |
255.255.255.255 | |
} | |
} | |
## 保留IPv6地址 | |
set BYPASS_IPv6 { | |
type ipv6_addr | |
flags interval | |
auto-merge | |
elements = { | |
::/128, | |
::1/128, | |
64:ff9b::/96, | |
100::/64, | |
2001::/32, | |
2001:20::/28, | |
fe80::/10, | |
ff00::/8 | |
} | |
} | |
## 本机公网 IPv6 地址 | |
set MY_PUBLIC_IPv6 { | |
type ipv6_addr | |
flags interval | |
auto-merge | |
} | |
chain tp_rule { | |
ip daddr @BYPASS_IPv4 meta l4proto { $TPROXY_L4PROTO } th dport != 53 accept comment "绕开私有IP" | |
ip6 daddr @BYPASS_IPv6 meta l4proto { $TPROXY_L4PROTO } th dport != 53 accept comment "绕开私有IP" | |
ip6 daddr @MY_PUBLIC_IPv6 meta l4proto { $TPROXY_L4PROTO } th dport != 53 accept comment "绕开本机公网 IPv6 地址流量" | |
meta l4proto { $TPROXY_L4PROTO } th dport != { $COMMON_PORTS } accept comment "绕开非常用端口流量" | |
} | |
chain tp_pre { | |
type filter hook prerouting priority filter; policy accept; | |
fib daddr type local meta l4proto { $TPROXY_L4PROTO } th dport $TPROXY_PORT reject with icmpx type host-unreachable comment "直接访问tproxy端口拒绝, 防止回环" | |
jump tp_rule | |
meta l4proto { $TPROXY_L4PROTO } socket transparent 1 mark set $TPROXY_MARK | |
socket transparent 0 socket wildcard 0 return comment "跳过已经由TProxy接管的流量" | |
meta l4proto { $TPROXY_L4PROTO } meta mark set $TPROXY_MARK tproxy ip to 127.0.0.1:$TPROXY_PORT accept comment "转发给sing-box" | |
meta l4proto { $TPROXY_L4PROTO } meta mark set $TPROXY_MARK tproxy ip6 to [::1]:$TPROXY_PORT accept comment "转发给sing-box" | |
} | |
chain tp_out { | |
type route hook output priority filter; policy accept; | |
meta skuid { $BYPASS_USERS } accept comment "绕开naive和sing-box发出的连接" | |
jump tp_rule | |
meta l4proto { $TPROXY_L4PROTO } meta mark set $TPROXY_MARK accept comment "重路由到prerouting" | |
} | |
} | |
EOF | |
update_public_ipv6 | |
} | |
function start_tproxy() { | |
clear_firewall_rules | |
wait_online | |
start_proxy | |
set_firewall_rules | |
} | |
function stop_tproxy() { | |
clear_firewall_rules | |
} | |
function main() { | |
case "$1" in | |
"start"|"restart") start_tproxy ;; | |
"stop") stop_tproxy ;; | |
*) echo "Usage: singbox-tproxy start|restart|stop"; exit 1 ;; | |
esac | |
} | |
main "$@" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Copy to /etc/NetworkManager/dispatcher.d/tproxy-dispatcher | |
[[ "$DEVICE_IFACE" == wlan* || "$DEVICE_IFACE" == ens* || "$DEVICE_IFACE" == eth* ]] || exit 0 | |
command -v singbox-tproxy > /dev/null 2>&1 || exit 0 | |
case "$2" in | |
"up") exec singbox-tproxy start ;; | |
"down") exec singbox-tproxy stop ;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment