在《这事不能说太细之openwrt》中我们提到了一个watchdog脚本,就是每隔10分钟执行一次,检查google和百度的网页,如果能访问百度但是不能访问google,就认为是ss服务有问题,重启ss服务;如果google额百度的网页都不能访问,说明是连接英特网有问题,则记录“Network Problem. Do nothing”,不做任何调整。
今天我们对这个脚本来改进一下,如果我们从log中发现已经重启了3次ss服务,那么我们就认为该ss服务连接的远端服务器有问题,我们切换到另一个ss服务器;如果我们从log中发现了记录3次网络连接有问题,我们就尝试重启路由器。
先来看看思路:
由于我们shadowsocks的配置文件是/etc/shadowsocks/config.json,那么我们提前准备好各个服务器的配置文件,当config.json有问题,那么就用config.json.ssserver1.hk1替换掉config.json;如果还不行,就用下一个config.json.ssserver1.ca1 替换掉config.json。
而这个问题的关键点是识别当前的config.json用的是哪个配置,本来在config.json中加一个注释用来做检测是个不错的思路,但是json的文件不能用一般的//做注释,或者用/* */做注释,我们得手工添加一个变量作为注释:
{
"_comment" : " 这里是个注释 ",
"server": "123.456.789.10",
"server_port": 10248,
"local": "0.0.0.0",
"local_port": 1080,
"password": "Thisispwd",
"timeout": 60,
"method": "rc4-md5"
}
我们可以把服务器名字放在这里。如
config.json.ssserver1.hk1文件的内容是
{
"_comment" : " config.json.ssserver1.hk1 ",
"server": "123.456.789.10",
"server_port": 10248,
"local": "0.0.0.0",
"local_port": 1080,
"password": "Thisispwd",
"timeout": 60,
"method": "rc4-md5"
}
config.json.ssserver1.ca1文件的内容是
{
"_comment" : " config.json.ssserver1.ca1 ",
"server": "123.456.789.11",
"server_port": 10248,
"local": "0.0.0.0",
"local_port": 1080,
"password": "Thisispwd",
"timeout": 60,
"method": "rc4-md5"
}
以此类推,准备多个服务器的配置文件放在/etc/shadowsocks/下。
然后我们再做一个服务器列表:
root@OpenWrt:/etc/shadowsocks# cat server_list.txt
1 config.json.ssserver1.hk1
2 config.json.ssserver1.ca1
3 config.json.ssserver1.sg1
4 config.json.ssserver1.jp1
5 config.json.ssserver2.us1
6 config.json.ssserver3.tw1
7 config.json.ssserver4.hk1
root@OpenWrt:/etc/shadowsocks#
有了这2类文件之后,我们就可以判断当前config.json使用的那个配置文件,然后判断其在服务器列表的位置,然后取下一位的服务器名称。
整体的脚本,如下:
root@OpenWrt:~# cat /root/orasup/check_ss.sh
#!/bin/sh
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
wget -4 --spider --quiet --tries=1 --timeout=3 www.google.co.jp
if [ "$?" == "0" ]; then
echo '['$LOGTIME'] No Problem.'
else
wget -4 --spider --quiet --tries=1 --timeout=3 www.baidu.com
if [ "$?" == "0" ]; then
echo '['$LOGTIME'] Problem decteted, restarting shadowsocks.'
/etc/init.d/shadowsocks restart
else
echo '['$LOGTIME'] Network Problem. Do nothing.'
fi
fi
#####################
## Switch ss server when error message "Problem decteted, restarting shadowsocks" 3 times:
#####################
current_filename=`cat /etc/shadowsocks/config.json |grep comment |awk '{print $4}'`
current_servernumber=`cat /etc/shadowsocks/server_list.txt |grep $current_filename |awk '{print $1}'`
next_filename=`cat /etc/shadowsocks/server_list.txt |grep -A1 $current_filename |tail -1 |awk '{print $2}'`
next_servernumber=`cat /etc/shadowsocks/server_list.txt |grep $next_filename |awk '{print $1}'`
max_servernumber=`cat /etc/shadowsocks/server_list.txt |wc -l`
restart_ss_error_number=`cat /var/log/shadowsocks_watchdog.log |grep "Problem decteted, restarting shadowsocks" |wc -l`
network_error_number=`cat /var/log/shadowsocks_watchdog.log |grep "Network Problem. Do nothing" |wc -l`
if [ "$current_servernumber" -eq "$max_servernumber" ]; then
next_filename=`cat server_list.txt |head -1 |awk '{print $2}'`
fi
if [ "$restart_ss_error_number" -gt 3 ]; then
echo '['$LOGTIME'] Switch SS server to '$next_filename'.'
cp '/etc/shadowsocks/'$next_filename /etc/shadowsocks/config.json
/etc/init.d/shadowsocks restart
cat /var/log/shadowsocks_watchdog.log |grep -v "Problem decteted, restarting shadowsocks" > /var/log/shadowsocks_watchdog.log.tmp
mv /var/log/shadowsocks_watchdog.log.tmp /var/log/shadowsocks_watchdog.log
fi
##################################
## Restart router when error message "Network Problem. Do nothing" 3 times:
##################################
if [ "$network_error_number" -gt 3 ]; then
echo '['$LOGTIME'] Network error. Restart router.'
cat /var/log/shadowsocks_watchdog.log |grep -v "Network Problem. Do nothing" > /var/log/shadowsocks_watchdog.log.tmp
mv /var/log/shadowsocks_watchdog.log.tmp /var/log/shadowsocks_watchdog.log
/sbin/reboot
fi
我们把它放在crontab中每隔10分钟定期运行:
crontab -1
*/10 * * * * /root/orasup/check_ss.sh >> /var/log/shadowsocks_watchdog.log 2>&1