Browse Source

shadowsocks-libev: rewrite ss-rules

- New UCI options ifnames, dst_default
 - UCI options src_ips_xxx now accept cidr as their values
 - Export ipset names as part of the interface so that it can be
   depended on and used by other programs
 - Bypass only remote servers used ss-redir instances, so that it's
   possible to let other servers to go through existing re-redir
   instances

Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
lilik-openwrt-22.03
Yousong Zhou 7 years ago
parent
commit
df395767d3
4 changed files with 253 additions and 274 deletions
  1. +1
    -1
      net/shadowsocks-libev/Makefile
  2. +14
    -5
      net/shadowsocks-libev/README.md
  3. +31
    -44
      net/shadowsocks-libev/files/shadowsocks-libev.init
  4. +207
    -224
      net/shadowsocks-libev/files/ss-rules

+ 1
- 1
net/shadowsocks-libev/Makefile View File

@ -14,7 +14,7 @@ include $(TOPDIR)/rules.mk
# #
PKG_NAME:=shadowsocks-libev PKG_NAME:=shadowsocks-libev
PKG_VERSION:=3.0.8 PKG_VERSION:=3.0.8
PKG_RELEASE:=6
PKG_RELEASE:=7
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/shadowsocks/shadowsocks-libev/releases/download/v$(PKG_VERSION) PKG_SOURCE_URL:=https://github.com/shadowsocks/shadowsocks-libev/releases/download/v$(PKG_VERSION)


+ 14
- 5
net/shadowsocks-libev/README.md View File

@ -39,8 +39,9 @@ We can have multiple instances of component and `server` sections. The relation
redir_tcp name of ss_redir section with mode tcp_only or tcp_and_udp redir_tcp name of ss_redir section with mode tcp_only or tcp_and_udp
redir_udp name of ss_redir section with mode udp_only or tcp_and_udp redir_udp name of ss_redir section with mode udp_only or tcp_and_udp
ifnames only apply rules on packets from these ifnames
--- incoming packets having source address in
--- for incoming packets having source address in
src_ips_bypass will bypass the redir chain src_ips_bypass will bypass the redir chain
src_ips_forward will always go through the redir chain src_ips_forward will always go through the redir chain
@ -50,10 +51,6 @@ We can have multiple instances of component and `server` sections. The relation
src_default bypass, forward, [checkdst] src_default bypass, forward, [checkdst]
--- for local out tcp packets, the default action can be specified with
local_default [bypass], forward, checkdst
--- if the previous check result is checkdst, --- if the previous check result is checkdst,
--- then packets having destination address in --- then packets having destination address in
@ -62,6 +59,18 @@ We can have multiple instances of component and `server` sections. The relation
dst_ips_forward_file dst_ips_forward_file
dst_ips_forward will go through the redir chain dst_ips_forward will go through the redir chain
--- otherwise, the default action can be specified with
dst_default [bypass], forward
--- for local out tcp packets, the default action can be specified with
local_default [bypass], forward, checkdst
ss-rules uses kernel ipset mechanism for storing addresses/networks. Those ipsets are also part of the API and can be populated by other programs, e.g. dnsmasq with builtin ipset support. For more details please read output of `ss-rules --help`
Note also that `src_ips_xx` and `dst_ips_xx` actually also accepts cidr network representation. Names are retained for backward compatibility coniderations
## notes and faq ## notes and faq
Useful paths and commands for debugging Useful paths and commands for debugging


+ 31
- 44
net/shadowsocks-libev/files/shadowsocks-libev.init View File

@ -107,7 +107,7 @@ ss_xxx() {
[ -x "$bin" ] || return [ -x "$bin" ] || return
eval "$("validate_${cfgtype}_section" "$cfg" ss_validate_mklocal)" eval "$("validate_${cfgtype}_section" "$cfg" ss_validate_mklocal)"
"validate_${cfgtype}_section" "$cfg"
"validate_${cfgtype}_section" "$cfg" || return 1
[ "$disabled" = 0 ] || return [ "$disabled" = 0 ] || return
if ss_mkjson \ if ss_mkjson \
@ -127,21 +127,17 @@ ss_xxx() {
} }
ss_rules_cb() { ss_rules_cb() {
local cfgserver
local server
[ "$cfgtype" != ss_server ] || return
config_get cfgserver "$cfg" server
config_get server "$cfgserver" server
local cfgserver server
ss_rules_servers="$ss_rules_servers $server"
if [ "$cfgtype" = ss_redir ]; then if [ "$cfgtype" = ss_redir ]; then
config_get cfgserver "$cfg" server
config_get server "$cfgserver" server
ss_redir_servers="$ss_redir_servers $server"
if [ "$mode" = tcp_only -o "$mode" = "tcp_and_udp" ]; then if [ "$mode" = tcp_only -o "$mode" = "tcp_and_udp" ]; then
eval "ss_rules_redir_tcp_$cfg=$local_port" eval "ss_rules_redir_tcp_$cfg=$local_port"
fi fi
if [ "$mode" = udp_only -o "$mode" = "tcp_and_udp" ]; then if [ "$mode" = udp_only -o "$mode" = "tcp_and_udp" ]; then
eval "ss_rules_redir_udp_$cfg=$local_port" eval "ss_rules_redir_udp_$cfg=$local_port"
eval "ss_rules_redir_server_udp_$cfg=$server"
fi fi
fi fi
} }
@ -150,48 +146,37 @@ ss_rules() {
local cfg="ss_rules" local cfg="ss_rules"
local bin="$ss_bindir/ss-rules" local bin="$ss_bindir/ss-rules"
local cfgtype local cfgtype
local args local_port_tcp local_port_udp server_udp
local i a_args d_args
local local_port_tcp local_port_udp
[ -x "$bin" ] || return 1 [ -x "$bin" ] || return 1
config_get cfgtype "$cfg" TYPE config_get cfgtype "$cfg" TYPE
[ "$cfgtype" = ss_rules ] || return 1 [ "$cfgtype" = ss_rules ] || return 1
eval "$(validate_ss_rules_section "$cfg" ss_validate_mklocal)" eval "$(validate_ss_rules_section "$cfg" ss_validate_mklocal)"
validate_ss_rules_section "$cfg"
validate_ss_rules_section "$cfg" || return 1
[ "$disabled" = 0 ] || return 1 [ "$disabled" = 0 ] || return 1
eval local_port_tcp="\$ss_rules_redir_tcp_$redir_tcp" eval local_port_tcp="\$ss_rules_redir_tcp_$redir_tcp"
eval local_port_udp="\$ss_rules_redir_udp_$redir_udp" eval local_port_udp="\$ss_rules_redir_udp_$redir_udp"
eval server_udp="\$ss_rules_redir_server_udp_$redir_udp"
[ -z "$local_port_udp" ] || args="$args -U"
case "$local_default" in
forward) args="$args -O" ;;
checkdst) args="$args -o" ;;
esac
case "$src_default" in
bypass) d_args=RETURN ;;
forward) d_args=SS_SPEC_WAN_FW ;;
checkdst) d_args=SS_SPEC_WAN_AC ;;
esac
ss_rules_servers="$(echo "$ss_rules_servers" | tr ' ' '\n' | sort -u)"
for i in $src_ips_bypass; do a_args="b,$i $a_args"; done
for i in $src_ips_forward; do a_args="g,$i $a_args"; done
for i in $src_ips_checkdst; do a_args="n,$i $a_args"; done
[ -n "$local_port_tcp" -o -n "$local_port_udp" ] || return 1
ss_redir_servers="$(echo "$ss_redir_servers" | tr ' ' '\n' | sort -u)"
"$bin" \ "$bin" \
-s "$ss_rules_servers" \
-s "$ss_redir_servers" \
-l "$local_port_tcp" \ -l "$local_port_tcp" \
-S "$server_udp" \
-L "$local_port_udp" \ -L "$local_port_udp" \
-B "$dst_ips_bypass_file" \
-W "$dst_ips_forward_file" \
-b "$dst_ips_bypass" \
-w "$dst_ips_forward" \
-e "$ipt_args" \
-a "$a_args" \
-d "$d_args" \
$args \
--src-default "$src_default" \
--dst-default "$dst_default" \
--local-default "$local_default" \
--dst-bypass-file "$dst_ips_bypass_file" \
--dst-forward-file "$dst_ips_forward_file" \
--dst-bypass "$dst_ips_bypass" \
--dst-forward "$dst_ips_forward" \
--src-bypass "$src_ips_bypass" \
--src-forward "$src_ips_forward" \
--src-checkdst "$src_ips_checkdst" \
--ifnames "$ifnames" \
--ipt-extra "$ipt_args" \
|| "$bin" -f || "$bin" -f
} }
@ -299,15 +284,17 @@ validate_ss_rules_section() {
'disabled:bool:0' \ 'disabled:bool:0' \
'redir_tcp:uci("shadowsocks-libev", "@ss_redir")' \ 'redir_tcp:uci("shadowsocks-libev", "@ss_redir")' \
'redir_udp:uci("shadowsocks-libev", "@ss_redir")' \ 'redir_udp:uci("shadowsocks-libev", "@ss_redir")' \
'src_ips_bypass:list(ipaddr)' \
'src_ips_forward:list(ipaddr)' \
'src_ips_checkdst:list(ipaddr)' \
'src_ips_bypass:list(or(ip4addr,cidr4))' \
'src_ips_forward:list(or(ip4addr,cidr4))' \
'src_ips_checkdst:list(or(ip4addr,cidr4))' \
'dst_ips_bypass_file:file' \ 'dst_ips_bypass_file:file' \
'dst_ips_bypass:list(ipaddr)' \
'dst_ips_bypass:list(or(ip4addr,cidr4))' \
'dst_ips_forward_file:file' \ 'dst_ips_forward_file:file' \
'dst_ips_forward:list(ipaddr)' \
'src_default:or("bypass", "forward", "checkdst")' \
'local_default:or("bypass", "forward", "checkdst")' \
'dst_ips_forward:list(or(ip4addr,cidr4))' \
'src_default:or("bypass", "forward", "checkdst"):checkdst' \
'dst_default:or("bypass", "forward"):bypass' \
'local_default:or("bypass", "forward", "checkdst"):bypass' \
'ifnames:list(maxlength(15))' \
'ipt_args:string' 'ipt_args:string'
} }


+ 207
- 224
net/shadowsocks-libev/files/ss-rules View File

@ -1,260 +1,243 @@
#!/bin/sh
#!/bin/sh -e
# #
# Copyright (C) 2014-2017 Jian Chang <aa65535@live.com>
# Copyright (C) 2017 Yousong Zhou <yszhou4tech@gmail.com>
#
# The design idea was derived from ss-rules by Jian Chang <aa65535@live.com>
# #
# This is free software, licensed under the GNU General Public License v3. # This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information. # See /LICENSE for more information.
# #
usage() {
cat <<-EOF
Usage: ss-rules [options]
Valid options are:
-s <server_ips> ip address of shadowsocks remote server
-l <local_port> port number of shadowsocks local server
-S <server_ips> ip address of shadowsocks remote UDP server
-L <local_port> port number of shadowsocks local UDP server
-B <ip_list_file> a file whose content is bypassed ip list
-b <wan_ips> wan ip of will be bypassed
-W <ip_list_file> a file whose content is forwarded ip list
-w <wan_ips> wan ip of will be forwarded
-I <interface> proxy only for the given interface
-d <target> the default target of lan access control
-a <lan_hosts> lan ip of access control, need a prefix to
define proxy type
-e <extra_args> extra arguments for iptables
-o apply the rules to the OUTPUT chain
-O apply the global rules to the OUTPUT chain
-u enable udprelay mode, TPROXY is required
-U enable udprelay mode, using different IP
and ports for TCP and UDP
-f flush the rules
-h show this help message and exit
ss_usage() {
cat >&2 <<EOF
Usage: ss-rules [options]
-h, --help Show this help message then exit
-f, --flush Flush rules, ipset then exit
-l <port> Local port number of ss-redir with TCP mode
-L <port> Local port number of ss-redir with UDP mode
-s <ips> List of ip addresses of remote shadowsocks server
--ifnames Only apply rules on packets from these ifnames
--src-bypass <ips|cidr>
--src-forward <ips|cidr>
--src-checkdst <ips|cidr>
--src-default <bypass|forward|checkdst>
Packets will have their src ip checked in order against
bypass, forward, checkdst list and will bypass, forward
through, or continue to have their dst ip checked
respectively on the first match. Otherwise, --src-default
decide the default action
--dst-bypass <ips|cidr>
--dst-forward <ips|cidr>
--dst-bypass-file <file>
--dst-forward-file <file>
--dst-default <bypass|forward>
Same as with their --src-xx equivalent
--local-default <bypass|forward|checkdst>
Default action for local out TCP traffic
The following ipsets will be created by ss-rules. They are also intended to be
populated by other programs like dnsmasq with ipset support
ss_rules_src_bypass
ss_rules_src_forward
ss_rules_src_checkdst
ss_rules_dst_bypass
ss_rules_dst_forward
EOF EOF
exit $1
} }
loger() {
# 1.alert 2.crit 3.err 4.warn 5.notice 6.info 7.debug
logger -st ss-rules[$$] -p$1 $2
o_dst_bypass_="
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.0.0.0/24
192.0.2.0/24
192.31.196.0/24
192.52.193.0/24
192.88.99.0/24
192.168.0.0/16
192.175.48.0/24
198.18.0.0/15
198.51.100.0/24
203.0.113.0/24
224.0.0.0/4
240.0.0.0/4
255.255.255.255
"
o_src_default=bypass
o_dst_default=bypass
o_local_default=bypass
__errmsg() {
echo "ss-rules: $*" >&2
} }
flush_rules() {
iptables-save -c | grep -v "SS_SPEC" | iptables-restore -c
if command -v ip >/dev/null 2>&1; then
ip rule del fwmark 1 lookup 100 2>/dev/null
ip route del local default dev lo table 100 2>/dev/null
fi
for setname in $(ipset -n list | grep "ss_spec"); do
ipset destroy $setname 2>/dev/null
ss_rules_parse_args() {
while [ "$#" -gt 0 ]; do
case "$1" in
-h|--help) ss_usage; exit 0;;
-f|--flush) ss_rules_flush; exit 0;;
-l) o_redir_tcp_port="$2"; shift 2;;
-L) o_redir_udp_port="$2"; shift 2;;
-s) o_remote_servers="$2"; shift 2;;
--ifnames) o_ifnames="$2"; shift 2;;
--ipt-extra) o_ipt_extra="$2"; shift 2;;
--src-default) o_src_default="$2"; shift 2;;
--dst-default) o_dst_default="$2"; shift 2;;
--local-default) o_local_default="$2"; shift 2;;
--src-bypass) o_src_bypass="$2"; shift 2;;
--src-forward) o_src_forward="$2"; shift 2;;
--src-checkdst) o_src_checkdst="$2"; shift 2;;
--dst-bypass) o_dst_bypass="$2"; shift 2;;
--dst-forward) o_dst_forward="$2"; shift 2;;
--dst-bypass-file) o_dst_bypass_file="$2"; shift 2;;
--dst-forward-file) o_dst_forward_file="$2"; shift 2;;
*) __errmsg "unknown option $1"; return 1;;
esac
done done
FWI=$(uci get firewall.shadowsocks.path 2>/dev/null)
[ -n "$FWI" ] && echo '# firewall include file' >$FWI
return 0
}
ipset_init() {
ipset -! restore <<-EOF || return 1
create ss_spec_src_ac hash:ip hashsize 64
create ss_spec_src_bp hash:ip hashsize 64
create ss_spec_src_fw hash:ip hashsize 64
create ss_spec_dst_sp hash:net hashsize 64
create ss_spec_dst_bp hash:net hashsize 64
create ss_spec_dst_fw hash:net hashsize 64
$(gen_lan_host_ipset_entry)
$(gen_special_purpose_ip | sed -e "s/^/add ss_spec_dst_sp /")
$(sed -e "s/^/add ss_spec_dst_bp /" ${WAN_BP_LIST:=/dev/null} 2>/dev/null)
$(for ip in $WAN_BP_IP; do echo "add ss_spec_dst_bp $ip"; done)
$(sed -e "s/^/add ss_spec_dst_fw /" ${WAN_FW_LIST:=/dev/null} 2>/dev/null)
$(for ip in $WAN_FW_IP; do echo "add ss_spec_dst_fw $ip"; done)
EOF
return 0
}
ipt_nat() {
include_ac_rules nat
ipt="iptables -t nat"
$ipt -A SS_SPEC_WAN_FW -p tcp \
-j REDIRECT --to-ports $local_port || return 1
if [ -n "$OUTPUT" ]; then
$ipt -N SS_SPEC_WAN_DG
$ipt -A SS_SPEC_WAN_DG -m set --match-set ss_spec_dst_sp dst -j RETURN
$ipt -A SS_SPEC_WAN_DG -p tcp $EXT_ARGS -j $OUTPUT
$ipt -I OUTPUT 1 -p tcp -j SS_SPEC_WAN_DG
if [ -z "$o_redir_tcp_port" -a -z "$o_redir_udp_port" ]; then
__errmsg "Requires at least -l or -L option"
return 1
fi fi
return $?
} }
ipt_mangle() {
[ -n "$TPROXY" ] || return 0
if !(lsmod | grep -q TPROXY && command -v ip >/dev/null); then
loger 4 "TPROXY or ip not found."
return 0
fi
ip rule add fwmark 1 lookup 100
ip route add local default dev lo table 100
include_ac_rules mangle
iptables -t mangle -A SS_SPEC_WAN_FW -p udp \
-j TPROXY --on-port $LOCAL_PORT --tproxy-mark 0x01/0x01
return $?
ss_rules_flush() {
local setname
iptables-save --counters | grep -v ss_rules_ | iptables-restore --counters
while ip rule del fwmark 1 lookup 100 2>/dev/null; do true; done
ip route flush table 100
for setname in $(ipset -n list | grep "ss_rules_"); do
ipset destroy "$setname" 2>/dev/null || true
done
} }
export_ipt_rules() {
[ -n "$FWI" ] || return 0
cat <<-CAT >>$FWI
iptables-save -c | grep -v "SS_SPEC" | iptables-restore -c
iptables-restore -n <<-EOF
$(iptables-save | grep -E "SS_SPEC|^\*|^COMMIT" |\
sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/")
ss_rules_ipset_init() {
ipset --exist restore <<-EOF
create ss_rules_src_bypass hash:net hashsize 64
create ss_rules_src_forward hash:net hashsize 64
create ss_rules_src_checkdst hash:net hashsize 64
create ss_rules_dst_bypass hash:net hashsize 64
create ss_rules_dst_bypass_ hash:net hashsize 64
create ss_rules_dst_forward hash:net hashsize 64
$(ss_rules_ipset_mkadd ss_rules_dst_bypass_ "$o_dst_bypass_ $o_remote_servers")
$(ss_rules_ipset_mkadd ss_rules_src_bypass "$o_src_bypass")
$(ss_rules_ipset_mkadd ss_rules_src_forward "$o_src_forward")
$(ss_rules_ipset_mkadd ss_rules_src_checkdst "$o_src_checkdst")
$(ss_rules_ipset_mkadd ss_rules_dst_bypass "$o_dst_bypass $(cat "$o_dst_bypass_file" 2>/dev/null)")
$(ss_rules_ipset_mkadd ss_rules_dst_forward "$o_dst_forward $(cat "$o_dst_forward_file" 2>/dev/null)")
EOF EOF
CAT
return $?
} }
gen_lan_host_ipset_entry() {
for host in $LAN_HOSTS; do
case "${host:0:1}" in
n|N)
echo add ss_spec_src_ac ${host:2}
;;
b|B)
echo add ss_spec_src_bp ${host:2}
;;
g|G)
echo add ss_spec_src_fw ${host:2}
;;
esac
ss_rules_ipset_mkadd() {
local setname="$1"; shift
local i
for i in $*; do
echo "add $setname $i"
done done
} }
gen_special_purpose_ip() {
cat <<-EOF | grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}"
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.0.0.0/24
192.0.2.0/24
192.31.196.0/24
192.52.193.0/24
192.88.99.0/24
192.168.0.0/16
192.175.48.0/24
198.18.0.0/15
198.51.100.0/24
203.0.113.0/24
224.0.0.0/4
240.0.0.0/4
255.255.255.255
$server
$SERVER
EOF
ss_rules_iptchains_init() {
ss_rules_iptchains_init_tcp
ss_rules_iptchains_init_udp
} }
include_ac_rules() {
local protocol=$([ "$1" = "mangle" ] && echo udp || echo tcp)
iptables-restore -n <<-EOF
*$1
:SS_SPEC_LAN_DG - [0:0]
:SS_SPEC_LAN_AC - [0:0]
:SS_SPEC_WAN_AC - [0:0]
:SS_SPEC_WAN_FW - [0:0]
-A SS_SPEC_LAN_DG -m set --match-set ss_spec_dst_sp dst -j RETURN
-A SS_SPEC_LAN_DG -p $protocol $EXT_ARGS -j SS_SPEC_LAN_AC
-A SS_SPEC_LAN_AC -m set --match-set ss_spec_src_bp src -j RETURN
-A SS_SPEC_LAN_AC -m set --match-set ss_spec_src_fw src -j SS_SPEC_WAN_FW
-A SS_SPEC_LAN_AC -m set --match-set ss_spec_src_ac src -j SS_SPEC_WAN_AC
-A SS_SPEC_LAN_AC -j ${LAN_TARGET:=SS_SPEC_WAN_AC}
-A SS_SPEC_WAN_AC -m set --match-set ss_spec_dst_fw dst -j SS_SPEC_WAN_FW
-A SS_SPEC_WAN_AC -m set --match-set ss_spec_dst_bp dst -j RETURN
-A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
$(gen_prerouting_rules $protocol)
COMMIT
EOF
ss_rules_iptchains_init_tcp() {
local ipt="iptables -t nat"
local local_target
local forward_rules
local r
[ -n "$o_redir_tcp_port" ] || return 0
ss_rules_iptchains_init_ nat tcp
case "$o_local_default" in
checkdst) local_target=ss_rules_dst ;;
forward) local_target=ss_rules_forward ;;
bypass|*) return 0;;
esac
iptables-restore --noflush <<-EOF
*nat
:ss_rules_local_out -
-I OUTPUT 1 -p tcp -j ss_rules_local_out
-A ss_rules_local_out -m set --match-set ss_rules_dst_bypass_ dst -j RETURN
-A ss_rules_local_out -p tcp $o_ipt_extra -j $local_target -m comment --comment "local_default: $o_local_default"
COMMIT
EOF
} }
gen_prerouting_rules() {
[ -z "$IFNAMES" ] && echo -I PREROUTING 1 -p $1 -j SS_SPEC_LAN_DG
for ifname in $IFNAMES; do
echo -I PREROUTING 1 -i $ifname -p $1 -j SS_SPEC_LAN_DG
done
ss_rules_iptchains_init_udp() {
[ -n "$o_redir_udp_port" ] || return 0
ss_rules_iptchains_init_ mangle udp
} }
while getopts ":s:l:S:L:B:b:W:w:I:d:a:e:oOuUfh" arg; do
case "$arg" in
s)
server=$(for ip in $OPTARG; do echo $ip; done)
;;
l)
local_port=$OPTARG
;;
S)
SERVER=$(for ip in $OPTARG; do echo $ip; done)
;;
L)
LOCAL_PORT=$OPTARG
;;
B)
WAN_BP_LIST=$OPTARG
;;
b)
WAN_BP_IP=$OPTARG
;;
W)
WAN_FW_LIST=$OPTARG
;;
w)
WAN_FW_IP=$OPTARG
;;
I)
IFNAMES=$OPTARG
;;
d)
LAN_TARGET=$OPTARG
;;
a)
LAN_HOSTS=$OPTARG
;;
e)
EXT_ARGS=$OPTARG
;;
o)
OUTPUT=SS_SPEC_WAN_AC
;;
O)
OUTPUT=SS_SPEC_WAN_FW
;;
u)
TPROXY=1
;;
U)
TPROXY=2
;;
f)
flush_rules
exit 0
ss_rules_iptchains_init_() {
local table="$1"
local proto="$2"
local forward_rules
local src_default_target dst_default_target
case "$proto" in
tcp)
forward_rules="-A ss_rules_forward -p tcp -j REDIRECT --to-ports $o_redir_tcp_port"
;; ;;
h)
usage 0
udp)
ip rule add fwmark 1 lookup 100
ip route add local default dev lo table 100
forward_rules="-A ss_rules_forward -p udp -j TPROXY --on-port "$o_redir_udp_port" --tproxy-mark 0x01/0x01"
;; ;;
esac esac
done
case "$o_src_default" in
forward) src_default_target=ss_rules_forward ;;
checkdst) src_default_target=ss_rules_dst ;;
bypass|*) src_default_target=RETURN ;;
esac
case "$o_dst_default" in
forward) dst_default_target=ss_rules_forward ;;
bypass|*) dst_default_target=RETURN ;;
esac
iptables-restore --noflush <<-EOF
*$table
:ss_rules_pre_src -
:ss_rules_src -
:ss_rules_dst -
:ss_rules_forward -
$(ss_rules_iptchains_mkprerules "$proto")
-A ss_rules_pre_src -m set --match-set ss_rules_dst_bypass_ dst -j RETURN
-A ss_rules_pre_src -p $proto $o_ipt_extra -j ss_rules_src
-A ss_rules_src -m set --match-set ss_rules_src_bypass src -j RETURN
-A ss_rules_src -m set --match-set ss_rules_src_forward src -j ss_rules_forward
-A ss_rules_src -m set --match-set ss_rules_src_checkdst src -j ss_rules_dst
-A ss_rules_src -j $src_default_target -m comment --comment "src_default: $o_src_default"
-A ss_rules_dst -m set --match-set ss_rules_dst_bypass dst -j RETURN
-A ss_rules_dst -m set --match-set ss_rules_dst_forward dst -j ss_rules_forward
-A ss_rules_dst -j $dst_default_target -m comment --comment "dst_default: $o_dst_default"
$forward_rules
COMMIT
EOF
}
[ -z "$server" -o -z "$local_port" ] && usage 2
ss_rules_iptchains_mkprerules() {
local proto="$1"
if [ "$TPROXY" = 1 ]; then
unset SERVER
LOCAL_PORT=$local_port
elif [ "$TPROXY" = 2 ]; then
: ${SERVER:?"You must assign an ip for the udp relay server."}
: ${LOCAL_PORT:?"You must assign a port for the udp relay server."}
fi
if [ -z "$o_ifnames" ]; then
echo "-I PREROUTING 1 -p $proto -j ss_rules_pre_src"
else
echo "$o_ifnames" \
| tr ' ' '\n' \
| sed "s/.*/-I PREROUTING 1 -i \\0 -p $proto -j ss_rules_pre_src/"
fi
}
flush_rules && ipset_init && ipt_nat && ipt_mangle && export_ipt_rules
RET=$?
[ "$RET" = 0 ] || loger 3 "Start failed!"
exit $RET
ss_rules_parse_args "$@"
ss_rules_flush
ss_rules_ipset_init
ss_rules_iptchains_init

Loading…
Cancel
Save