3 # Copyright (C) 2014-2017 Jian Chang <aa65535@live.com>
5 # This is free software, licensed under the GNU General Public License v3.
6 # See /LICENSE for more information.
11 Usage: ss-rules [options]
15 -s <server_ips> ip address of shadowsocks remote server
16 -l <local_port> port number of shadowsocks local server
17 -S <server_ips> ip address of shadowsocks remote UDP server
18 -L <local_port> port number of shadowsocks local UDP server
19 -B <ip_list_file> a file whose content is bypassed ip list
20 -b <wan_ips> wan ip of will be bypassed
21 -W <ip_list_file> a file whose content is forwarded ip list
22 -w <wan_ips> wan ip of will be forwarded
23 -I <interface> proxy only for the given interface
24 -d <target> the default target of lan access control
25 -a <lan_hosts> lan ip of access control, need a prefix to
27 -e <extra_args> extra arguments for iptables
28 -o apply the rules to the OUTPUT chain
29 -O apply the global rules to the OUTPUT chain
30 -u enable udprelay mode, TPROXY is required
31 -U enable udprelay mode, using different IP
32 and ports for TCP and UDP
34 -h show this help message and exit
40 # 1.alert 2.crit 3.err 4.warn 5.notice 6.info 7.debug
41 logger
-st ss-rules
[$$
] -p$1 $2
45 iptables-save
-c |
grep -v "SS_SPEC" | iptables-restore
-c
46 if command -v ip
>/dev
/null
2>&1; then
47 ip rule del fwmark
1 lookup
100 2>/dev
/null
48 ip route del
local default dev lo table
100 2>/dev
/null
50 for setname
in $
(ipset
-n list |
grep "ss_spec"); do
51 ipset destroy
$setname 2>/dev
/null
53 FWI
=$
(uci get firewall.shadowsocks.path
2>/dev
/null
)
54 [ -n "$FWI" ] && echo '# firewall include file' >$FWI
59 ipset
-! restore
<<-EOF || return 1
60 create ss_spec_src_ac hash:ip hashsize 64
61 create ss_spec_src_bp hash:ip hashsize 64
62 create ss_spec_src_fw hash:ip hashsize 64
63 create ss_spec_dst_sp hash:net hashsize 64
64 create ss_spec_dst_bp hash:net hashsize 64
65 create ss_spec_dst_fw hash:net hashsize 64
66 $(gen_lan_host_ipset_entry)
67 $(gen_special_purpose_ip | sed -e "s/^/add ss_spec_dst_sp /")
68 $(sed -e "s/^/add ss_spec_dst_bp /" ${WAN_BP_LIST:=/dev/null} 2>/dev/null)
69 $(for ip in $WAN_BP_IP; do echo "add ss_spec_dst_bp $ip"; done)
70 $(sed -e "s/^/add ss_spec_dst_fw /" ${WAN_FW_LIST:=/dev/null} 2>/dev/null)
71 $(for ip in $WAN_FW_IP; do echo "add ss_spec_dst_fw $ip"; done)
79 $ipt -A SS_SPEC_WAN_FW
-p tcp \
80 -j REDIRECT
--to-ports $local_port ||
return 1
81 if [ -n "$OUTPUT" ]; then
82 $ipt -N SS_SPEC_WAN_DG
83 $ipt -A SS_SPEC_WAN_DG
-m set --match-set ss_spec_dst_sp dst
-j RETURN
84 $ipt -A SS_SPEC_WAN_DG
-p tcp
$EXT_ARGS -j $OUTPUT
85 $ipt -I OUTPUT
1 -p tcp
-j SS_SPEC_WAN_DG
91 [ -n "$TPROXY" ] ||
return 0
92 if !(lsmod |
grep -q TPROXY
&& command -v ip
>/dev
/null
); then
93 loger
4 "TPROXY or ip not found."
96 ip rule add fwmark
1 lookup
100
97 ip route add
local default dev lo table
100
98 include_ac_rules mangle
99 iptables
-t mangle
-A SS_SPEC_WAN_FW
-p udp \
100 -j TPROXY
--on-port $LOCAL_PORT --tproxy-mark 0x01/0x01
105 [ -n "$FWI" ] ||
return 0
107 iptables-save -c | grep -v "SS_SPEC" | iptables-restore -c
108 iptables-restore -n <<-EOF
109 $(iptables-save | grep -E "SS_SPEC|^\*|^COMMIT" |\
110 sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/")
116 gen_lan_host_ipset_entry
() {
117 for host in $LAN_HOSTS; do
118 case "${host:0:1}" in
120 echo add ss_spec_src_ac
${host:2}
123 echo add ss_spec_src_bp
${host:2}
126 echo add ss_spec_src_fw
${host:2}
132 gen_special_purpose_ip
() {
133 cat <<-EOF | grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}"
159 local protocol
=$
([ "$1" = "mangle" ] && echo udp ||
echo tcp
)
160 iptables-restore
-n <<-EOF
162 :SS_SPEC_LAN_DG - [0:0]
163 :SS_SPEC_LAN_AC - [0:0]
164 :SS_SPEC_WAN_AC - [0:0]
165 :SS_SPEC_WAN_FW - [0:0]
166 -A SS_SPEC_LAN_DG -m set --match-set ss_spec_dst_sp dst -j RETURN
167 -A SS_SPEC_LAN_DG -p $protocol $EXT_ARGS -j SS_SPEC_LAN_AC
168 -A SS_SPEC_LAN_AC -m set --match-set ss_spec_src_bp src -j RETURN
169 -A SS_SPEC_LAN_AC -m set --match-set ss_spec_src_fw src -j SS_SPEC_WAN_FW
170 -A SS_SPEC_LAN_AC -m set --match-set ss_spec_src_ac src -j SS_SPEC_WAN_AC
171 -A SS_SPEC_LAN_AC -j ${LAN_TARGET:=SS_SPEC_WAN_AC}
172 -A SS_SPEC_WAN_AC -m set --match-set ss_spec_dst_fw dst -j SS_SPEC_WAN_FW
173 -A SS_SPEC_WAN_AC -m set --match-set ss_spec_dst_bp dst -j RETURN
174 -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
175 $(gen_prerouting_rules $protocol)
180 gen_prerouting_rules
() {
181 [ -z "$IFNAMES" ] && echo -I PREROUTING
1 -p $1 -j SS_SPEC_LAN_DG
182 for ifname
in $IFNAMES; do
183 echo -I PREROUTING
1 -i $ifname -p $1 -j SS_SPEC_LAN_DG
187 while getopts ":s:l:S:L:B:b:W:w:I:d:a:e:oOuUfh" arg
; do
190 server
=$
(for ip
in $OPTARG; do echo $ip; done)
196 SERVER
=$
(for ip
in $OPTARG; do echo $ip; done)
226 OUTPUT
=SS_SPEC_WAN_AC
229 OUTPUT
=SS_SPEC_WAN_FW
247 [ -z "$server" -o -z "$local_port" ] && usage
2
249 if [ "$TPROXY" = 1 ]; then
251 LOCAL_PORT
=$local_port
252 elif [ "$TPROXY" = 2 ]; then
253 : ${SERVER:?"You must assign an ip for the udp relay server."}
254 : ${LOCAL_PORT:?"You must assign a port for the udp relay server."}
257 flush_rules
&& ipset_init
&& ipt_nat
&& ipt_mangle
&& export_ipt_rules
259 [ "$RET" = 0 ] || loger
3 "Start failed!"