aboutsummaryrefslogtreecommitdiff
path: root/net/shadowsocks-libev
diff options
context:
space:
mode:
authorYousong Zhou <yszhou4tech@gmail.com>2017-08-13 16:00:19 +0800
committerYousong Zhou <yszhou4tech@gmail.com>2017-08-20 02:21:54 +0800
commitdf395767d31593b4b3cfbda64d07aafa540b236c (patch)
tree50d87bc9b651f9470c98ed1619e571a09eae289e /net/shadowsocks-libev
parentb1cd3a955ae57df9340ab6681dd6e2f16b13075d (diff)
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>
Diffstat (limited to 'net/shadowsocks-libev')
-rw-r--r--net/shadowsocks-libev/Makefile2
-rw-r--r--net/shadowsocks-libev/README.md19
-rw-r--r--net/shadowsocks-libev/files/shadowsocks-libev.init75
-rwxr-xr-xnet/shadowsocks-libev/files/ss-rules431
4 files changed, 253 insertions, 274 deletions
diff --git a/net/shadowsocks-libev/Makefile b/net/shadowsocks-libev/Makefile
index 2bca7f44b..307fac9d8 100644
--- a/net/shadowsocks-libev/Makefile
+++ b/net/shadowsocks-libev/Makefile
@@ -14,7 +14,7 @@ include $(TOPDIR)/rules.mk
#
PKG_NAME:=shadowsocks-libev
PKG_VERSION:=3.0.8
-PKG_RELEASE:=6
+PKG_RELEASE:=7
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/shadowsocks/shadowsocks-libev/releases/download/v$(PKG_VERSION)
diff --git a/net/shadowsocks-libev/README.md b/net/shadowsocks-libev/README.md
index 75790ea69..bb0545c51 100644
--- a/net/shadowsocks-libev/README.md
+++ b/net/shadowsocks-libev/README.md
@@ -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_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_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]
- --- for local out tcp packets, the default action can be specified with
-
- local_default [bypass], forward, checkdst
-
--- if the previous check result is checkdst,
--- 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 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
Useful paths and commands for debugging
diff --git a/net/shadowsocks-libev/files/shadowsocks-libev.init b/net/shadowsocks-libev/files/shadowsocks-libev.init
index e198c7e3b..0142cc1d8 100644
--- a/net/shadowsocks-libev/files/shadowsocks-libev.init
+++ b/net/shadowsocks-libev/files/shadowsocks-libev.init
@@ -107,7 +107,7 @@ ss_xxx() {
[ -x "$bin" ] || return
eval "$("validate_${cfgtype}_section" "$cfg" ss_validate_mklocal)"
- "validate_${cfgtype}_section" "$cfg"
+ "validate_${cfgtype}_section" "$cfg" || return 1
[ "$disabled" = 0 ] || return
if ss_mkjson \
@@ -127,21 +127,17 @@ ss_xxx() {
}
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
+ 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
eval "ss_rules_redir_tcp_$cfg=$local_port"
fi
if [ "$mode" = udp_only -o "$mode" = "tcp_and_udp" ]; then
eval "ss_rules_redir_udp_$cfg=$local_port"
- eval "ss_rules_redir_server_udp_$cfg=$server"
fi
fi
}
@@ -150,48 +146,37 @@ ss_rules() {
local cfg="ss_rules"
local bin="$ss_bindir/ss-rules"
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
config_get cfgtype "$cfg" TYPE
[ "$cfgtype" = ss_rules ] || return 1
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
eval local_port_tcp="\$ss_rules_redir_tcp_$redir_tcp"
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" \
- -s "$ss_rules_servers" \
+ -s "$ss_redir_servers" \
-l "$local_port_tcp" \
- -S "$server_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
}
@@ -299,15 +284,17 @@ validate_ss_rules_section() {
'disabled:bool:0' \
'redir_tcp: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:list(ipaddr)' \
+ 'dst_ips_bypass:list(or(ip4addr,cidr4))' \
'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'
}
diff --git a/net/shadowsocks-libev/files/ss-rules b/net/shadowsocks-libev/files/ss-rules
index 8bd7264af..660360434 100755
--- a/net/shadowsocks-libev/files/ss-rules
+++ b/net/shadowsocks-libev/files/ss-rules
@@ -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.
# 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
- 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
- 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
- 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
-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
}
-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
-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