前一段时间路由器刷的老毛子固件“穿透服务”中定时更新阿里DDNS失败了,用了很久第一次遇到。所以需要做个备用的措施用来实时获取公网ip信息
1、基于python实现
- #!/usr/bin/python
- # -*- coding: UTF-8 -*-
- import os
- import re
- import random
- import requests
- import logging
- import smtplib
- from email.mime.text import MIMEText
- from email.header import Header
- from string import Template
- from email.utils import parseaddr, formataddr
- # 输出日志格式
- logging.basicConfig(format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',
- level=logging.INFO,
- filename='sendWANIP.log',
- filemode='a')
-
-
- def _format_addr(s):
- """
- 美化邮箱地址,用于可显示发/收件人
- :param s: 邮件地址
- :return: 美化后的地址
- """
- addr = parseaddr(s)
- return formataddr(addr)
-
- def get_current_ip():
- """
- 获取当前公网ip地址
- :return: 公网ip地址
- """
- ip_reg = re.compile("((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}")
- # 可根据需求增删获取ip网址
- api_tuple = (
- "http://txt.go.sohu.com/ip/soip",
- "https://ident.me/",
- "https://ifconfig.me/ip",
- "https://icanhazip.com/",
- "https://checkip.amazonaws.com/",
- "http://members.3322.org/dyndns/getip"
- )
- url = api_tuple[random.randrange(len(api_tuple))]
- # print(url)
- r = requests.get(url)
- ip = re.findall(r'\d+.\d+.\d+.\d+', r.text)
- # ip[0]
- if re.match(ip_reg,ip[0]):
- logging.info("从{}获取地址成功!ip={}".format(url,ip))
- return ip[0]
- else:
- logging.error("从{}获取地址失败!".format(url))
- exit(-1)
-
- def record_ip(params):
- """
- 将最新的ip记录在文件中
- :param params: 包含ip的参数
- """
- filename="./lastwanip"
- last_wan_ip=""
- if os.path.exists(filename):
- f=open(filename,'r');
- last_wan_ip=f.readline()
- f.close()
- logging.info("从文件中读到ip地址为:{}".format(last_wan_ip))
- if last_wan_ip!= params['current_ip']:
- f = open(filename, 'w');
- f.write(params['current_ip'])
- f.close()
- else:
- logging.info("ip地址已经是最新的,无需更新")
- exit(0)
- def send_mail(params):
- """
- 给指定用户发送邮件
- :param params: 发送邮件信息
- :return: 0: 发送成功,>0 发送失败
- """
- # 第三方 SMTP 服务
- mail_host = "smtp.163.com" # 设置服务器
- mail_user = "xxxx" # 用户名
- mail_pass = "xxxxxxxx" # 口令,即授权码不是账户密码
- receivers = sender = 'xxxx@163.com'
- # 邮件内容支持html格式,仿照的腾讯云模板
- mail_text="""
-
-
-
-
-
IP地址 -
-
-
-
-
-
-
-
-
-
- style="word-break: break-all;box-sizing:border-box;text-align:center;min-width:320px; max-width:660px; border:1px solid #f6f6f6; background-color:#f7f8fa; margin:auto; padding:20px 0 30px; font-family:'helvetica neue',PingFangSC-Light,arial,'hiragino sans gb','microsoft yahei ui','microsoft yahei',simsun,sans-serif">
-
-
-
-
-
-
-
-
-
-
- """
- mail = MIMEText(Template(mail_text).substitute(params), 'html', 'utf-8')
- # 显示发件人
- mail['From'] = _format_addr(sender)
- mail['To'] = _format_addr(receivers)
- # 设置邮件主题
- subject = '[DynamicIP-Notice] {}'.format(params['current_ip'])
- mail['Subject'] = Header(subject, 'utf-8')
-
- try:
- smtpObj = smtplib.SMTP()
- smtpObj.connect(mail_host, 25) # 25 为 SMTP 端口号
- smtpObj.login(mail_user, mail_pass)
- smtpObj.sendmail(sender, receivers, mail.as_string())
- logging.info("邮件发送成功,最新ip为{}".format(params['current_ip']))
- return 0
- except smtplib.SMTPException as ex:
- logging.error("邮件发送失败{},".format(ex))
- return 1
-
- if __name__=='__main__':
- device = os.environ['COMPUTERNAME']
- params = {"current_ip": get_current_ip(), "device": device}
- record_ip(params)
- send_mail(params)
2、创建bat文件启动脚本
"D:\Program Files\Python310\python.exe" D:\Code\Code\sendWANIP\sendWANIP.py
3、Windows任务计划
添加windows任务计划,每隔10分钟执行bat文件获取公网ip
注意:

4、shell脚本
路由器上跑的shell脚本,百度得来的出处忘记了,有需要的可以参考
- #!/bin/bash
-
- #SMTP配置 #(例子)
- #SMTP服务器#smtpserver=smtp.126.com
- #邮箱账号#fromaddress=xxxxxx@126.com
- #邮箱密码fromaddresspwd=xxxxxxxxxxxxx
- #收件人信息#toaddress=xxxxxx@qq.com 英文逗号分隔
-
-
-
- #SMTP配置
- smtpserver=smtp.163.com
- fromaddress=xxxx@163.com
- fromaddresspwd=xxxxxxxxxxxxx
- toaddress=xxxxx@163.com
-
-
-
- #文件路径,最新ip写入lastwanip.txt
- iptxt="/etc/storage/lastwanip.txt"
- #文件路径,邮件正文,写入mail文件
- mailtxtpath="/etc/storage/mail.txt"
-
-
-
-
- #获取WANIP接口
- newwanip=`wget http://members.3322.org/dyndns/getip -q -O -`
-
-
-
-
- #如接口获取不到ip,本次取消发送
- echo $newwanip
-
- if [ x"$newwanip" = "x" ]; then
- newwanip=`wget https://ifconfig.me/ip -q -O -`
- echo $newwanip
- if [ x"$newwanip" = "x" ]; then
- exit
- fi
- fi
-
- if [ -f $iptxt ]; then
- oldwanip=`cat $iptxt`
- else
- oldwanip="0.0.0.0"
- fi
-
-
-
-
-
- #对比上次IP,如相同则不发邮件,否则发送
- echo $oldwanip
-
- if [ "$newwanip" = "$oldwanip" ]; then
- exit
- fi
- if [ -f $mailtxtpath ]; then
- rm -f $mailtxtpath
- fi
-
-
-
-
-
- #配置邮件标题,修改“wanip”和在${newwanip} 后面加参数
- #不能修改代码格式,行与行之间必须空格!
- cat <<EOF >>$mailtxtpath
- Subject: WANIP:[ ${newwanip} ]
-
- 路由器型号 = RedMi AC2100
-
- IP= ${newwanip}
-
- ok
-
- To: $toaddress
- From: $fromaddress
- EOF
-
-
-
-
-
- #调用系统邮件服务
- sendmail -f $fromaddress -t $toaddress -S $smtpserver -au$fromaddress -ap$fromaddresspwd < $mailtxtpath
-
-
-
-
- #缓存最新ip地址,写入/etc/storage/lastwanip.txt"
- echo $newwanip > $iptxt
-
-
-
-
- #打印系统日志,调用logger接口
- logger 发现WANIP变化,外网IP= $newwanip
- logger ($fromaddress)已邮件通知($toaddress)