700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 使用ORAY蒲公英异地组网实现树莓派异地SSH访问

使用ORAY蒲公英异地组网实现树莓派异地SSH访问

时间:2021-04-17 15:32:02

相关推荐

使用ORAY蒲公英异地组网实现树莓派异地SSH访问

使用ORAY蒲公英异地组网实现树莓派异地SSH访问

前情提要需求准备项(重要)正式开始第一步:创建启动蒲公英服务脚本第二步:创建网络检测脚本第三步:配置开机启动项第四步:自动将局域网IP地址发送至指定邮箱第五步:实现通过邮件向树莓派发送指令第六步:上电开机,等待蒲公英服务上线 注意事项

前情提要

上手了一块树莓派4B,希望能够在公司和家里都能调试开发;公司和家里没有公网IP(所以说还是电信大法好),没办法实现公网访问树莓派;虚拟机开发环境准备太麻烦,杀鸡用牛刀;不愿意每天带着板子来回跑。

需求

上电开机开机后检测是否联网(自动执行脚本);确认网络连接成功后登录蒲公英(自动执行脚本);联网后邮件发送局域网IP地址(自动执行python文件);通过蒲公英实现异地组网访问树莓派。

准备项(重要)

树莓派开启ssh;设置WiFi自动连接;安装蒲公英并设置好自动登录;智能插座。

正式开始

第一步:创建启动蒲公英服务脚本

在/home/pi/Desktop目录下创建启动蒲公英服务脚本pgyvpnservice.sh:

#!/bin/sh#/etc/init.d/pgyvpnservice.sh### BEGIN INIT INFO# Provides:testboot# Required-Start:$remote_fs $syslog# Required-Stop:$remote_fs $syslog# Default-Start:2 3 4 5# Default-Stop:0 1 6# Short-Description: testboot# Description: This service is used to start my applaction### END INIT INFOcase "$1" instart)echo "启动蒲公英异地组网"su root -c "pgyvpn"# 以root模式执行pgyvpn指令打开蒲公英;;stop)echo "执行完毕";;esac

第二步:创建网络检测脚本

在/etc/init.d目录下创建网络检测脚本network_test.sh:

#!/bin/bash#检测网络链接&&ftp上传数据declare -i n=0#创建变量n并声明为数值while [ $n -ne 1 ]#判断n是否不等于1doret_code=`curl -I -s --connect-timeout 5 -w %{http_code} | tail -n1`#网络值if [ "$ret_code" = "200" ]; thennohup /home/pi/Desktop/pgyvpnservice.sh &#网络连接成功后需要启动的程序脚本,即pgyvpnservice.shn=1;elsen=0; #失败等待fidone

第三步:配置开机启动项

实现开机检测网络连接,网络连接正常后运行蒲公英。

编辑rc.local文件:

sudo nano /etc/rc.local

在exit0前输入:

nohup /etc/init.d/network_test.sh &#后台启动网络检测脚本

第四步:自动将局域网IP地址发送至指定邮箱

目的

当无法登录路由器查看分配的IP地址时,了解树莓派所在位置。收到邮件即可确认树莓派已联网并顺利开启蒲公英,可以实现公网访问(这一步通过蒲公英控制台或客户端也可以实现,但通过邮件可以有效避免缓存等问题带来的困扰)。 编写ip_address.py,用于获取树莓派地址并发送邮件:

# -*- coding: utf-8 -*-from multiprocessing import connectionimport socketimport smtplibimport timeimport socket# 分割线内部分为网络检测,如在树莓派设置网络检测脚本,本部分可省略# ------------------------------------------------------------------# 测试网络连接情况def isNetOK(testserver):s=socket.socket()s.settimeout(3)try:status = s.connect_ex(testserver)if status == 0:s.close()return Trueelse:return Falseexcept Exception as e:return False# 测试百度是否可以访问def isNetChainOK(testserver=('',443)):isOK = isNetOK(testserver)return isOKif __name__ == '__main__':connection_attempt=Truewhile connection_attempt:chinanet = isNetChainOK()if chinanet==True:break# ------------------------------------------------------------------# 邮件发送方邮箱地址MAIL_USER = ''# MAIL_PASS要使用授权码而非密码MAIL_PASS = ''# 邮箱stmp服务器地址SMTP_SERVER = ''SMTP_PORT = 25# 邮件接收方邮箱地址recipient1=''# 邮件主题subject1 = 'ip_address'#获取IP地址def get_host_ip():try:s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)s.connect(('8.8.8.8',80))ip = s.getsockname()[0]finally:s.close()return ipdef send_mail(input_text):text = input_textsmtpserver = smtplib.SMTP(SMTP_SERVER,SMTP_PORT)smtpserver.ehlo()smtpserver.starttls()smtpserver.ehlosmtpserver.login(MAIL_USER,MAIL_PASS)header = 'To:'+recipient1+'\n'+'From:'+MAIL_USERheader = header + '\n' +'Subject:' + subject1 +'\n'timeStr = time.strftime(' %Y_%m_%d %H:%M:%S',time.localtime(time.time()))msg = header +'\n'+text+'\n'+timeStr+'\n\n'smtpserver.sendmail(MAIL_USER,recipient1,msg)smtpserver.close()time.sleep(10)send_mail(get_host_ip())

将ip_address.py复制到/home/pi/Desktop。将ip_address.py设置为开机启动:

# 编辑rc.local文件sudo nano /etc/rc.local# 在exit0前、nohup /etc/init.d/network_test.sh &后输入:sudo python /home/pi/Desktop/ip_address.py

第五步:实现通过邮件向树莓派发送指令

command_trans.py可通过邮件方式与树莓派终端进行有限的临时通讯,以备不时之需:

import osimport datetimefrom calendar import TextCalendarfrom cgitb import textfrom operator import truedivimport poplibimport base64from email.parser import Parserfrom email.header import decode_headerfrom email.utils import parseaddrfrom time import sleepimport smtplibfrom email import encodersfrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom unittest import resultdef get_email_content():useraccount = ''password = ''# 邮件服务器地址,以下为网易邮箱pop3_server = ''# 开始连接到服务器server = poplib.POP3(pop3_server)# 打开或者关闭调试信息,为打开,会在控制台打印客户端与服务器的交互信息server.set_debuglevel(0)# 打印POP3服务器的欢迎文字,验证是否正确连接到了邮件服务器# print(server.getwelcome().decode('utf8'))# 开始进行身份验证server.user(useraccount)server.pass_(password)# 返回邮件总数目和占用服务器的空间大小(字节数), 通过stat()方法即可email_num, email_size = server.stat()# print("消息的数量:{0}, 消息的总大小:{1}".format(email_num, email_size))# 使用list()返回所有邮件的编号,默认为字节类型的串rsp, msg_list, rsp_siz = server.list()# print("服务器的响应: {0},\n消息列表: {1},\n返回消息的大小: {2}".format(rsp, msg_list, rsp_siz))# print('邮件总数:{}'.format(len(msg_list)))# 获取最新的一封邮件total_mail_numbers = len(msg_list)rsp, msglines, msgsiz = server.retr(total_mail_numbers)# print("服务器的响应: {0},\n原始邮件内容: {1},\n该封邮件所占字节大小: {2}".format(rsp, msglines, msgsiz))msg_content = b'\r\n'.join(msglines).decode('gbk')# 邮件信息(未解码)msg = Parser().parsestr(text=msg_content)# print('解码后的邮件信息:\n{}'.format(msg))# 关闭与服务器的连接,释放资源server.close()return msg# 用来解析邮件主题 def parser_subject(msg):subject = msg['Subject']value, charset = decode_header(subject)[0]if charset:value = value.decode(charset)# print('邮件主题:{0}'.format(value))return value# 用来解析邮件来源 def parser_address(msg):hdr, addr = parseaddr(msg['From'])# name 发送人邮箱名称, addr 发送人邮箱地址name, charset = decode_header(hdr)[0]if charset:name = name.decode(charset)# print('发送人邮箱地址: {0}'.format(addr))return addrdef parser_content(msg):content = msg.get_payload()# 文本信息content_charset = content[0].get_content_charset() # 获取编码格式text = content[0].as_string().split('base64')[-1]text_content = base64.b64decode(text).decode(content_charset) # base64解码# 添加了HTML代码的信息# content_charset = content[1].get_content_charset()# text = content[1].as_string().split('base64')[-1]# html_content = base64.b64decode(text).decode(content_charset)# print('文本信息: {0}'.format(text_content))return text_contentdef send_email(command, execution_feedback):# sender是邮件发送人邮箱,pw是服务器授权码,mail_host是服务器地址sender = ''pw = ''mail_host = ''# receivers是邮件接收人,用列表保存,可以添加多个receivers = ['']# 设置email信息msg = MIMEMultipart()time_stamp = '{0:%Y-%m-%d-%H-%M}'.format(datetime.datetime.now())# 邮件主题msg['Subject'] = command + ' -- Execution result -- '+time_stamp# 发送方信息msg['From'] = sender# 邮件正文是MIMEText:msg_content = execution_feedbackmsg.attach(MIMEText(msg_content, 'plain', 'utf-8'))# 登录并发送邮件try:#QQsmtp服务器的端口号为465或994s = smtplib.SMTP_SSL(mail_host, 465)s.set_debuglevel(1)s.login(sender,pw)#给receivers列表中的联系人逐个发送邮件for item in receivers:msg['To'] = to = items.sendmail(sender,to,msg.as_string())print('Success!')s.quit()# print ("All emails have been sent over!")except smtplib.SMTPException as e:print ("Falied,%s",e)if __name__ == '__main__':# 返回解码的邮件详情msg = get_email_content()# 解析邮件主题value=parser_subject(msg)# 解析发件人详情addr=parser_address(msg)# 解析内容text_content=parser_content(msg)# 保证每次开机读取邮件时不会被已有邮件干扰command_line=text_contentsend_email('设备已开机,网络连接正常,已准备好通过邮件接收指令。', '最新一封邮件内容:'+text_content)while True:# 返回解码的邮件详情msg = get_email_content()# 解析邮件主题value=parser_subject(msg)# 解析发件人详情addr=parser_address(msg)# 解析内容text_content=parser_content(msg)if text_content!=command_line:command_line=text_contentstatement_execution = os.popen(command_line.replace('\n', '').replace('\r', ''))feedback_line = statement_execution.read()send_email(command_line,feedback_line)else:pass# 每间隔5分钟进行一次邮件收发sleep(300)

将command_trans.py复制到/home/pi/Desktop。将command_trans.py设置为开机启动:

# 编辑rc.local文件sudo nano /etc/rc.local# 在exit0前、sudo python /home/pi/Desktop/ip_address.py &后输入:sudo python /home/pi/Desktop/command_trans.py

第六步:上电开机,等待蒲公英服务上线

使用智能插座远程控制上电,上电后视网络情况等待一段时间,收到局域网IP地址邮件(推荐)或在蒲公英控制台/客户端上看到树莓派端已登录并能够ping通,即可通过蒲公英分配的IP地址进行公网访问。

注意事项

提前完成准备项内各项工作,蒲公英要保证自动登录能够执行,否则脚本无法开启该服务。务必关注rc.local文件中启动项顺序,顺序错误可能导致后面启动项无法正常启动。待补充。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。