lede-packages-rs

git clone git://archive.git.mtrnord.blog/MTRNord/lede-packages-rs.git
Log | Files | Refs | README | LICENSE

ss-rules (4871B)


      1 #!/bin/sh
      2 
      3 usage() {
      4 	cat <<-EOF
      5 		Usage: ss-rules [options]
      6 
      7 		Valid options are:
      8 
      9 		    -s <server_host>        hostname or ip of shadowsocks remote server
     10 		    -l <local_port>         port number of shadowsocks local server
     11 		    -i <ip_list_file>       a file content is bypassed ip list
     12 		    -a <lan_ips>            lan ip of access control, need a prefix to
     13 		                            define access control mode
     14 		    -b <wan_ips>            wan ip of will be bypassed
     15 		    -w <wan_ips>            wan ip of will be forwarded
     16 		    -e <extra_options>      extra options for iptables
     17 		    -o                      apply the rules to the OUTPUT chain
     18 		    -u                      enable udprelay mode, TPROXY is required
     19 		    -U                      enable udprelay mode, using different IP
     20 		                            and ports for TCP and UDP
     21 		    -f                      flush the rules
     22 EOF
     23 }
     24 
     25 loger() {
     26 	# 1.alert 2.crit 3.err 4.warn 5.notice 6.info 7.debug
     27 	logger -st ss-rules[$$] -p$1 $2
     28 }
     29 
     30 ipt_n="iptables -t nat"
     31 ipt_m="iptables -t mangle"
     32 
     33 flush_r() {
     34 	local IPT
     35 
     36 	IPT=$(iptables-save -t nat)
     37 	eval $(echo "$IPT" | grep "_SS_SPEC_RULE_" | \
     38 		sed -e 's/^-A/$ipt_n -D/' -e 's/$/;/')
     39 
     40 	for chain in $(echo "$IPT" | awk '/^:SS_SPEC/{print $1}'); do
     41 		$ipt_n -F ${chain:1} 2>/dev/null && $ipt_n -X ${chain:1}
     42 	done
     43 
     44 	IPT=$(iptables-save -t mangle)
     45 	eval $(echo "$IPT" | grep "_SS_SPEC_RULE_" | \
     46 		sed -e 's/^-A/$ipt_m -D/' -e 's/$/;/')
     47 
     48 	for chain in $(echo "$IPT" | awk '/^:SS_SPEC/{print $1}'); do
     49 		$ipt_m -F ${chain:1} 2>/dev/null && $ipt_m -X ${chain:1}
     50 	done
     51 
     52 	ip rule del fwmark 0x01/0x01 table 100 2>/dev/null
     53 	ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null
     54 	ipset -X ss_spec_lan_ac 2>/dev/null
     55 	ipset -X ss_spec_wan_ac 2>/dev/null
     56 	return 0
     57 }
     58 
     59 ipset_r() {
     60 	ipset -! -R <<-EOF || return 1
     61 		create ss_spec_wan_ac hash:net
     62 		$(echo -e "$IPLIST" | sed -e "s/^/add ss_spec_wan_ac /")
     63 		$(for ip in $WAN_FW_IP; do echo "add ss_spec_wan_ac $ip nomatch"; done)
     64 EOF
     65 	$ipt_n -N SS_SPEC_WAN_AC && \
     66 	$ipt_n -A SS_SPEC_WAN_AC -m set --match-set ss_spec_wan_ac dst -j RETURN && \
     67 	$ipt_n -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
     68 	return $?
     69 }
     70 
     71 fw_rule() {
     72 	$ipt_n -N SS_SPEC_WAN_FW && \
     73 	$ipt_n -A SS_SPEC_WAN_FW -p tcp \
     74 		-j REDIRECT --to-ports $local_port 2>/dev/null || {
     75 		loger 3 "Can't redirect, please check the iptables."
     76 		exit 1
     77 	}
     78 	return $?
     79 }
     80 
     81 ac_rule() {
     82 	local TAG ROUTECHAIN
     83 
     84 	if [ -n "$LAN_AC_IP" ]; then
     85 		if [ "${LAN_AC_IP:0:1}" = "w" ]; then
     86 			TAG="nomatch"
     87 		else
     88 			if [ "${LAN_AC_IP:0:1}" != "b" ]; then
     89 				loger 3 "Bad argument \`-a $LAN_AC_IP\`."
     90 				return 2
     91 			fi
     92 		fi
     93 	fi
     94 
     95 	ROUTECHAIN=PREROUTING
     96 	if iptables-save -t nat | grep -q "^:zone_lan_prerouting"; then
     97 		ROUTECHAIN=zone_lan_prerouting
     98 	fi
     99 
    100 	ipset -! -R <<-EOF || return 1
    101 		create ss_spec_lan_ac hash:net
    102 		$(for ip in ${LAN_AC_IP:1}; do echo "add ss_spec_lan_ac $ip $TAG"; done)
    103 EOF
    104 	$ipt_n -A $ROUTECHAIN -p tcp $EXT_ARGS \
    105 		-m set ! --match-set ss_spec_lan_ac src \
    106 		-m comment --comment "_SS_SPEC_RULE_" -j SS_SPEC_WAN_AC
    107 
    108 	if [ "$OUTPUT" = 1 ]; then
    109 		$ipt_n -A OUTPUT -p tcp $EXT_ARGS \
    110 			-m comment --comment "_SS_SPEC_RULE_" -j SS_SPEC_WAN_AC
    111 	fi
    112 	return $?
    113 }
    114 
    115 tp_rule() {
    116 	[ -n "$TPROXY" ] || return 0
    117 	ip rule add fwmark 0x01/0x01 table 100
    118 	ip route add local 0.0.0.0/0 dev lo table 100
    119 	$ipt_m -N SS_SPEC_TPROXY
    120 	$ipt_m -A SS_SPEC_TPROXY -p udp -m set ! --match-set ss_spec_wan_ac dst \
    121 		-j TPROXY --on-port $LOCAL_PORT --tproxy-mark 0x01/0x01
    122 	$ipt_m -A PREROUTING -p udp $EXT_ARGS \
    123 		-m set ! --match-set ss_spec_lan_ac src \
    124 		-m comment --comment "_SS_SPEC_RULE_" -j SS_SPEC_TPROXY
    125 	return $?
    126 }
    127 
    128 while getopts ":s:l:S:L:i:e:a:b:w:ouUf" arg; do
    129 	case $arg in
    130 		s)
    131 			server=$OPTARG
    132 			;;
    133 		l)
    134 			local_port=$OPTARG
    135 			;;
    136 		S)
    137 			SERVER=$OPTARG
    138 			;;
    139 		L)
    140 			LOCAL_PORT=$OPTARG
    141 			;;
    142 		i)
    143 			IGNORE=$OPTARG
    144 			;;
    145 		e)
    146 			EXT_ARGS=$OPTARG
    147 			;;
    148 		a)
    149 			LAN_AC_IP=$OPTARG
    150 			;;
    151 		b)
    152 			WAN_BP_IP=$(for ip in $OPTARG; do echo $ip; done)
    153 			;;
    154 		w)
    155 			WAN_FW_IP=$OPTARG
    156 			;;
    157 		o)
    158 			OUTPUT=1
    159 			;;
    160 		u)
    161 			TPROXY=1
    162 			;;
    163 		U)
    164 			TPROXY=2
    165 			;;
    166 		f)
    167 			flush_r
    168 			exit 0
    169 			;;
    170 	esac
    171 done
    172 
    173 if [ -z "$server" -o -z "$local_port" ]; then
    174 	usage
    175 	exit 2
    176 fi
    177 
    178 if [ "$TPROXY" = 1 ]; then
    179 	SERVER=$server
    180 	LOCAL_PORT=$local_port
    181 fi
    182 
    183 if [ "$TPROXY" = 2 ]; then
    184 	if [ -z "$SERVER" -o -z "$LOCAL_PORT" ]; then
    185 		loger 3 "Please use -S and -L specifies IP and port for UDP."
    186 	fi
    187 fi
    188 
    189 if [ -f "$IGNORE" ]; then
    190 	IGNORE_IP=$(cat $IGNORE 2>/dev/null)
    191 fi
    192 
    193 IPLIST=$(cat <<-EOF | grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}"
    194 	$server
    195 	$SERVER
    196 	0.0.0.0/8
    197 	10.0.0.0/8
    198 	100.64.0.0/10
    199 	127.0.0.0/8
    200 	169.254.0.0/16
    201 	172.16.0.0/12
    202 	192.0.0.0/24
    203 	192.0.2.0/24
    204 	192.88.99.0/24
    205 	192.168.0.0/16
    206 	198.18.0.0/15
    207 	198.51.100.0/24
    208 	203.0.113.0/24
    209 	224.0.0.0/4
    210 	240.0.0.0/4
    211 	255.255.255.255
    212 	$WAN_BP_IP
    213 	$IGNORE_IP
    214 EOF
    215 )
    216 
    217 flush_r && fw_rule && ipset_r && ac_rule && tp_rule
    218 
    219 exit $?