From df395767d31593b4b3cfbda64d07aafa540b236c Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Sun, 13 Aug 2017 16:00:19 +0800 Subject: [PATCH] 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 --- net/shadowsocks-libev/Makefile | 2 +- net/shadowsocks-libev/README.md | 19 +- .../files/shadowsocks-libev.init | 75 ++- net/shadowsocks-libev/files/ss-rules | 431 +++++++++--------- 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 +# Copyright (C) 2017 Yousong Zhou +# +# The design idea was derived from ss-rules by Jian Chang # # 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 ip address of shadowsocks remote server - -l port number of shadowsocks local server - -S ip address of shadowsocks remote UDP server - -L port number of shadowsocks local UDP server - -B a file whose content is bypassed ip list - -b wan ip of will be bypassed - -W a file whose content is forwarded ip list - -w wan ip of will be forwarded - -I proxy only for the given interface - -d the default target of lan access control - -a lan ip of access control, need a prefix to - define proxy type - -e 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 < Local port number of ss-redir with TCP mode + -L Local port number of ss-redir with UDP mode + -s List of ip addresses of remote shadowsocks server + --ifnames Only apply rules on packets from these ifnames + --src-bypass + --src-forward + --src-checkdst + --src-default + 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 + --dst-forward + --dst-bypass-file + --dst-forward-file + --dst-default + Same as with their --src-xx equivalent + --local-default + 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