背景

  在之前一篇文章中介绍了利用路由器的端口映射功能实现内网穿透的方法。

  ubuntu SSH内网穿透 + Vscode远程访问

  在实际的使用过程中,发现这一实现途径存在一些不足之处,即当路由器的公网ip地址改变之后,需要重新在ubuntu主机或者路由器上查看其公网ip地址,然后再在windows上修改ip地址。在远程访问的情况下,实际操作ubuntu主机或者路由器往往比较费时费力,因此本文描述了一种能够自动获取公网ip地址,当发现公网ip地址变化的时候,自动发送邮件至指定邮箱通知管理员,而不需要管理员再实际操作物理ubuntu主机的实现方案。

实现方法简介

  本文主要利用python语言构建一个在ubuntu主机上运行的程序,其能够利用访问获取外网ip地址的网页方式自动获取外网ip地址,并保存在ubuntu主机上,当发现公网ip地址发生变化的时候,利用SMTP协议发送邮件,当公网ip没有发生变化的时候,不发送邮件。

具体实现介绍

启动SMTP服务

  这里利用邮箱的SMTP功能实现邮件的发送,以163邮箱为例,在网页版邮箱设置页面启用SMTP,会生成一个授权密码,该授权码只显示一次,需复制到之后的python程序之中。

python程序代码

import json
from urllib.request import urlopenimport os
import timeimport smtplib
from email.header import Header
from email.mime.text import MIMEText# 两个获取ip地址的网站
ip_url_1 = 'https://api.ipify.org/?format=json'
ip_url_2 = 'http://jsonip.com'# 配置文件名
config_file_name = '.global_ip.json'# 第三方 SMTP 服务
mail_host = "smtp.163.com"      # SMTP服务器
mail_user = "xxx@mail.com"      # 用户名
mail_pass = "xxx"               # 授权密码,非登录密码sender = 'xxx@163.com'            # 发件人邮箱(最好写全, 不然会失败)
receivers = ['xxx@mail.com']    # 接收邮件,可设置为你的QQ邮箱或者其他邮箱title = 'update_addr'              # 邮件主题
content = ''                 # 邮件内容# 检查配置文件及其权限
def check_configfile_exist():file_exist = os.access(config_file_name, os.F_OK)file_read  = os.access(config_file_name, os.R_OK)file_write = os.access(config_file_name, os.W_OK)return{'file_exist':file_exist,'file_read':file_read,'file_write':file_write}def generate_configfile(ip_addr):config_construct = {"ip_addr": ip_addr}with open(config_file_name, "w", encoding='utf8') as fp:fp.write(json.dumps(config_construct,indent=4, ensure_ascii=False))fp.close()def sendEmail():message = MIMEText(content, 'plain', 'utf-8')  # 内容, 格式, 编码message['From'] = "{}".format(sender)message['To'] = ",".join(receivers)message['Subject'] = titletry:smtpObj = smtplib.SMTP_SSL(mail_host, 465)  # 启用SSL发信, 端口一般是465smtpObj.login(mail_user, mail_pass)  # 登录验证smtpObj.sendmail(sender, receivers, message.as_string())  # 发送print("mail has been send successfully.")except smtplib.SMTPException as e:print(e)def send_email2(SMTP_host, from_account, from_passwd, to_account, subject, content):email_client = smtplib.SMTP(SMTP_host)email_client.login(from_account, from_passwd)# create msgmsg = MIMEText(content, 'plain', 'utf-8')msg['Subject'] = Header(subject, 'utf-8')  # subjectmsg['From'] = from_accountmsg['To'] = to_accountemail_client.sendmail(from_account, to_account, msg.as_string())email_client.quit()localtime = time.localtime(time.time()) # 打印本地时间
print("\n" + time.asctime(localtime))# 通过两个网站获取ip地址
my_ip_1 = str(json.load(urlopen(ip_url_1))['ip'])
my_ip_2 = str(json.load(urlopen(ip_url_2))['ip'])if (my_ip_1 == my_ip_2):ip_addr = my_ip_1
else:ip_addr = "ip_1 :" + my_ip_1 + "\n" + "ip_2 :" + my_ip_2if(check_configfile_exist()['file_exist'] & check_configfile_exist()['file_write']):config_file = open(config_file_name,'r')read_context = json.load(config_file)old_ip = read_context['ip_addr']config_file.close()if (old_ip == ip_addr):print("ip address is up-to-date")else:content = "old ip address is : " + old_ip + '\n' + "new ip address is : " + ip_addrsendEmail()generate_configfile(ip_addr)
else:generate_configfile(ip_addr)content = "new ip address is : " + ip_addrsendEmail()

   这里的程序都是一些细节的实现,需要注意的是该程序提供了两个发送邮件的函数,其区别在于是否使用SSL发信,在163邮箱的设置页有说明,即上图的底部说明全部支持SSL连接,因此此处使用支持SSL的发信函数。

定时启动python程序

  以上的程序实现了获取公网ip地址并发送邮件的功能,但是还缺少一步,就是让其在ubuntu主机上周期性的运行,例如每隔15分钟运行一次,检查一次ip地址,因此下一步,将利用crontab来实现这一功能。
  Linux crontab是用来定期执行程序的命令。
  利用crontab -e 即可进入编辑执行命令。

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

  以上是其说明文字,从中可以看到命令的格式说明,m h dom mon dow command这几个缩写是以下英文的缩写:
  minute, hour, day of month, month, day of week, command
  利用这些信息即可编写定时启动python程序的代码,这里我设置的是每隔15分钟进行一次执行,即:

0,15,30,45 * * * *
/path/to/python3.x
/path/to/python/file/get_ip_and_mail.py >>
/path/to/log/file/check_and_email_ip.log

  这里需要注意的是python的路径,python文件的路径以及log文件的保存路径,当然这里可以不输出log文件,保存log文件只是为了后续方便调试程序,运行出错时方便寻找问题。另一方面该命令的执行目录是在$HOME变量所在的目录,倘若需要修改执行目录,可以修改$HOME变量,或者修改命令为cd /path/to/target; command,转到目标路径下再执行命令。
  配置好后重启一下crontab服务。

service cron restart

  当第一次运行的时候程序会自动生成配置文件并发送邮件至指定邮箱,如下图:

  当ip地址发生变化时,会收到如下的邮件信息:

  综上完成了该方法的介绍。

一种获取公网ip地址并发送邮件至指定邮箱的实现方法相关推荐

  1. SRT编码器传输获取公网IP地址3种解决方案

    SRT是时下最热门的互联网传输协议,具备低延时.稳定可靠传输的优势特性,可广泛应用于远程制作.远程监看.异地互动等需要互联网远程传输场景. SRT 是点对点传输协议,由于需要穿透互联网,所以至少需要有 ...

  2. java 获取ip地址 公网,java获取公网ip地址操作

    获取公网ip地址操作 import javax.servlet.http.HttpServletRequest; /** * * 获取公网ip地址操作 * @ClassNmae:NewClass * ...

  3. Android获取公网IP地址

    Android想要获取公网IP地址,连接wifi的情况下在应用层开发的角度使用系统的API是做不到的,只能直接或间接利用第三方的接口服务: 1.公共接口: 搜狐: http://pv.sohu.com ...

  4. 你会在终端下快速获取公网 IP 地址吗,学会这些技巧后你就游刃有余了!

    在排除网络问题,建立新连接或配置防火墙时,了解设备的 IP 地址很重要. IP 地址可以分为两类,公用和私有(专用).公用 IP 是唯一的 IP 地址,可以从 Internet 访问.专用 IP 地址 ...

  5. linux系统wget、curl终端命令行获取公网ip地址及其他网络信息

    前言 在linux开发环境中查看当前公网ip地址或者某个端口是否通,对于新手来说是个比较麻烦的事情,下面我这里介绍一下如何在终端查询当前公网ip以及其他网络信息. 安装wget.curl工具 wget ...

  6. 湖南地区电信如何获取公网IP地址

    1.打电信电话.要求公网IP地址. 软磨硬泡10分钟后...答应.如果客服说不会,继续打. 2.成功后将光猫改为桥接模式 一般情况下,现在的光猫的超级密码都不是之前的网上的了,其实只需要访问一下地址就 ...

  7. android获取公网ip地址,获取公网ip

    /** * 获取公网ip * @return */ public String getNetIp() { String ip = ""; InputStream inStream ...

  8. 关于Java获取公网IP地址

    首先写这个只是做个笔记,下次直接需要使用,真是不想吐槽有些文章标题党,搜的就是如何查看公网IP 外网IP ,你们标题挂着也是获取公网IP. 外网IP ,写的是获取本地的IP ,好像有大病. 做这个是因 ...

  9. 利用python实时获取公网IP地址

    使用本地运行python任务+OneDrive同步的方式,替代DDNS获取公网地址 # /* # * @Author: qyn987707.qianyunan # * @Date: 2021-11-0 ...

最新文章

  1. 回顾2018——区块链行业十大关键词
  2. mysql监听地址的设定 —— 解决外部网址无法连接mysql的办法服务器
  3. uniapp H5页面使用uni.request时,出现跨域问题
  4. PAT甲级 -- 1103 Integer Factorization (30 分)
  5. FreeCAD v0.19源码编译与VS2017+Qt5环境搭建
  6. 在React中处理事件
  7. 全球首发!计算机视觉Polygon Mesh Processing读书笔记6——微分几何中的Metric Properties
  8. k8s的应用打包工具Helm
  9. Hadoop阅读笔记(一)——强大的MapReduce
  10. struts的action访问servlet的IOC方式与非IOC方式
  11. 直接播放H264视频流的方法或工具
  12. cmd指令-快捷查看电脑ip地址
  13. 华为usg6000配置手册_三国志11手机版,问题解决手册 1.4.4版本
  14. 小程序倒计时显示晃动问题
  15. onvif 添加H265开发流程
  16. python魔方方法
  17. 百度统计的JS脚本原理分析 2013年文章转载
  18. pytho中的json序列化与反序列化操作
  19. 五子棋游戏程序记录和复盘功能设置
  20. Mock 的使用方法

热门文章

  1. win10鼠标不受控制乱动_win10 控制面板在哪里?
  2. ARFoundation之路-人脸检测增强之二
  3. 【Kubernetes】k8s的安全管理详细说明【k8s框架说明、token验证和kubeconfig验证详细说明】
  4. java get方法_java get方法
  5. get_price函数定义python_python get()函数
  6. Julia发布全功能调试器:4大新功能问世
  7. 8080 端口被占用的解决方法 netstat -ano;taskkill (命令行)
  8. 怎样在网上赚钱啊,小编告诉你6种赚钱方式!
  9. vue01-前端知识体系(狂神)
  10. 《Python数据分析基础教程:NumPy学习指南(第2版)》笔记5:第三章 常用函数1——文件读写、算术平均值、最大值最小值、极值