mirror of
https://github.com/kenzok8/small-package.git
synced 2026-02-04 13:57:45 +08:00
update 2026-01-31 12:00:52
This commit is contained in:
@@ -1590,15 +1590,16 @@ start() {
|
||||
Start_Run
|
||||
start_xhttp_addr
|
||||
start_rules
|
||||
start_dns
|
||||
# Restore ipsets after rules creation
|
||||
if [ "$HAS_IPSET" -eq 1 ]; then
|
||||
for setname in gfwlist china blacklist whitelist netflix; do
|
||||
[ "$setname" = "gfwlist" ] && [ "$run_mode" != "gfw" ] && continue
|
||||
if [ -f "/tmp/ssrplus_save/${setname}.save" ]; then
|
||||
ipset restore -! < "/tmp/ssrplus_save/${setname}.save" 2>/dev/null
|
||||
fi
|
||||
done
|
||||
fi
|
||||
start_dns
|
||||
add_cron
|
||||
start_switch
|
||||
else
|
||||
@@ -1652,11 +1653,13 @@ stop() {
|
||||
# Save ipsets before stopping to persist transparent proxy state
|
||||
if [ "$HAS_IPSET" -eq 1 ]; then
|
||||
mkdir -p /tmp/ssrplus_save
|
||||
ipset save gfwlist > /tmp/ssrplus_save/gfwlist.save 2>/dev/null
|
||||
ipset save china > /tmp/ssrplus_save/china.save 2>/dev/null
|
||||
ipset save blacklist > /tmp/ssrplus_save/blacklist.save 2>/dev/null
|
||||
ipset save whitelist > /tmp/ssrplus_save/whitelist.save 2>/dev/null
|
||||
ipset save netflix > /tmp/ssrplus_save/netflix.save 2>/dev/null
|
||||
local run_mode="$(uci_get_by_type global run_mode)"
|
||||
if [ "$run_mode" = "gfw" ]; then
|
||||
ipset save gfwlist > /tmp/ssrplus_save/gfwlist.save 2>/dev/null
|
||||
fi
|
||||
for setname in china blacklist whitelist netflix; do
|
||||
ipset save $setname > /tmp/ssrplus_save/$setname.save 2>/dev/null
|
||||
done
|
||||
fi
|
||||
unlock
|
||||
set_lock
|
||||
|
||||
@@ -1,108 +1,110 @@
|
||||
ipset=/91smartyun.pt/gfwlist
|
||||
ipset=/adobe.com/gfwlist
|
||||
ipset=/amazonaws.com/gfwlist
|
||||
ipset=/ampproject.org/gfwlist
|
||||
ipset=/apple.news/gfwlist
|
||||
ipset=/aws.amazon.com/gfwlist
|
||||
ipset=/azureedge.net/gfwlist
|
||||
ipset=/backpackers.com.tw/gfwlist
|
||||
ipset=/bitfinex.com/gfwlist
|
||||
ipset=/buzzfeed.com/gfwlist
|
||||
ipset=/clockwise.ee/gfwlist
|
||||
ipset=/cloudfront.net/gfwlist
|
||||
ipset=/coindesk.com/gfwlist
|
||||
ipset=/coinsquare.io/gfwlist
|
||||
ipset=/cryptocompare.com/gfwlist
|
||||
ipset=/dropboxstatic.com/gfwlist
|
||||
ipset=/eurecom.fr/gfwlist
|
||||
ipset=/gdax.com/gfwlist
|
||||
ipset=/github.com/gfwlist
|
||||
ipset=/kknews.cc/gfwlist
|
||||
ipset=/nutaq.com/gfwlist
|
||||
ipset=/openairinterface.org/gfwlist
|
||||
ipset=/skype.com/gfwlist
|
||||
ipset=/sublimetext.com/gfwlist
|
||||
ipset=/textnow.com/gfwlist
|
||||
ipset=/textnow.me/gfwlist
|
||||
ipset=/trouter.io/gfwlist
|
||||
ipset=/t66y.com/gfwlist
|
||||
ipset=/uploaded.net/gfwlist
|
||||
ipset=/whatsapp.com/gfwlist
|
||||
ipset=/whatsapp.net/gfwlist
|
||||
ipset=/wsj.net/gfwlist
|
||||
ipset=/google.com/gfwlist
|
||||
ipset=/google.com.hk/gfwlist
|
||||
ipset=/gstatic.com/gfwlist
|
||||
ipset=/googleusercontent.com/gfwlist
|
||||
ipset=/googlepages.com/gfwlist
|
||||
ipset=/googlevideo.com/gfwlist
|
||||
ipset=/googlecode.com/gfwlist
|
||||
ipset=/googleapis.com/gfwlist
|
||||
ipset=/googlesource.com/gfwlist
|
||||
ipset=/googledrive.com/gfwlist
|
||||
ipset=/ggpht.com/gfwlist
|
||||
ipset=/youtube.com/gfwlist
|
||||
ipset=/youtu.be/gfwlist
|
||||
ipset=/ytimg.com/gfwlist
|
||||
ipset=/twitter.com/gfwlist
|
||||
ipset=/facebook.com/gfwlist
|
||||
ipset=/fastly.net/gfwlist
|
||||
ipset=/akamai.net/gfwlist
|
||||
ipset=/akamaiedge.net/gfwlist
|
||||
ipset=/akamaihd.net/gfwlist
|
||||
ipset=/edgesuite.net/gfwlist
|
||||
ipset=/edgekey.net/gfwlist
|
||||
server=/91smartyun.pt/127.0.0.1#5335
|
||||
ipset=/91smartyun.pt/gfwlist
|
||||
server=/adobe.com/127.0.0.1#5335
|
||||
ipset=/adobe.com/gfwlist
|
||||
server=/amazonaws.com/127.0.0.1#5335
|
||||
ipset=/amazonaws.com/gfwlist
|
||||
server=/ampproject.org/127.0.0.1#5335
|
||||
ipset=/ampproject.org/gfwlist
|
||||
server=/apple.news/127.0.0.1#5335
|
||||
ipset=/apple.news/gfwlist
|
||||
server=/aws.amazon.com/127.0.0.1#5335
|
||||
ipset=/aws.amazon.com/gfwlist
|
||||
server=/azureedge.net/127.0.0.1#5335
|
||||
ipset=/azureedge.net/gfwlist
|
||||
server=/backpackers.com.tw/127.0.0.1#5335
|
||||
ipset=/backpackers.com.tw/gfwlist
|
||||
server=/bitfinex.com/127.0.0.1#5335
|
||||
ipset=/bitfinex.com/gfwlist
|
||||
server=/buzzfeed.com/127.0.0.1#5335
|
||||
ipset=/buzzfeed.com/gfwlist
|
||||
server=/clockwise.ee/127.0.0.1#5335
|
||||
ipset=/clockwise.ee/gfwlist
|
||||
server=/cloudfront.net/127.0.0.1#5335
|
||||
ipset=/cloudfront.net/gfwlist
|
||||
server=/coindesk.com/127.0.0.1#5335
|
||||
ipset=/coindesk.com/gfwlist
|
||||
server=/coinsquare.io/127.0.0.1#5335
|
||||
ipset=/coinsquare.io/gfwlist
|
||||
server=/cryptocompare.com/127.0.0.1#5335
|
||||
ipset=/cryptocompare.com/gfwlist
|
||||
server=/dropboxstatic.com/127.0.0.1#5335
|
||||
ipset=/dropboxstatic.com/gfwlist
|
||||
server=/eurecom.fr/127.0.0.1#5335
|
||||
ipset=/eurecom.fr/gfwlist
|
||||
server=/gdax.com/127.0.0.1#5335
|
||||
ipset=/gdax.com/gfwlist
|
||||
server=/github.com/127.0.0.1#5335
|
||||
ipset=/github.com/gfwlist
|
||||
server=/kknews.cc/127.0.0.1#5335
|
||||
ipset=/kknews.cc/gfwlist
|
||||
server=/nutaq.com/127.0.0.1#5335
|
||||
ipset=/nutaq.com/gfwlist
|
||||
server=/openairinterface.org/127.0.0.1#5335
|
||||
ipset=/openairinterface.org/gfwlist
|
||||
server=/skype.com/127.0.0.1#5335
|
||||
ipset=/skype.com/gfwlist
|
||||
server=/sublimetext.com/127.0.0.1#5335
|
||||
ipset=/sublimetext.com/gfwlist
|
||||
server=/textnow.com/127.0.0.1#5335
|
||||
ipset=/textnow.com/gfwlist
|
||||
server=/textnow.me/127.0.0.1#5335
|
||||
ipset=/textnow.me/gfwlist
|
||||
server=/trouter.io/127.0.0.1#5335
|
||||
ipset=/trouter.io/gfwlist
|
||||
server=/t66y.com/127.0.0.1#5335
|
||||
ipset=/t66y.com/gfwlist
|
||||
server=/uploaded.net/127.0.0.1#5335
|
||||
ipset=/uploaded.net/gfwlist
|
||||
server=/v2rayssr.com/127.0.0.1#5335
|
||||
ipset=/v2rayssr.com/gfwlist
|
||||
server=/whatsapp.com/127.0.0.1#5335
|
||||
ipset=/whatsapp.com/gfwlist
|
||||
server=/whatsapp.net/127.0.0.1#5335
|
||||
ipset=/whatsapp.net/gfwlist
|
||||
server=/wsj.net/127.0.0.1#5335
|
||||
ipset=/wsj.net/gfwlist
|
||||
server=/google.com/127.0.0.1#5335
|
||||
ipset=/google.com/gfwlist
|
||||
server=/google.com.hk/127.0.0.1#5335
|
||||
ipset=/google.com.hk/gfwlist
|
||||
server=/gstatic.com/127.0.0.1#5335
|
||||
ipset=/gstatic.com/gfwlist
|
||||
server=/googleusercontent.com/127.0.0.1#5335
|
||||
ipset=/googleusercontent.com/gfwlist
|
||||
server=/googlepages.com/127.0.0.1#5335
|
||||
ipset=/googlepages.com/gfwlist
|
||||
server=/googlevideo.com/127.0.0.1#5335
|
||||
ipset=/googlevideo.com/gfwlist
|
||||
server=/googlecode.com/127.0.0.1#5335
|
||||
ipset=/googlecode.com/gfwlist
|
||||
server=/googleapis.com/127.0.0.1#5335
|
||||
ipset=/googleapis.com/gfwlist
|
||||
server=/googlesource.com/127.0.0.1#5335
|
||||
ipset=/googlesource.com/gfwlist
|
||||
server=/googledrive.com/127.0.0.1#5335
|
||||
ipset=/googledrive.com/gfwlist
|
||||
server=/ggpht.com/127.0.0.1#5335
|
||||
ipset=/ggpht.com/gfwlist
|
||||
server=/youtube.com/127.0.0.1#5335
|
||||
ipset=/youtube.com/gfwlist
|
||||
server=/youtu.be/127.0.0.1#5335
|
||||
ipset=/youtu.be/gfwlist
|
||||
server=/ytimg.com/127.0.0.1#5335
|
||||
ipset=/ytimg.com/gfwlist
|
||||
server=/twitter.com/127.0.0.1#5335
|
||||
ipset=/twitter.com/gfwlist
|
||||
server=/facebook.com/127.0.0.1#5335
|
||||
ipset=/facebook.com/gfwlist
|
||||
server=/fastly.net/127.0.0.1#5335
|
||||
ipset=/fastly.net/gfwlist
|
||||
server=/akamai.net/127.0.0.1#5335
|
||||
ipset=/akamai.net/gfwlist
|
||||
server=/akamaiedge.net/127.0.0.1#5335
|
||||
ipset=/akamaiedge.net/gfwlist
|
||||
server=/akamaihd.net/127.0.0.1#5335
|
||||
ipset=/akamaihd.net/gfwlist
|
||||
server=/edgesuite.net/127.0.0.1#5335
|
||||
ipset=/edgesuite.net/gfwlist
|
||||
server=/edgekey.net/127.0.0.1#5335
|
||||
ipset=/edgekey.net/gfwlist
|
||||
|
||||
@@ -258,7 +258,6 @@ flush_nftables() {
|
||||
$NFT flush set ip ss_spec_mangle $setname 2>/dev/null
|
||||
$NFT delete set ip ss_spec_mangle $setname 2>/dev/null
|
||||
done
|
||||
|
||||
# Delete entire table
|
||||
$NFT delete table ip ss_spec_mangle 2>/dev/null
|
||||
fi
|
||||
@@ -268,7 +267,8 @@ flush_nftables() {
|
||||
ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null
|
||||
|
||||
# Optional: force delete all ss_spec related sets (even if table was accidentally deleted)
|
||||
for setname in ss_spec_lan_ac ss_spec_wan_ac ssr_gen_router fplan bplan gmlan oversea whitelist blacklist netflix gfwlist china music; do
|
||||
for setname in ss_spec_lan_ac ss_spec_wan_ac ssr_gen_router \
|
||||
china fplan bplan gmlan oversea whitelist blacklist netflix gfwlist music; do
|
||||
$NFT delete set inet ss_spec $setname 2>/dev/null
|
||||
$NFT delete set ip ss_spec_mangle $setname 2>/dev/null
|
||||
done
|
||||
@@ -299,8 +299,8 @@ flush_iptables_legacy() {
|
||||
flush_iptables mangle
|
||||
ip rule del fwmark 0x01/0x01 table 100 2>/dev/null
|
||||
ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null
|
||||
for setname in ss_spec_lan_ac ss_spec_lan_ac_udp ss_spec_wan_ac ss_spec_wan_ac_tcp ss_spec_wan_ac_udp ssr_gen_router \
|
||||
china fplan bplan gmlan oversea whitelist blacklist netflix; do
|
||||
for setname in ss_spec_lan_ac ss_spec_wan_ac ssr_gen_router \
|
||||
china fplan bplan gmlan oversea whitelist blacklist netflix gfwlist music; do
|
||||
ipset -X $setname 2>/dev/null
|
||||
done
|
||||
[ -n "$FWI" ] && echo '#!/bin/sh' >$FWI
|
||||
@@ -359,7 +359,7 @@ ipset_nft() {
|
||||
done
|
||||
|
||||
# Create main chains for WAN access control
|
||||
for chain in ss_spec_wan_fw_tcp ss_spec_wan_fw_udp ss_spec_wan_ac_tcp ss_spec_wan_ac_udp; do
|
||||
for chain in ss_spec_wan_fw ss_spec_wan_ac; do
|
||||
if ! $NFT list chain inet ss_spec $chain >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec $chain
|
||||
fi
|
||||
@@ -368,29 +368,18 @@ ipset_nft() {
|
||||
|
||||
# Add basic rules
|
||||
# BASIC RULES (exceptions first) — TCP
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp meta l4proto tcp tcp dport 53 ip daddr 127.0.0.0/8 return
|
||||
[ -n "$server" ] && $NFT add rule inet ss_spec ss_spec_wan_ac_tcp meta l4proto tcp tcp dport != 53 ip daddr "$server" return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac meta l4proto tcp tcp dport 53 ip daddr 127.0.0.0/8 return
|
||||
[ -n "$server" ] && $NFT add rule inet ss_spec ss_spec_wan_ac meta l4proto tcp tcp dport != 53 ip daddr "$server" return
|
||||
|
||||
# Access control: blacklist -> whitelist -> fplan/bplan — TCP
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip daddr @blacklist jump ss_spec_wan_fw_tcp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip daddr @whitelist return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip saddr @fplan jump ss_spec_wan_fw_tcp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip saddr @bplan return
|
||||
|
||||
# BASIC RULES (exceptions first) — UDP
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp meta l4proto udp udp dport 53 ip daddr 127.0.0.0/8 return
|
||||
[ -n "$server" ] && $NFT add rule inet ss_spec ss_spec_wan_ac_udp meta l4proto udp udp dport != 53 ip daddr "$server" return
|
||||
|
||||
# Access control: blacklist -> whitelist -> fplan/bplan — UDP
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip daddr @blacklist jump ss_spec_wan_fw_udp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip daddr @whitelist return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip saddr @fplan jump ss_spec_wan_fw_udp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip saddr @bplan return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @blacklist jump ss_spec_wan_fw
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @whitelist return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip saddr @fplan jump ss_spec_wan_fw
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip saddr @bplan return
|
||||
|
||||
# Music unlocking support
|
||||
if $NFT list set inet ss_spec music >/dev/null 2>&1; then
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp meta l4proto tcp ip daddr @music return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp meta l4proto udp ip daddr @music return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac meta l4proto tcp ip daddr @music return
|
||||
fi
|
||||
|
||||
# Shunt/Netflix rules
|
||||
@@ -403,66 +392,42 @@ ipset_nft() {
|
||||
# Set up mode-specific rules
|
||||
case "$RUNMODE" in
|
||||
router)
|
||||
if ! $NFT list set inet ss_spec ss_spec_wan_ac_tcp >/dev/null 2>&1; then
|
||||
$NFT add set inet ss_spec ss_spec_wan_ac_tcp '{ type ipv4_addr; flags interval; auto-merge; }'
|
||||
if ! $NFT list set inet ss_spec ss_spec_wan_ac >/dev/null 2>&1; then
|
||||
$NFT add set inet ss_spec ss_spec_wan_ac '{ type ipv4_addr; flags interval; auto-merge; }'
|
||||
else
|
||||
$NFT flush set inet ss_spec ss_spec_wan_ac_tcp 2>/dev/null
|
||||
$NFT flush set inet ss_spec ss_spec_wan_ac 2>/dev/null
|
||||
fi
|
||||
# Add special IP ranges to WAN AC set
|
||||
for ip in $(gen_spec_iplist); do
|
||||
[ -n "$ip" ] && $NFT add element inet ss_spec ss_spec_wan_ac_tcp "{ $ip }" 2>/dev/null
|
||||
[ -n "$ip" ] && $NFT add element inet ss_spec ss_spec_wan_ac "{ $ip }" 2>/dev/null
|
||||
done
|
||||
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip daddr @ss_spec_wan_ac_tcp return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip daddr @china return
|
||||
if $NFT list chain inet ss_spec ss_spec_wan_ac_tcp >/dev/null 2>&1; then
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip saddr @gmlan ip daddr != @china jump ss_spec_wan_fw_tcp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp jump ss_spec_wan_fw_tcp
|
||||
fi
|
||||
if ! $NFT list set inet ss_spec ss_spec_wan_ac_udp >/dev/null 2>&1; then
|
||||
$NFT add set inet ss_spec ss_spec_wan_ac_udp '{ type ipv4_addr; flags interval; auto-merge; }'
|
||||
else
|
||||
$NFT flush set inet ss_spec ss_spec_wan_ac_udp 2>/dev/null
|
||||
fi
|
||||
# Add special IP ranges to WAN AC set
|
||||
for ip in $(gen_spec_iplist); do
|
||||
[ -n "$ip" ] && $NFT add element inet ss_spec ss_spec_wan_ac_udp "{ $ip }" 2>/dev/null
|
||||
done
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip daddr @ss_spec_wan_ac_udp return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip daddr @china return
|
||||
if $NFT list chain inet ss_spec ss_spec_wan_fw_udp >/dev/null 2>&1; then
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip saddr @gmlan ip daddr != @china jump ss_spec_wan_fw_udp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp jump ss_spec_wan_fw_udp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @ss_spec_wan_ac return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @china return
|
||||
if $NFT list chain inet ss_spec ss_spec_wan_ac >/dev/null 2>&1; then
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip saddr @gmlan ip daddr != @china jump ss_spec_wan_fw
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac jump ss_spec_wan_fw
|
||||
fi
|
||||
;;
|
||||
gfw)
|
||||
if ! $NFT list set inet ss_spec gfwlist >/dev/null 2>&1; then
|
||||
$NFT add set inet ss_spec gfwlist '{ type ipv4_addr; flags interval; auto-merge; }' 2>/dev/null
|
||||
fi
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip daddr @china return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip daddr @gfwlist jump ss_spec_wan_fw_tcp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip saddr @gmlan ip daddr != @china jump ss_spec_wan_fw_tcp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip daddr @china return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip daddr @gfwlist jump ss_spec_wan_fw_udp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip saddr @gmlan ip daddr != @china jump ss_spec_wan_fw_udp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @china return
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @gfwlist jump ss_spec_wan_fw
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip saddr @gmlan ip daddr != @china jump ss_spec_wan_fw
|
||||
;;
|
||||
oversea)
|
||||
if ! $NFT list set inet ss_spec oversea >/dev/null 2>&1; then
|
||||
$NFT add set inet ss_spec oversea '{ type ipv4_addr; flags interval; auto-merge; }' 2>/dev/null
|
||||
fi
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip daddr @oversea jump ss_spec_wan_fw_tcp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip saddr @gmlan jump ss_spec_wan_fw_tcp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp ip daddr @china jump ss_spec_wan_fw_tcp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip daddr @oversea jump ss_spec_wan_fw_udp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip saddr @gmlan jump ss_spec_wan_fw_udp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp ip daddr @china jump ss_spec_wan_fw_udp
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @oversea jump ss_spec_wan_fw
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip saddr @gmlan jump ss_spec_wan_fw
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @china jump ss_spec_wan_fw
|
||||
;;
|
||||
all)
|
||||
if $NFT list chain inet ss_spec ss_spec_wan_fw_tcp >/dev/null 2>&1; then
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp jump ss_spec_wan_fw_tcp
|
||||
fi
|
||||
if $NFT list chain inet ss_spec ss_spec_wan_fw_udp >/dev/null 2>&1; then
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp jump ss_spec_wan_fw_udp
|
||||
if $NFT list chain inet ss_spec ss_spec_wan_fw >/dev/null 2>&1; then
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac jump ss_spec_wan_fw
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
@@ -473,17 +438,11 @@ ipset_nft() {
|
||||
ipset_iptables() {
|
||||
[ -f "$IGNORE_LIST" ] && /usr/share/shadowsocksr/chinaipset.sh "$IGNORE_LIST"
|
||||
|
||||
$IPT -N SS_SPEC_WAN_AC_TCP 2>/dev/null
|
||||
$ipt -N SS_SPEC_WAN_AC_UDP 2>/dev/null
|
||||
$IPT -N SS_SPEC_WAN_AC 2>/dev/null
|
||||
$IPT -F SS_SPEC_WAN_AC
|
||||
|
||||
$IPT -F SS_SPEC_WAN_AC_TCP
|
||||
$ipt -F SS_SPEC_WAN_AC_UDP
|
||||
|
||||
$IPT -I SS_SPEC_WAN_AC_TCP -p tcp --dport 53 -d 127.0.0.0/8 -j RETURN
|
||||
$IPT -I SS_SPEC_WAN_AC_TCP -p tcp ! --dport 53 -d "$server" -j RETURN
|
||||
|
||||
$ipt -I SS_SPEC_WAN_AC_UDP -p udp --dport 53 -d 127.0.0.0/8 -j RETURN
|
||||
$ipt -I SS_SPEC_WAN_AC_UDP -p udp ! --dport 53 -d "$server" -j RETURN
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp --dport 53 -d 127.0.0.0/8 -j RETURN
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d "$server" -j RETURN
|
||||
|
||||
ipset -N gmlan hash:net 2>/dev/null
|
||||
for ip in $LAN_GM_IP; do ipset -! add gmlan "$ip"; done
|
||||
@@ -491,58 +450,38 @@ ipset_iptables() {
|
||||
case "$RUNMODE" in
|
||||
router)
|
||||
ipset -! -R <<-EOF || return 1
|
||||
create ss_spec_wan_ac_tcp hash:net
|
||||
$(gen_spec_iplist | sed -e "s/^/add ss_spec_wan_ac_tcp /")
|
||||
create ss_spec_wan_ac hash:net
|
||||
$(gen_spec_iplist | sed -e "s/^/add ss_spec_wan_ac /")
|
||||
EOF
|
||||
ipset -! -R <<-EOF || return 1
|
||||
create ss_spec_wan_ac_udp hash:net
|
||||
$(gen_spec_iplist | sed -e "s/^/add ss_spec_wan_ac_udp /")
|
||||
EOF
|
||||
$IPT -A SS_SPEC_WAN_AC_TCP -m set --match-set ss_spec_wan_ac_tcp dst -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_AC_TCP -m set --match-set china dst -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_AC_TCP -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW_TCP
|
||||
$IPT -A SS_SPEC_WAN_AC_TCP -j SS_SPEC_WAN_FW_TCP
|
||||
|
||||
$ipt -A SS_SPEC_WAN_AC_UDP -m set --match-set ss_spec_wan_ac_udp dst -j RETURN
|
||||
$ipt -A SS_SPEC_WAN_AC_UDP -m set --match-set china dst -j RETURN
|
||||
$ipt -A SS_SPEC_WAN_AC_UDP -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW_UDP
|
||||
$ipt -A SS_SPEC_WAN_AC_UDP -j SS_SPEC_WAN_FW_UDP
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set ss_spec_wan_ac dst -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW
|
||||
$IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
|
||||
;;
|
||||
gfw)
|
||||
ipset -N gfwlist hash:net 2>/dev/null
|
||||
$IPT -A SS_SPEC_WAN_AC_TCP -m set --match-set china dst -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_AC_TCP -m set --match-set gfwlist dst -j SS_SPEC_WAN_FW_TCP
|
||||
$IPT -A SS_SPEC_WAN_AC_TCP -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW_TCP
|
||||
|
||||
$ipt -A SS_SPEC_WAN_AC_UDP -m set --match-set china dst -j RETURN
|
||||
$ipt -A SS_SPEC_WAN_AC_UDP -m set --match-set gfwlist dst -j SS_SPEC_WAN_FW_UDP
|
||||
$ipt -A SS_SPEC_WAN_AC_UDP -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW_UDP
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set gfwlist dst -j SS_SPEC_WAN_FW
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW
|
||||
;;
|
||||
oversea)
|
||||
ipset -N oversea hash:net 2>/dev/null
|
||||
$IPT -I SS_SPEC_WAN_AC_TCP -m set --match-set oversea dst -j SS_SPEC_WAN_FW_TCP
|
||||
$IPT -A SS_SPEC_WAN_AC_TCP -m set --match-set gmlan src -j SS_SPEC_WAN_FW_TCP
|
||||
$IPT -A SS_SPEC_WAN_AC_TCP -m set --match-set china dst -j SS_SPEC_WAN_FW_TCP
|
||||
|
||||
$ipt -I SS_SPEC_WAN_AC_UDP -m set --match-set oversea dst -j SS_SPEC_WAN_FW_UDP
|
||||
$ipt -A SS_SPEC_WAN_AC_UDP -m set --match-set gmlan src -j SS_SPEC_WAN_FW_UDP
|
||||
$ipt -A SS_SPEC_WAN_AC_UDP -m set --match-set china dst -j SS_SPEC_WAN_FW_UDP
|
||||
$IPT -I SS_SPEC_WAN_AC -m set --match-set oversea dst -j SS_SPEC_WAN_FW
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -j SS_SPEC_WAN_FW
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j SS_SPEC_WAN_FW
|
||||
;;
|
||||
all)
|
||||
$IPT -A SS_SPEC_WAN_AC_TCP -j SS_SPEC_WAN_FW_TCP
|
||||
$ipt -A SS_SPEC_WAN_AC_UDP -j SS_SPEC_WAN_FW_UDP
|
||||
$IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
|
||||
;;
|
||||
esac
|
||||
|
||||
ipset -N fplan hash:net 2>/dev/null
|
||||
for ip in $LAN_FP_IP; do ipset -! add fplan "$ip"; done
|
||||
$IPT -I SS_SPEC_WAN_AC_TCP -m set --match-set fplan src -j SS_SPEC_WAN_FW_TCP
|
||||
$ipt -I SS_SPEC_WAN_AC_UDP -m set --match-set fplan src -j SS_SPEC_WAN_FW_UDP
|
||||
$IPT -I SS_SPEC_WAN_AC -m set --match-set fplan src -j SS_SPEC_WAN_FW
|
||||
|
||||
ipset -N bplan hash:net 2>/dev/null
|
||||
for ip in $LAN_BP_IP; do ipset -! add bplan "$ip"; done
|
||||
$IPT -I SS_SPEC_WAN_AC_TCP -m set --match-set bplan src -j RETURN
|
||||
$ipt -I SS_SPEC_WAN_AC_UDP -m set --match-set bplan src -j RETURN
|
||||
$IPT -I SS_SPEC_WAN_AC -m set --match-set bplan src -j RETURN
|
||||
|
||||
ipset -N whitelist hash:net 2>/dev/null
|
||||
if [ -f "${xhttp_ip:=/etc/ssrplus/xhttp_address.txt}" ]; then
|
||||
@@ -552,15 +491,11 @@ ipset_iptables() {
|
||||
fi
|
||||
|
||||
ipset -N blacklist hash:net 2>/dev/null
|
||||
$IPT -I SS_SPEC_WAN_AC_TCP -m set --match-set blacklist dst -j SS_SPEC_WAN_FW_TCP
|
||||
$IPT -I SS_SPEC_WAN_AC_TCP -m set --match-set whitelist dst -j RETURN
|
||||
|
||||
$ipt -I SS_SPEC_WAN_AC_UDP -m set --match-set blacklist dst -j SS_SPEC_WAN_FW_UDP
|
||||
$ipt -I SS_SPEC_WAN_AC_UDP -m set --match-set whitelist dst -j RETURN
|
||||
$IPT -I SS_SPEC_WAN_AC -m set --match-set blacklist dst -j SS_SPEC_WAN_FW
|
||||
$IPT -I SS_SPEC_WAN_AC -m set --match-set whitelist dst -j RETURN
|
||||
|
||||
if [ $(ipset list music -name -quiet | grep music) ]; then
|
||||
$IPT -I SS_SPEC_WAN_AC_TCP -m set --match-set music dst -j RETURN 2>/dev/null
|
||||
$ipt -I SS_SPEC_WAN_AC_UDP -m set --match-set music dst -j RETURN 2>/dev/null
|
||||
$IPT -I SS_SPEC_WAN_AC -m set --match-set music dst -j RETURN 2>/dev/null
|
||||
fi
|
||||
|
||||
for ip in $WAN_BP_IP; do ipset -! add whitelist "$ip"; done
|
||||
@@ -572,15 +507,12 @@ ipset_iptables() {
|
||||
case "$SHUNT_PORT" in
|
||||
0) ;;
|
||||
1)
|
||||
$IPT -I SS_SPEC_WAN_AC_TCP -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports "$local_port"
|
||||
$ipt -I SS_SPEC_WAN_AC_UDP -p udp -m set --match-set netflix dst -j TPROXY --on-port "$local_port" --tproxy-mark 0x01/0x01
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports "$local_port"
|
||||
;;
|
||||
*)
|
||||
$IPT -I SS_SPEC_WAN_AC_TCP -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports "$SHUNT_PORT"
|
||||
$ipt -I SS_SPEC_WAN_AC_UDP -p udp -m set --match-set netflix dst -j TPROXY --on-port "$SHUNT_PORT" --tproxy-mark 0x01/0x01
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports "$SHUNT_PORT"
|
||||
if [ "$SHUNT_PROXY" = "1" ]; then
|
||||
$IPT -I SS_SPEC_WAN_AC_TCP -p tcp -d "$SHUNT_IP" -j REDIRECT --to-ports "$local_port"
|
||||
$ipt -I SS_SPEC_WAN_AC_UDP -p udp -d "$SHUNT_IP" -j TPROXY --on-port "$local_port" --tproxy-mark 0x01/0x01
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp -d "$SHUNT_IP" -j REDIRECT --to-ports "$local_port"
|
||||
else
|
||||
ipset -! add whitelist "$SHUNT_IP"
|
||||
fi
|
||||
@@ -614,47 +546,30 @@ fw_rule_nft() {
|
||||
PORTS_ARGS=$(echo "$PROXY_PORTS" | sed 's/-m multiport --dports //')
|
||||
if [ -n "$PORTS_ARGS" ]; then
|
||||
TCP_EXT_ARGS="meta l4proto tcp tcp dport { $PORTS_ARGS }"
|
||||
UDP_EXT_ARGS="meta l4proto udp udp dport { $PORTS_ARGS }"
|
||||
|
||||
TCP_RULE="meta l4proto tcp tcp dport { $PORTS_ARGS } counter redirect to :$local_port"
|
||||
UDP_RULE="meta l4proto udp udp dport { $PORTS_ARGS } counter tproxy ip to :$local_port meta mark set 0x01"
|
||||
fi
|
||||
else
|
||||
TCP_EXT_ARGS="meta l4proto tcp"
|
||||
UDP_EXT_ARGS="meta l4proto udp"
|
||||
|
||||
# default: redirect everything except ssh(22)
|
||||
TCP_RULE="meta l4proto tcp tcp dport != 22 counter redirect to :$local_port"
|
||||
# default: when PROXY_PORTS present, redirect those udp ports to local_port
|
||||
UDP_RULE="meta l4proto udp counter tproxy ip to :$local_port meta mark set 0x01"
|
||||
fi
|
||||
# add TCP rule to fw chain if not exists (use -F exact match)
|
||||
if ! $NFT list chain inet ss_spec ss_spec_wan_fw_tcp 2>/dev/null | grep -F -- "$TCP_RULE" >/dev/null 2>&1; then
|
||||
if ! $NFT add rule inet ss_spec ss_spec_wan_fw_tcp $TCP_RULE 2>/dev/null; then
|
||||
if ! $NFT list chain inet ss_spec ss_spec_wan_fw 2>/dev/null | grep -F -- "$TCP_RULE" >/dev/null 2>&1; then
|
||||
if ! $NFT add rule inet ss_spec ss_spec_wan_fw $TCP_RULE 2>/dev/null; then
|
||||
loger 3 "Can't redirect TCP, please check nftables."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! $NFT list chain inet ss_spec ss_spec_wan_fw_udp 2>/dev/null | grep -F -- "$UDP_RULE" >/dev/null 2>&1; then
|
||||
if ! $NFT add rule inet ss_spec ss_spec_wan_fw_udp $UDP_RULE 2>/dev/null; then
|
||||
loger 3 "Can't tproxy UDP, please check nftables."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$SHUNT_PORT" != "0" ] && [ -f "$SHUNT_LIST" ]; then
|
||||
case "$SHUNT_PORT" in
|
||||
1)
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp $TCP_EXT_ARGS ip daddr @netflix counter redirect to :$local_port
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp $UDP_EXT_ARGS ip daddr @netflix counter tproxy ip to :$local_port meta mark set 0x01
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac $TCP_EXT_ARGS ip daddr @netflix counter redirect to :$local_port
|
||||
;;
|
||||
*)
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp $TCP_EXT_ARGS ip daddr @netflix counter redirect to :$SHUNT_PORT
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp $UDP_EXT_ARGS ip daddr @netflix counter tproxy ip to :$SHUNT_PORT meta mark set 0x01
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac $TCP_EXT_ARGS ip daddr @netflix counter redirect to :$SHUNT_PORT
|
||||
if [ "$SHUNT_PROXY" = "1" ]; then
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_tcp $TCP_EXT_ARGS ip daddr $SHUNT_IP counter redirect to :$local_port
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac_udp $UDP_EXT_ARGS ip daddr $SHUNT_IP counter tproxy ip to :$local_port meta mark set 0x01
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac $TCP_EXT_ARGS ip daddr $SHUNT_IP counter redirect to :$local_port
|
||||
else
|
||||
[ -n "$SHUNT_IP" ] && $NFT add element inet ss_spec whitelist "{ $SHUNT_IP }" 2>/dev/null
|
||||
fi
|
||||
@@ -675,39 +590,22 @@ fw_rule_iptables() {
|
||||
ip route add local 0.0.0.0/0 dev lo table 100 2>/dev/null
|
||||
fi
|
||||
|
||||
# 创建TCP链 (在nat表中)
|
||||
$IPT -N SS_SPEC_WAN_FW_TCP 2>/dev/null
|
||||
$IPT -F SS_SPEC_WAN_FW_TCP
|
||||
# Create TCP chain in NAT table
|
||||
$IPT -N SS_SPEC_WAN_FW 2>/dev/null
|
||||
$IPT -F SS_SPEC_WAN_FW
|
||||
|
||||
for net in \
|
||||
0.0.0.0/8 10.0.0.0/8 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
|
||||
do
|
||||
$IPT -A SS_SPEC_WAN_FW_TCP -d "$net" -j RETURN
|
||||
$IPT -A SS_SPEC_WAN_FW -d "$net" -j RETURN
|
||||
done
|
||||
|
||||
$IPT -A SS_SPEC_WAN_FW_TCP -p tcp $PROXY_PORTS -j REDIRECT --to-ports "$local_port" 2>/dev/null || {
|
||||
$IPT -A SS_SPEC_WAN_FW -p tcp $PROXY_PORTS -j REDIRECT --to-ports "$local_port" 2>/dev/null || {
|
||||
loger 3 "Can't redirect TCP, please check the iptables."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 创建UDP链 (在mangle表中)
|
||||
$ipt -N SS_SPEC_WAN_FW_UDP 2>/dev/null
|
||||
$ipt -F SS_SPEC_WAN_FW_UDP
|
||||
|
||||
for net in \
|
||||
0.0.0.0/8 10.0.0.0/8 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
|
||||
do
|
||||
$ipt -A SS_SPEC_WAN_FW_UDP -p udp -d "$net" -j RETURN
|
||||
done
|
||||
|
||||
# UDP TPROXY规则 (必须在mangle表中)
|
||||
$ipt -A SS_SPEC_WAN_FW_UDP -p udp $PROXY_PORTS -j TPROXY --on-port "$local_port" --tproxy-mark 0x01/0x01 2>/dev/null || {
|
||||
loger 3 "Can't set UDP TPROXY, please check the iptables."
|
||||
exit 1
|
||||
}
|
||||
|
||||
return $?
|
||||
}
|
||||
|
||||
@@ -750,42 +648,22 @@ ac_rule_nft() {
|
||||
fi
|
||||
|
||||
# Create ss_spec_prerouting tcp chain
|
||||
if ! $NFT list chain inet ss_spec ss_spec_prerouting_tcp >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_prerouting_tcp '{ type nat hook prerouting priority 0; policy accept; }'
|
||||
if ! $NFT list chain inet ss_spec ss_spec_prerouting >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_prerouting '{ type nat hook prerouting priority 0; policy accept; }'
|
||||
fi
|
||||
$NFT flush chain inet ss_spec ss_spec_prerouting_tcp 2>/dev/null
|
||||
$NFT flush chain inet ss_spec ss_spec_prerouting 2>/dev/null
|
||||
|
||||
# Exclude special local addresses
|
||||
if $NFT list chain inet ss_spec ss_spec_prerouting_tcp >/dev/null 2>&1; then
|
||||
if $NFT list chain inet ss_spec ss_spec_prerouting >/dev/null 2>&1; then
|
||||
for net in 0.0.0.0/8 10.0.0.0/8 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; do
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting_tcp ip daddr $net return 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting ip daddr $net return 2>/dev/null
|
||||
done
|
||||
fi
|
||||
|
||||
# Temporarily comment IPV6 for future enablement
|
||||
#if $NFT list chain inet ss_spec ss_spec_prerouting_tcp >/dev/null 2>&1; then
|
||||
#if $NFT list chain inet ss_spec ss_spec_prerouting >/dev/null 2>&1; then
|
||||
# for net in ::1/128 fe80::/10 fc00::/7 ff00::/8 ::/128 ::ffff:0:0/96; do
|
||||
# $NFT add rule inet ss_spec ss_spec_prerouting_tcp ip6 daddr $net return 2>/dev/null
|
||||
# done
|
||||
#fi
|
||||
|
||||
# Create ss_spec_prerouting udp chain
|
||||
if ! $NFT list chain inet ss_spec ss_spec_prerouting_udp >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_prerouting_udp '{ type filter hook prerouting priority -150; policy accept; }'
|
||||
fi
|
||||
$NFT flush chain inet ss_spec ss_spec_prerouting_udp 2>/dev/null
|
||||
|
||||
# Exclude special local addresses
|
||||
if $NFT list chain inet ss_spec ss_spec_prerouting_udp >/dev/null 2>&1; then
|
||||
for net in 0.0.0.0/8 10.0.0.0/8 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; do
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting_udp ip daddr $net return 2>/dev/null
|
||||
done
|
||||
fi
|
||||
|
||||
# Temporarily comment IPV6 for future enablement
|
||||
#if $NFT list chain inet ss_spec ss_spec_prerouting_udp >/dev/null 2>&1; then
|
||||
# for net in ::1/128 fe80::/10 fc00::/7 ff00::/8 ::/128 ::ffff:0:0/96; do
|
||||
# $NFT add rule inet ss_spec ss_spec_prerouting_udp ip6 daddr $net return 2>/dev/null
|
||||
# $NFT add rule inet ss_spec ss_spec_prerouting ip6 daddr $net return 2>/dev/null
|
||||
# done
|
||||
#fi
|
||||
|
||||
@@ -794,22 +672,41 @@ ac_rule_nft() {
|
||||
PORTS_ARGS=$(echo "$PROXY_PORTS" | sed 's/-m multiport --dports //')
|
||||
if [ -n "$PORTS_ARGS" ]; then
|
||||
TCP_EXT_ARGS="meta l4proto tcp tcp dport { $PORTS_ARGS }"
|
||||
UDP_EXT_ARGS="meta l4proto udp udp dport { $PORTS_ARGS }"
|
||||
fi
|
||||
else
|
||||
TCP_EXT_ARGS="meta l4proto tcp"
|
||||
UDP_EXT_ARGS="meta l4proto udp"
|
||||
fi
|
||||
|
||||
# Block UDP port 443 when TPROXY not Enable
|
||||
if [ -z "$TPROXY" ]; then
|
||||
# Add UDP 443 block rule
|
||||
if [ -z "$Interface" ]; then
|
||||
if [ -n "$MATCH_SET" ]; then
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting meta l4proto udp $MATCH_SET udp dport 443 drop comment "\"$TAG\"" 2>/dev/null
|
||||
else
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting meta l4proto udp udp dport 443 drop comment "\"$TAG\"" 2>/dev/null
|
||||
fi
|
||||
else
|
||||
for name in $Interface; do
|
||||
local IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null)
|
||||
[ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null)
|
||||
if [ -n "$IFNAME" ]; then
|
||||
if [ -n "$MATCH_SET" ]; then
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting meta iifname "$IFNAME" meta l4proto udp $MATCH_SET udp dport 443 drop comment "\"$TAG\"" 2>/dev/null
|
||||
else
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting meta iifname "$IFNAME" meta l4proto udp udp dport 443 drop comment "\"$TAG\"" 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
if [ -z "$Interface" ]; then
|
||||
# generic prerouting jump already exists (see ipset_nft), but if we have MATCH_SET_CONDITION we add a more specific rule
|
||||
if [ -n "$MATCH_SET" ]; then
|
||||
# add a more specific rule at the top of ss_spec_prerouting
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting_tcp $TCP_EXT_ARGS $MATCH_SET jump ss_spec_wan_ac_tcp comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting_udp $UDP_EXT_ARGS $MATCH_SET jump ss_spec_wan_ac_udp comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting $TCP_EXT_ARGS $MATCH_SET jump ss_spec_wan_ac comment "\"$TAG\"" 2>/dev/null
|
||||
else
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting_tcp $TCP_EXT_ARGS jump ss_spec_wan_ac_tcp comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting_udp $UDP_EXT_ARGS jump ss_spec_wan_ac_udp comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting $TCP_EXT_ARGS jump ss_spec_wan_ac comment "\"$TAG\"" 2>/dev/null
|
||||
fi
|
||||
else
|
||||
# For each Interface, find its actual ifname and add an iifname-limited prerouting rule
|
||||
@@ -818,63 +715,37 @@ ac_rule_nft() {
|
||||
[ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null)
|
||||
if [ -n "$IFNAME" ]; then
|
||||
if [ -n "$MATCH_SET" ]; then
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting_tcp meta iifname "$IFNAME" $TCP_EXT_ARGS $MATCH_SET jump ss_spec_wan_ac_tcp comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting_udp meta iifname "$IFNAME" $UDP_EXT_ARGS $MATCH_SET jump ss_spec_wan_ac_udp comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting meta iifname "$IFNAME" $TCP_EXT_ARGS $MATCH_SET jump ss_spec_wan_ac comment "\"$TAG\"" 2>/dev/null
|
||||
else
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting_tcp meta iifname "$IFNAME" $TCP_EXT_ARGS jump ss_spec_wan_ac_tcp comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting_udp meta iifname "$IFNAME" $UDP_EXT_ARGS jump ss_spec_wan_ac_udp comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_prerouting meta iifname "$IFNAME" $TCP_EXT_ARGS jump ss_spec_wan_ac comment "\"$TAG\"" 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
case "$OUTPUT" in
|
||||
1)
|
||||
# Create ss_spec_output tcp chain
|
||||
if ! $NFT list chain inet ss_spec ss_spec_output_tcp >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_output_tcp '{ type nat hook output priority 0; policy accept; }'
|
||||
if ! $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_output '{ type nat hook output priority 0; policy accept; }'
|
||||
fi
|
||||
$NFT flush chain inet ss_spec ss_spec_output_tcp 2>/dev/null
|
||||
$NFT flush chain inet ss_spec ss_spec_output 2>/dev/null
|
||||
|
||||
# Exclude special local addresses
|
||||
if $NFT list chain inet ss_spec ss_spec_output_tcp >/dev/null 2>&1; then
|
||||
if $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then
|
||||
for net in 0.0.0.0/8 10.0.0.0/8 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; do
|
||||
$NFT add rule inet ss_spec ss_spec_output_tcp ip daddr $net return 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_output ip daddr $net return 2>/dev/null
|
||||
done
|
||||
fi
|
||||
|
||||
# Temporarily comment IPV6 for future enablement
|
||||
#if $NFT list chain inet ss_spec ss_spec_output_tcp >/dev/null 2>&1; then
|
||||
#if $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then
|
||||
# for net in ::1/128 fe80::/10 fc00::/7 ff00::/8 ::/128 ::ffff:0:0/96; do
|
||||
# $NFT add rule inet ss_spec ss_spec_output_tcp ip6 daddr $net return 2>/dev/null
|
||||
# $NFT add rule inet ss_spec ss_spec_output ip6 daddr $net return 2>/dev/null
|
||||
# done
|
||||
#fi
|
||||
|
||||
# create output hook chain & route output traffic into router chain
|
||||
$NFT add rule inet ss_spec ss_spec_output_tcp $TCP_EXT_ARGS jump ss_spec_wan_ac_tcp comment "\"$TAG\"" 2>/dev/null
|
||||
|
||||
# Create ss_spec_output udp chain
|
||||
if ! $NFT list chain inet ss_spec ss_spec_output_udp >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_output_udp '{ type filter hook output priority -150; policy accept; }'
|
||||
fi
|
||||
$NFT flush chain inet ss_spec ss_spec_output_udp 2>/dev/null
|
||||
|
||||
# Exclude special local addresses
|
||||
if $NFT list chain inet ss_spec ss_spec_output_udp >/dev/null 2>&1; then
|
||||
for net in 0.0.0.0/8 10.0.0.0/8 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; do
|
||||
$NFT add rule inet ss_spec ss_spec_output_udp ip daddr $net return 2>/dev/null
|
||||
done
|
||||
fi
|
||||
|
||||
# Temporarily comment IPV6 for future enablement
|
||||
#if $NFT list chain inet ss_spec ss_spec_output_udp >/dev/null 2>&1; then
|
||||
# for net in ::1/128 fe80::/10 fc00::/7 ff00::/8 ::/128 ::ffff:0:0/96; do
|
||||
# $NFT add rule inet ss_spec ss_spec_output_udp ip6 daddr $net return 2>/dev/null
|
||||
# done
|
||||
#fi
|
||||
|
||||
# create output hook chain & route output traffic into router chain
|
||||
$NFT add rule inet ss_spec ss_spec_output_udp $UDP_EXT_ARGS meta mark set 0x01 comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_output $TCP_EXT_ARGS jump ss_spec_wan_ac comment "\"$TAG\"" 2>/dev/null
|
||||
;;
|
||||
2)
|
||||
# Create ss_spec_output tcp chain
|
||||
@@ -895,13 +766,13 @@ ac_rule_nft() {
|
||||
for ip in $(gen_spec_iplist); do
|
||||
[ -n "$ip" ] && $NFT add element inet ss_spec ssr_gen_router "{ $ip }" 2>/dev/null
|
||||
done
|
||||
$NFT add chain inet ss_spec ss_spec_router 2>/dev/null
|
||||
if ! $NFT list chain inet ss_spec ss_spec_router >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_router 2>/dev/null
|
||||
fi
|
||||
$NFT flush chain inet ss_spec ss_spec_router 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_router ip daddr @ssr_gen_router return 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_router jump ss_spec_wan_fw_tcp 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_router jump ss_spec_wan_fw_udp 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_router jump ss_spec_wan_fw 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_output $TCP_EXT_ARGS jump ss_spec_router comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_output $UDP_EXT_ARGS meta mark set 0x01 comment "\"$TAG\"" 2>/dev/null
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
@@ -927,40 +798,48 @@ ac_rule_iptables() {
|
||||
create ss_spec_lan_ac hash:net
|
||||
$(for ip in ${LAN_AC_IP#?}; do echo "add ss_spec_lan_ac $ip"; done)
|
||||
EOF
|
||||
|
||||
# Block UDP port 443 when TPROXY not Enable
|
||||
if [ -z "$TPROXY" ]; then
|
||||
# Add UDP 443 block rule
|
||||
if [ -z "$Interface" ]; then
|
||||
$ipt -I PREROUTING 1 -p udp $EXT_ARGS $MATCH_SET --dport 443 -j DROP -m comment --comment "$TAG"
|
||||
else
|
||||
for name in $Interface; do
|
||||
local IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null)
|
||||
[ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null)
|
||||
if [ -n "$IFNAME" ]; then
|
||||
$ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET --dport 443 -j DROP -m comment --comment "$TAG"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
if [ -z "$Interface" ]; then
|
||||
$IPT -I PREROUTING 1 -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC_TCP
|
||||
$ipt -I PREROUTING 1 -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC_UDP
|
||||
$IPT -I PREROUTING 1 -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC
|
||||
else
|
||||
for name in $Interface; do
|
||||
local IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null)
|
||||
[ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null)
|
||||
if [ -n "$IFNAME" ]; then
|
||||
$IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC_TCP
|
||||
$ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC_UDP
|
||||
$IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
case "$OUTPUT" in
|
||||
1)
|
||||
$IPT -I OUTPUT 1 -p tcp $EXT_ARGS -m comment --comment "$TAG" -j SS_SPEC_WAN_AC_TCP
|
||||
#$ipt -I OUTPUT 1 -p udp $EXT_ARGS -m comment --comment "$TAG" -j MARK --set-xmark 0x01/0x01
|
||||
$IPT -I OUTPUT 1 -p tcp $EXT_ARGS -m comment --comment "$TAG" -j SS_SPEC_WAN_AC
|
||||
;;
|
||||
2)
|
||||
ipset -! -R <<-EOF || return 1
|
||||
create ssr_gen_router hash:net
|
||||
$(gen_spec_iplist | sed -e "s/^/add ssr_gen_router /")
|
||||
EOF
|
||||
$IPT -N SS_SPEC_ROUTER_TCP 2>/dev/null
|
||||
$IPT -F SS_SPEC_ROUTER_TCP 2>/dev/null
|
||||
$IPT -A SS_SPEC_ROUTER_TCP -m set --match-set ssr_gen_router dst -j RETURN && \
|
||||
$IPT -A SS_SPEC_ROUTER_TCP -j SS_SPEC_WAN_FW_TCP
|
||||
$IPT -I OUTPUT 1 -p tcp -m comment --comment "$TAG" -j SS_SPEC_ROUTER_TCP
|
||||
$ipt -N SS_SPEC_ROUTER_UDP 2>/dev/null
|
||||
$ipt -F SS_SPEC_ROUTER_UDP 2>/dev/null
|
||||
$ipt -A SS_SPEC_ROUTER_UDP -m set --match-set ssr_gen_router dst -j RETURN && \
|
||||
$ipt -A SS_SPEC_ROUTER_UDP -j SS_SPEC_WAN_FW_UDP
|
||||
#$ipt -I OUTPUT 1 -p udp -m comment --comment "$TAG" -j SS_SPEC_ROUTER_UDP
|
||||
$IPT -N SS_SPEC_ROUTER 2>/dev/null
|
||||
$IPT -F SS_SPEC_ROUTER 2>/dev/null
|
||||
$IPT -A SS_SPEC_ROUTER -m set --match-set ssr_gen_router dst -j RETURN && \
|
||||
$IPT -A SS_SPEC_ROUTER -j SS_SPEC_WAN_FW
|
||||
$IPT -I OUTPUT 1 -p tcp -m comment --comment "$TAG" -j SS_SPEC_ROUTER
|
||||
;;
|
||||
esac
|
||||
return $?
|
||||
@@ -1102,7 +981,8 @@ tp_rule_nft() {
|
||||
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip daddr @ss_spec_wan_ac return 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip daddr @china return 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp udp dport 80 drop 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp udp dport 80 counter drop comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp udp dport 443 counter drop comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip saddr @gmlan ip daddr != @china counter tproxy ip to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp $EXT_ARGS ip daddr != @ss_spec_wan_ac counter tproxy ip to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
|
||||
;;
|
||||
@@ -1111,7 +991,8 @@ tp_rule_nft() {
|
||||
$NFT add set ip ss_spec_mangle gfwlist '{ type ipv4_addr; flags interval; auto-merge; }' 2>/dev/null
|
||||
fi
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip daddr @china return 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp udp dport 80 drop 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp udp dport 80 counter drop comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp udp dport 443 counter drop comment "\"$TAG\"" 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp $EXT_ARGS ip daddr @gfwlist counter tproxy ip to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip saddr @gmlan ip daddr != @china counter tproxy ip to :"$LOCAL_PORT" meta mark set 0x01 2>/dev/null
|
||||
;;
|
||||
@@ -1170,19 +1051,17 @@ tp_rule_iptables() {
|
||||
fi
|
||||
$ipt -N SS_SPEC_TPROXY 2>/dev/null
|
||||
$ipt -F SS_SPEC_TPROXY
|
||||
$ipt -N PREROUTING_UDP 2>/dev/null
|
||||
$ipt -F PREROUTING_UDP
|
||||
|
||||
$ipt -A SS_SPEC_TPROXY -p udp --dport 53 -j RETURN
|
||||
|
||||
local MATCH_SET_UDP=""
|
||||
local MATCH_SET=""
|
||||
if [ -n "$LAN_AC_IP" ]; then
|
||||
case "${LAN_AC_IP%${LAN_AC_IP#?}}" in
|
||||
w | W)
|
||||
MATCH_SET_UDP="-m set --match-set ss_spec_lan_ac_udp src"
|
||||
MATCH_SET_UDP="-m set --match-set ss_spec_lan_ac src"
|
||||
;;
|
||||
b | B)
|
||||
MATCH_SET_UDP="-m set ! --match-set ss_spec_lan_ac_udp src"
|
||||
MATCH_SET_UDP="-m set ! --match-set ss_spec_lan_ac src"
|
||||
;;
|
||||
*)
|
||||
loger 3 "Bad argument \`-a $LAN_AC_IP\`."
|
||||
@@ -1191,8 +1070,8 @@ tp_rule_iptables() {
|
||||
esac
|
||||
fi
|
||||
ipset -! -R <<-EOF || return 1
|
||||
create ss_spec_lan_ac_udp hash:net
|
||||
$(for ip in ${LAN_AC_IP#?}; do echo "add ss_spec_lan_ac_udp $ip"; done)
|
||||
create ss_spec_lan_ac hash:net
|
||||
$(for ip in ${LAN_AC_IP#?}; do echo "add ss_spec_lan_ac $ip"; done)
|
||||
EOF
|
||||
|
||||
for net in \
|
||||
@@ -1219,12 +1098,14 @@ tp_rule_iptables() {
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set ss_spec_wan_ac dst -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set china dst -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp --dport 80 -j DROP
|
||||
$ipt -A SS_SPEC_TPROXY -p udp --dport 443 -j DROP
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
|
||||
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set ! --match-set ss_spec_wan_ac dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
|
||||
;;
|
||||
gfw)
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set china dst -j RETURN
|
||||
$ipt -A SS_SPEC_TPROXY -p udp --dport 80 -j DROP
|
||||
$ipt -A SS_SPEC_TPROXY -p udp --dport 443 -j DROP
|
||||
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set gfwlist dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
|
||||
;;
|
||||
@@ -1238,12 +1119,12 @@ tp_rule_iptables() {
|
||||
;;
|
||||
esac
|
||||
if [ -z "$Interface" ]; then
|
||||
$ipt -I PREROUTING_UDP 1 -p udp $EXT_ARGS $MATCH_SET_UDP -m comment --comment "$TAG" -j SS_SPEC_TPROXY
|
||||
$ipt -I PREROUTING 1 -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY
|
||||
else
|
||||
for name in $Interface; do
|
||||
local IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null)
|
||||
[ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null)
|
||||
[ -n "$IFNAME" ] && $ipt -I PREROUTING_UDP 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET_UDP -m comment --comment "$TAG" -j SS_SPEC_TPROXY
|
||||
[ -n "$IFNAME" ] && $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY
|
||||
done
|
||||
fi
|
||||
return $?
|
||||
|
||||
Reference in New Issue
Block a user