Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[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

This comment has been minimized.

Copy link
Owner Author

commented Apr 18, 2017

Updated now.

@SilverBut

This comment has been minimized.

Copy link
Owner Author

commented Apr 18, 2017

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
You can’t perform that action at this time.