|
最近需要从公网登录家里的Openwrt路由器,我家的宽带是有公网IP地址的,所以先配好DDNS。
但是在使用是发现,当路由器WAN的IP发生变化后,虽然DDNS已经更新成正确的新IP,但从外网还是无法SSH登录到路由器,提示目标主机主动拒绝。查看Openwrt上的系统日志,并没有发现关于拒绝登录的记录。正当不知所措时,偶然地运行一下ps查看dropbear的相关命令和参数,发现了一个问题。原来dropbear并不是监听某一个端口,而是监听一个固定的IP地址。而当WAN的IP发生变化后,dropbear仍然在监听原来的IP地址,导致无法从外网登录。我用的是CC版本和官方的DDNS包,不知道是只有我一个人有这个问题还是普遍的Bug。找到问题所在就好解决了,DDNS使用shell脚本来监听、对比和更新IP。找到脚本所在,使其在向DDNS服务器更新IP的同时,重启Openwrt自己的dropbear,即可解决问题。脚本的路径是 /usr/lib/ddns/dynamic_dns_functions.sh,向其中新增一行即可。
do_transfer "$__URL" || return 1
/etc/init.d/dropbear restart && write_log 7 "Dropbear restart successfully"
write_log 7 "DDNS Provider answered:\n$(cat $DATFILE)"
然后我又想让其在IP发生变化的时候,将新的IP用其它方式通知我,以备在DDNS服务失效的时候找到自己的路由,最后选择使用向移动139邮箱发邮件的方式通知。向139邮箱发邮件有一个好处,即可以免费同时接到手机短信。这样需要首先找一个其它的支持SMTP的邮箱作为发件方,由于国内的大部分免费邮箱都需要绑定手机才能开通SMTP,所以我选择了微软的Outlook邮箱,以下命令的参数也是Outlook邮箱的参数,如果换用其它的邮箱,则需要更换成对应的SMTP服务器地址和认证方式。邮件客户端我选用mailsend,好处是不需要任何配置文件,只用一行脚本即可实现发件。还是在刚才的脚本中新增两行。这样即便DDNS服务器失效,只要DDNS上我们注册的IP和我们路由器实际的IP不一致,就会一直将实际的IP通知我,直到DDNS上注册了正确的IP为止。
[ $use_https -ne 0 ] && __URL=$(echo $__URL | sed -e 's#^http:#https:#')
ifconfig pppoe-wan | awk -F'[ :]+' '/inet\ addr/{print $4}' > /tmp/curip
/usr/bin/mailsend -t [phone]@139.com -f [uesename]@outlook.com -4 -smtp smtp-mail.outlook.com -port 25 -user [uesename]@outlook.com -pass [password] -sub "IP change warning" -msg-body /tmp/curip -auth-login -starttls
do_transfer "$__URL" || return 1
最后我还想再留一条备用线路,考虑情况,由于各种原因,已经无法在外部连通路由,但路由本身还可以上网。如果路由器能定时地主动地到某个地方读取指令,就可以尝试在外部无法连通时修复路由。最初我还是考虑使用邮箱,通过POP3将邮箱上的邮件下载下来并执行其中的脚本,但找遍全网也没有找到能在Openwrt上用的POP3客户端。再考虑其它的ftp空间、网盘外链等基本也都没有免费的,最后选定使用博客,虽然博客处于公共空间无法认证身份,但如果真用到了这个备用线路的话,一般也就restart然后再试图通过正常的SSH连接,所以也没有什么保密信息。基本思路是路由器定时地下载博客主页,如果发现其中有脚本,就执行。这样在选择博客时,需要此博客对个人有固定的域名,几级无所谓但一定要固定。同时能在主页显示出尽量多的文章正文,并且最好关闭评论以防其他网友通过留言的方式控制路由器。需要运行的脚本需要嵌入在其它自定义且易识别的字段中,以便路由器在下载到博客页面后能方便地解析出要执行的语句。我使用
@2016020318@touch /mnt/test@2016020318@
这种格式来标识命令,在@中包括年月日小时信息,这样如果路由器设置为每一小时检查博客一次的话,就可以避免重复运行命令。所用到的脚本如下
#!/bin/sh
/usr/bin/wget [blog url] -O /tmp/cmdpage -q
DATE=$(date +%Y%m%d%H)
cat /tmp/cmdpage | grep "\@${DATE}\@.*\@${DATE}\@" > /tmp/tocmd
sed -i "s/.*\@${DATE}\@\(.*\)@${DATE}\@.*/\1/g" /tmp/tocmd
sed -i 's/</</g' /tmp/tocmd
sed -i 's/>/>/g' /tmp/tocmd
sed -i 's/&/&/g' /tmp/tocmd
sed -i 's/"/"/g' /tmp/tocmd
sed -i 's/ / /g' /tmp/tocmd
sed -i '1 i#!/bin/sh' /tmp/tocmd
chmod 700 /tmp/tocmd
. /tmp/tocmd
1、使用wget将网页下载到本地
2、读取系统当前时间,精确到小时
3、从下载到的网页中找到含有标识符的行,并写入到新文件中
4、去掉标识符和其前后的其它字符,只留命令本身
5、恢复HTML中的转义字符
6、加入shell信息行
7、赋予可执行权限并执行
这样再按常规方法配置计划任务,即可在所有外部通道失效时,使用网页控制路由。
|
评分
-
查看全部评分
|