本帖最后由 cedricdai 于 2015-6-14 14:03 编辑
完美实现用邮件通知方式告知DD-WRT路由WAN口实时外网IP信息替代动态DDNS 对于有远程控制需求的同学们,一直受制于使用动态DDNS绑定第三方动态域名的方式来获取对自己想要远程IP地址的访问,比如使用比较流行的花生壳,3322等动态域名,其实他们的原理也就是获取你的外网IP地址和他们的域名直接绑定而已,例如你的路由(我拿路由器举例)WAN口现在的外网地址是118.25.30.55(我随便写的),一般在TPLINK的路由器中会有内置的花生壳绑定服务,你只要填入了相关账号信息,它就可以把你现有的外网IP:118.25.30.55绑定到一个动态域名,比如test.oicp.net(这个是花生壳的一种动态域名方式),如果绑定成功的话,你现在只需要在外网(非你家同一个路由下的内网)的浏览器地址栏输入http:// test.oicp.net,一般即可访问到你的路由器wan口了,如果开了防火墙,设置了相应的端口映射,输入http:// test.oicp.net:端口号,便可访问相关服务了。但是,第三方提供的动态域名绑定免费的总归效率不高,有时候还会无法服务,那通过例如访问http:// test.oicp.net就会报错,达不到自己想要的外网控制的目的。其实换种思路,如果我直接知道了我的WAN口IP地址,不就可以直接输入访问了吗,何必需要中间有这个动态域名绑定解析呢?比如现在直接知道了你的WAN口外网IP:118.25.30.55,你在外网浏览器可以直接输入http:// 118.25.30.55,便可轻松访问到想要访问的内网路由。这里问题就来了,因为私人用户一般很少会有固定的外网IP的,多是随机的动态外网IP,所以,路由的WAN口IP信息会不定时的更新变更,那当你身处在外时,便也无从知晓想要远程的这个外网IP地址信息了。【更多的,大家可以自己百度相关端口映射,DDNS知识,我懂得也只不过是皮毛。】 本文所针对的是使用DD-WRT系统的路由,其他系统的路由我也没有研究过,具体路由怎么刷DD-WRT系统请自行百度相关知识。 进入DD-WRT,管理 -> 命令菜单,在文本框输入以下内容,并点击“保存为自定义指令”按钮
以下脚本支持SMTP AUTH,因此需要首先准备邮件账号和密码的base64编码
=`echo -n "test@test.com" | opensslbase64`
=`echo -n "12345678" | opensslbase64`
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#!/bin/sh
{
echo "HELO DD-WRT";
echo "AUTH LOGIN";
sleep 1;
echo "";
sleep 1;
echo "";
sleep 1;
echo "MAIL FROM:";
echo "RCPT TO:";
echo "DATA";
echo "From: [DD-WRT] ";
echo "To: ";
echo "Date: `date '+%a, %d %b %Y %H:%M:%S%z'`";
echo "Subject: [DD-WRT::Note] Router bootup";
echo "";
echo "The new WANIP is $(ip -4 addr showdev ppp0 | awk '/inet / {print $2}' | cut -d/ -f1).";
echo "";
echo ".";
echo "QUIT";
} | telnet smtp.email.com 25
last=$(nvram get wan_ipaddr)
curr=$(nvram get wan_ipaddr)
while sleep 300s
do
curr=$(nvramget wan_ipaddr)
if[ "A$curr" != "A$last" ]; then
{
echo "HELO DD-WRT";
echo "AUTH LOGIN";
sleep 1;
echo "";
sleep 1;
echo "";
sleep 1;
echo "MAIL FROM:";
echo "RCPT TO:";
echo "DATA";
echo "From: [DD-WRT] ";
echo "To: ";
echo "Date: `date '+%a, %d %b %Y %H:%M:%S%z'`";
echo "Subject: [DD-WRT::Note] Router bootup";
echo "";
echo "The new WANIP is $(ip -4 addr showdev ppp0 | awk '/inet / {print $2}' | cut -d/ -f1).";
echo "";
echo ".";
echo "QUIT";
} | telnet smtp.email.com 25
last=$curr
fi
done
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
以上脚本提交成功之后,清空文本框内容,输入以下内容,然后点击“保存为启动指令”
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
/tmp/custom.sh &
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
大功告成,路由器启动之后会发送一封邮件到你的邮箱,中间每隔300s检查一次WAANIP是否变动,如果变动,则发送一封邮件告知你新的WANIP。
上面这篇文章大致思路有了,但是在具体细节上我还是无法理解(因为本人非IT专业,只是在大学学过C语言,而且很烂,能看懂基本的语言已经是“难能可贵”了)。比如上面写道的先准备好邮箱账号和密码的BASE64码,前两行指令到底是干嘛的?我是一头雾水,后来经过几次三番的测试,查询相关资料,终于晓得了其实这个程序是让DD-WRT系统调用telnet,来利用SMTP协议方式来发送邮件,DD-WRT系统类似于LINUX系统,在WINDOWS系统下利用OUTLOOK发送邮件的方式很像,需要发件人邮箱账号和密码,当然也需要知道这封邮件是发往哪里也就是收件人邮箱账号。搞懂了这个概念,我又从网上找到了相关LINUX调用SMTP发送邮件的相关文章,比如这篇:
文章内如如下: 关于telnet发送smtp邮箱的尝试之前没有试过这种方式的邮件发送,今天正好碰到一些相关问题,所以研究了一下,遇到了很多问题,最终还是成功了。 完整过程如下,还是很有意思的。 下面的例子是用qq的smtp服务器。
telnet smtp.qq.com 25220 smtp.qq.com Esmtp QQ Mail Serverhelo sis250 smtp.qq.comauth login334 VXNlcm5hbWU6***
334 UGFzc3dvcmQ6***
235 Authentication successfulmail from: <350510376@qq.com>250 Okrcpt to: <350510376@qq.com>250 Okdata354 End data with <CR><LF>.<CR><LF>to: hellofrom: niansubject: this is a test telnet smtp mailhello,telnet .250 Ok: queued as
做一些说明,可能遇到的问题是 1、首先telnet命令不存在,自己去百度下安装即可,很简单。 2、在和服务器通讯时 helo sis,回车后可能会出现【502 Error:command not implemented】,可以重新输入helo sis,或者helo 其他内容都可以,这边只是打个招呼。 出现上面的错误,多试几次即可,可能是服务器状态比较忙。
3、auth login后需要输入你的qq邮箱的用户名和密码,而且要转换为BASE64编码,随便找个百度应用都有这个功能。如QQ 352000114 用户名对应MzUwNTEwMzc2, 此过程可能也要多做几次,鉴于服务器的状态。 4、输入用户名和密码后出现如下错误【发送邮件错误 454Authentication failed, please open smtp flag first!】, 这个是我纠结了好久的问题,解决方式如下: 在QQ邮箱的设置里面,找到账户-》POP3/IMAP/SMTP选择开启POP3/SMTP服务 5、to: hello “邮件收件人的名称
from: nian ”邮件来源名称
subject: this is a test telnet smtp mail “主旨
hello,telnet ”内容
6、最后输入点,回车即结束邮件的发送 7、退出连接,可使用命令 quit 其实,理解下来应该是通过telnet的方式登录DD-WRT路由系统,也就相当于登录到了一个LINUX系统,让它利用SMTP的方式发送邮件。大家也可以自己在WINDOWS系统下启用TELNET功能(如何启用请百度),然后开始-运行-CMD进入,开始尝试用SMTP的方式发送邮件。 在最开始的第一篇文章中的命令代码在有了第二篇的基础上,我理解了问题所在,其实要调用SMTP发邮件,也就要先登录发件的邮箱账号,理所当然的也就要密码了,但是该协议下是要用BASE64编码方式输入登录邮箱账号和密码的,想要获得自己的账号和密码的BASE64编码可以去百度然后有网上自动编码解码的。理解了这个问题,我尝试着在命令行中输入相关指令,可是依然无法接收到邮件,又结合第二篇文章和自己测试下来的telnet方式登录SMTP发送邮件的过程,发现其实在每次输入一个指令后,远程邮件系统其实是会反馈会一段代码的,也就是有一个等待的过程,我在原始指令代码中,又在每条命令后加入了一个“sleep 1;”也就是等待1秒的意思,然后测试下来可以发送邮件了,但是发送后却收不到想要获取的WAN口IP地址信息,真是奇怪了。接下来继续百度查找相关问题,如何让DD-WRT系统获取IP信息,最终找到了其实在源代码中就有这个指令:nvramget wan_ipaddr,第一篇文章中的他用到的获取IP地址代码$(ip -4 addr show dev ppp0 | awk '/inet / {print$2}' | cut -d/ -f1),貌似无法获取到,根据我的渣渣C语言功底,我想这段代码前面的$符号应该是取得后面这个函数具体数值的功能,因此,我将这段替换成了$(nvram get wan_ipaddr)也就是,现在这段代码:echo "The new WANIP is $(nvram getwan_ipaddr).";测试下来,哈哈,终于成功发送了我的WAN口IP地址信息到我的邮件中了! 基本解决问题了,接下来我又在源指令代码中做了一些改动,让系统每隔1分钟就检测一次WAN口IP地址信息: while sleep 60s do curr=$(nvram get wan_ipaddr) if [ "A$curr" !="A$last" ]; then 其实也就是把原代码中的sleep 300s改成了60s(如果觉得频率太高了可以自行修改适当的时间)而已,这段代码的意思也就是:每隔60s比对一下现在WAN口IP地址和最近一次WAN口IP地址,如果不相同的话,那么执行大括号里的一段代码发送最新的WAN口IP地址信息到邮件中了。(我不太会弄循环,不知道怎么设置代码让系统每隔1个小时就发送一次WAN口IP位置信息到邮件,不然就能定时发送最新的IP了,现在这样只能保证WAN口IP变更后才发送邮件)。 我的完整代码如下:
#!/bin/sh
{
sleep 1; #让程序等待1秒以响应远程邮件服务
echo "HELO DD-WRT"; #与远程邮件服务器打招呼
sleep 1; #让程序等待1秒以响应远程邮件服务
echo "AUTH LOGIN"; #启动SMTP邮件登录服务
sleep 1; #让程序等待1秒以响应远程邮件服务
echo "*****5MjBAMT***"; #这里填入你的发件邮箱账号的BASE64码
sleep 1; #让程序等待1秒以响应远程邮件服务
echo "**ODU3MzE***"; #这里填入你的发件邮箱密码的BASE64码
sleep 1; #让程序等待1秒以响应远程邮件服务
echo "MAIL FROM:<**** 31920@163.com>"; #这里填入你的发件邮箱账号
sleep 1; #让程序等待1秒以响应远程邮件服务
echo "RCPT TO:<*** 920@163.com>"; #这里填入你的收件账号
sleep 1; #让程序等待1秒以响应远程邮件服务
echo "DATA";
sleep 1; #让程序等待1秒以响应远程邮件服务
echo "From: [DD-WRT] ";
echo "To: ";
echo "Date: `date '+%a, %d %b %Y %H:%M:%S %z'`";
echo "Subject: [DD-WRT::Note] Router boot up";
echo "";
echo "The new WANIP is $(nvram get wan_ipaddr)."; #获取WAN口IP地址
echo "";
echo ".";
echo "QUIT";
} | telnet smtp.163.com 25 #填入你发件邮箱的SMTP服务地址qq邮箱就是smtp.qq.com 25
last=$(nvram get wan_ipaddr)
curr=$(nvram get wan_ipaddr)
while sleep 60s
do
curr=$(nvram get wan_ipaddr)
if [ "A$curr" != "A$last" ]; then
{
sleep 1;
echo "HELO DD-WRT";
sleep 1;
echo "AUTH LOGIN";
sleep 1;
echo "**E5MjBAMTYzL***"; #这里填入你的发件邮箱账号的BASE64码
sleep 1;
echo "***1ODU3Mz***"; #这里填入你的发件邮箱密码的BASE64码
sleep 1;
echo "MAIL FROM:<**** 920@163.com>";
sleep 1;
echo "RCPT TO:<**** 920@163.com>";
sleep 1;
echo "DATA";
sleep 1;
echo "From: [DD-WRT] ";
echo "To: ";
echo "Date: `date '+%a, %d %b %Y %H:%M:%S %z'`";
echo "Subject: [DD-WRT::Note] Router boot up";
echo "";
echo "The new WANIP is $(nvram get wan_ipaddr).";
echo "";
echo ".";
echo "QUIT";
} | telnet smtp.163.com 25
last=$curr
fi
done
在DD-WRT系统中的管理——命令中的空白文本框中输入上述命令,点击“保存为自定义指令”,这样这段指令就成为了DD-WRT系统命令中的自定义脚本命令了,其他程序就可以来调用执行,因此,需要一个开机就执行的命令,在空白文本框中继续输入如下代码: /tmp/custom.sh &点击“保存为启动命令” 然后可以试着点击“运行命令”,如果没问题的话,你的收件邮箱中应该收到了邮件信息了吧,新的WAN口IP信息已经被你获得了,接下来,看你自己的需要进行操作了。 完成后在DD-WRT系统中的命令截图: |