Last active
May 1, 2017 19:24
-
-
Save SilverBut/501492bd69ad63b1ccf31973b2e28bf6 to your computer and use it in GitHub Desktop.
[Manual network solution] Work for my personal network problems in mainland China. #tags: GFW, network, shadowsocks, route, vpn
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
#!/usr/bin/sh | |
SCRIPTNAME=`basename $0` | |
function log_err() { echo "[$SCRIPTNAME][E] $@" 1>&2; } | |
function log() { echo "[$SCRIPTNAME][I] $@" 1>&2; } | |
RESULT_OK=0 | |
RESULT_FAILED=1 | |
RESULT_ARGS_ERR=2 | |
srv__vpn() { | |
vpn_name="YOUR-VPN-IN-NETWORKMANAGER" | |
operation=$1 | |
function vpn_start { | |
log "Performing VPN $vpn_name operation: start" | |
nmcli connection up $vpn_name | |
} | |
function vpn_stop { | |
log "Performing VPN $vpn_name operation: stop" | |
nmcli connection down $vpn_name | |
} | |
function vpn_test { | |
log "Performing VPN $vpn_name operation: test" | |
nmcli connection show $vpn_name | grep -E "^GENERAL.STATE:\s+activated$" > /dev/null | |
} | |
case "$operation" in | |
"start") | |
vpn_start | |
;; | |
"stop") | |
vpn_stop | |
;; | |
"test") | |
vpn_test | |
;; | |
"restart") | |
vpn_stop | |
sleep 1 | |
vpn_start | |
;; | |
*) | |
return $RESULT_ARGS_ERR | |
;; | |
esac | |
} | |
srv__route() { | |
route_table="chnip_list.txt" | |
operation=$1 | |
route_if="192.168.0.1" | |
route_add_cmd_pre="sudo ip route add" | |
route_add_cmd_post="via $route_if" | |
route_del_cmd_pre="sudo ip route del" | |
route_del_cmd_post="via $route_if" | |
function route_start { | |
log "Performing route operation: start" | |
log_err "This action will always return true, and exit once error" | |
while read route_item;do | |
$route_add_cmd_pre $route_item $route_add_cmd_post | |
if [[ $? -ne 0 ]]; then | |
log_err "Failed to add item $route_item" | |
break | |
fi | |
done < $route_table | |
return $RESULT_OK | |
} | |
function route_stop { | |
log "Performing route operation: stop" | |
log_err "This action will always return true, and exit once error" | |
while read route_item;do | |
$route_del_cmd_pre $route_item $route_del_cmd_post | |
if [[ $? -ne 0 ]]; then | |
log_err "Failed to del item $route_item" | |
break | |
fi | |
done < $route_table | |
return $RESULT_OK | |
} | |
function route_test { | |
log_err "This service have no test option." | |
return $RESULT_OK | |
} | |
case "$operation" in | |
"start") | |
route_start | |
;; | |
"stop") | |
route_stop | |
;; | |
"test") | |
route_test | |
;; | |
"restart") | |
route_stop | |
sleep 1 | |
route_start | |
;; | |
*) | |
return $RESULT_ARGS_ERR | |
;; | |
esac | |
} | |
srv__shadowsocks() { | |
nodelist=( | |
'node=(method | |
server port | |
listen atport | |
key)' | |
'node=(method | |
server port | |
listen atport | |
key)' | |
) | |
ssclient=ss-local | |
operation=$1 | |
rundir=/data/software/shadowsocks/pids | |
function ss_start { | |
log "Performing Shadowsocks operation: start" | |
for elt in "${nodelist[@]}"; do | |
eval $elt | |
log "Starting process at ${node[3]}:${node[4]}." | |
node_pidfile="$rundir/${node[4]}.pid" | |
$ssclient -m ${node[0]} -s ${node[1]} -p ${node[2]} -b ${node[3]} -l ${node[4]} -k ${node[5]} -v --fast-open -f $node_pidfile | |
done | |
if [[ ss_test -ne 0 ]] ; then | |
log_err "Failed status detected. Exiting now." | |
ss_stop | |
fi | |
log "Shadowsocks started." | |
cow_pid="$rundir/cow.pid" | |
nohup cow & | |
echo -ne $! > $cow_pid | |
log "Cow/Meow started." | |
sudo systemctl start haproxy | |
log "Haproxy started" | |
sudo systemctl start privoxy | |
log "Privoxy started" | |
} | |
function ss_stop { | |
log "Performing Shadowsocks operation: stop" | |
sudo systemctl stop privoxy | |
sudo systemctl stop haproxy | |
for pidfile in $rundir/*.pid; do | |
log "Killing $pidfile" | |
kill `cat $pidfile` | |
if [[ $? -eq 0 ]] ; then | |
rm $pidfile | |
fi | |
done | |
log "Shadowsocks started." | |
return $RESULT_OK | |
} | |
function ss_test { | |
log "Performing Shadowsocks operation: test" | |
pid_files=$(shopt -s nullglob dotglob; echo $rundir/*) | |
if [[ ${#pid_files} -eq 0 ]]; then | |
log "Have no pid file. Thinking as nothing here." | |
return $RESULT_FAILED | |
fi | |
for pid_file in ${pid_files[@]}; do | |
log "Checking if pid `cat $pid_file` exists" | |
kill -0 `cat $pid_file` > /dev/null 2>&1 | |
if [[ $? -ne 0 ]] ; then | |
log_err "Halted $pidfile" | |
return $RESULT_FAILED | |
fi | |
done | |
systemctl status privoxy haproxy > /dev/null | |
if [[ $? -ne 0 ]] ; then | |
log_err "Halted Privoxy or Haproxy" | |
return $RESULT_FAILED | |
fi | |
return $RESULT_OK | |
} | |
case "$operation" in | |
"start") | |
ss_start | |
;; | |
"stop") | |
ss_stop | |
;; | |
"test") | |
ss_test | |
;; | |
"restart") | |
ss_stop | |
sleep 1 | |
ss_start | |
;; | |
*) | |
return $RESULT_ARGS_ERR | |
;; | |
esac | |
} | |
function get_service_list(){ | |
echo $(declare -f | grep -oP '^srv__\K\w+') | |
} | |
function if_service_exists() { | |
srv_list=$(get_service_list) | |
for e in $srv_list; do [[ "$e" == "$1" ]] && return 0; done | |
return 1 | |
} | |
function usage() { | |
scriptname=`basename "$0"` | |
echo "Usage: $scriptname # this usage" | |
echo " $scriptname <start|stop|restart|test>" | |
echo " $scriptname <service> # default is test" | |
echo " $scriptname <service> [start|stop|restart|test]" | |
} | |
function service_test(){ | |
if srv__$1 test ; then | |
echo "Running $1 OK" | |
else | |
echo "Not running $1 or having an arror." | |
fi | |
} | |
function main() { | |
case $# in | |
1) | |
case $1 in | |
"start") | |
;& | |
"stop") | |
;& | |
"restart") | |
;& | |
"test") | |
srv_list=$(get_service_list) | |
for e in $srv_list; do | |
srv__$e $1 | |
done | |
;; | |
*) | |
if if_service_exists $1 ; then | |
service_test $1 | |
else | |
echo Invalid service. | |
echo Avaliable services are: | |
get_service_list | |
fi | |
;; | |
esac | |
;; | |
2) | |
if [[ $2 == "test" ]]; then | |
service_test $1 | |
else | |
srv__$1 $2 | |
fi | |
;; | |
*) | |
usage $@ | |
;; | |
esac | |
} | |
if test "`/usr/bin/id -u`" == 0 ; then | |
echo "$0: You should NOT be root to run this script" >& 2 | |
exit 1 | |
fi | |
main $@ |
Fixed bug of having wrong VPN indication
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated now.