Skip to content

Instantly share code, notes, and snippets.

@SilverBut
Last active May 1, 2017 19:24
Show Gist options
  • Save SilverBut/501492bd69ad63b1ccf31973b2e28bf6 to your computer and use it in GitHub Desktop.
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
#!/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 $@
@SilverBut
Copy link
Author

Updated now.

@SilverBut
Copy link
Author

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