Created
December 21, 2016 16:25
-
-
Save Nullizer/c7aa760c9c9196a7e152404e270d4e41 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh /etc/rc.common | |
# | |
# Copyright (C) 2016 Jian Chang <[email protected]> | |
# | |
# This is free software, licensed under the GNU General Public License v3. | |
# See /LICENSE for more information. | |
# | |
START=90 | |
STOP=15 | |
NAME=shadowsocks | |
EXTRA_COMMANDS=rules | |
CONFIG_FILE=/var/etc/$NAME.json | |
uci_get_by_name() { | |
local ret=$(uci get $NAME.$1.$2 2>/dev/null) | |
echo ${ret:=$3} | |
} | |
uci_get_by_type() { | |
local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null) | |
echo ${ret:=$3} | |
} | |
uci_bool_by_name() { | |
case "$(uci_get_by_name $1 $2)" in | |
1|on|true|yes|enabled) return 0;; | |
esac | |
return 1 | |
} | |
valid_server() { | |
[ "$(uci get $NAME.$1 2>/dev/null)" = "servers" ] | |
} | |
get_arg_udp() { | |
local server=$(uci_get_by_type transparent_proxy udp_relay_server) | |
[ "$server" = "same" ] || valid_server $server && echo "-u" | |
} | |
get_arg_out() { | |
case "$(uci_get_by_type access_control self_proxy 1)" in | |
1) echo "-o";; | |
2) echo "-O";; | |
esac | |
} | |
get_arg_ota() { | |
uci_bool_by_name $1 auth && echo "-A" | |
} | |
get_arg_tfo() { | |
if [ "3" = "$(cat /proc/sys/net/ipv4/tcp_fastopen 2>/dev/null)" ]; then | |
uci_bool_by_name $1 fast_open && echo "--fast-open" | |
fi | |
} | |
get_server_ips() { | |
echo $(uci_get_by_name $1 server) | |
} | |
get_lan_hosts() { | |
uci_bool_by_name $1 enable && \ | |
echo "$(uci_get_by_name $1 type),$(uci_get_by_name $1 host)" | |
} | |
gen_config_file() { | |
cat <<-EOF >$CONFIG_FILE | |
{ | |
"server": "$(uci_get_by_name $1 server)", | |
"server_port": $(uci_get_by_name $1 server_port), | |
"local_address": "0.0.0.0", | |
"password": "$(uci_get_by_name $1 password)", | |
"timeout": $(uci_get_by_name $1 timeout 60), | |
"method": "$(uci_get_by_name $1 encrypt_method)" | |
} | |
EOF | |
} | |
start_rules() { | |
config_load $NAME | |
/usr/bin/ss-rules \ | |
-s "$(config_foreach get_server_ips servers)" \ | |
-l "$(uci_get_by_type transparent_proxy local_port 1234)" \ | |
-i "$(uci_get_by_type access_control wan_bp_list)" \ | |
-b "$(uci_get_by_type access_control wan_bp_ips)" \ | |
-w "$(uci_get_by_type access_control wan_fw_ips)" \ | |
-I "$(uci_get_by_type access_control lan_ifaces)" \ | |
-d "$(uci_get_by_type access_control lan_target)" \ | |
-a "$(config_foreach get_lan_hosts lan_hosts)" \ | |
-e "$(uci_get_by_type access_control ipt_ext)" \ | |
$(get_arg_out) $(get_arg_udp) | |
ipset create chnroute hash:net | |
sed 's/^/add chnroute /g' /etc/ignore.list | ipset restore | |
iptables -t nat -I SS_SPEC_WAN_AC 1 -p tcp -m set --match-set chnroute dst -j RETURN | |
} | |
rules() { | |
if !(pidof ss-redir >/dev/null); then | |
logger -st $NAME -p3 "ss-redir not running." | |
return 1 | |
fi | |
start_rules || /usr/bin/ss-rules -f | |
} | |
start_redir() { | |
gen_config_file $1 | |
ss-redir -c $CONFIG_FILE $2 $(get_arg_ota $1) \ | |
-l $(uci_get_by_type transparent_proxy local_port 1234) \ | |
-f /var/run/ss-redir$3.pid | |
} | |
ss_redir() { | |
command -v ss-redir >/dev/null 2>&1 || return 1 | |
local main_server=$(uci_get_by_type transparent_proxy main_server) | |
valid_server $main_server || return 1 | |
local udp_relay_server=$(uci_get_by_type transparent_proxy udp_relay_server) | |
[ "$udp_relay_server" = "same" ] && udp_relay_server=$main_server | |
if [ "$udp_relay_server" = "$main_server" ]; then | |
start_redir $main_server -u | |
elif valid_server $udp_relay_server; then | |
start_redir $main_server | |
start_redir $udp_relay_server -U -udp | |
else | |
start_redir $main_server | |
fi | |
} | |
start_local() { | |
gen_config_file $1 | |
ss-local -c $CONFIG_FILE -u $(get_arg_ota $1) $(get_arg_tfo $1) \ | |
-l $(uci_get_by_type socks5_proxy local_port 1080) \ | |
-f /var/run/ss-local.pid | |
} | |
ss_local() { | |
command -v ss-local >/dev/null 2>&1 || return 0 | |
local server=$(uci_get_by_type socks5_proxy server) | |
valid_server $server && start_local $server | |
} | |
start_tunnel() { | |
gen_config_file $1 | |
ss-tunnel -c $CONFIG_FILE -u $(get_arg_ota $1) \ | |
-l $(uci_get_by_type port_forward local_port 5300) \ | |
-L $(uci_get_by_type port_forward destination 8.8.4.4:53) \ | |
-f /var/run/ss-tunnel.pid | |
} | |
ss_tunnel() { | |
command -v ss-tunnel >/dev/null 2>&1 || return 0 | |
local server=$(uci_get_by_type port_forward server) | |
valid_server $server && start_tunnel $server | |
} | |
start() { | |
mkdir -p /var/run /var/etc | |
ss_redir && rules | |
ss_local | |
ss_tunnel | |
rm -f $CONFIG_FILE | |
} | |
kill_all() { | |
kill -9 $(pidof $@) >/dev/null 2>&1 | |
} | |
stop() { | |
/usr/bin/ss-rules -f | |
kill_all ss-redir ss-local ss-tunnel | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment