笑看尘世|利用阿里云API实现内网穿透,不用花钱再用花生壳花生棒了


前言:
自从家里有小孩后手机里的照片多的没地方放 , 又想实时能查看 , 家里人的手机都拍了宝宝照片视频 , 也没法相互查看 , 所以这个场景下不管是云备份 , qq空间都无法实现这个诉求 , 腾讯相册的小程序倒是好 , 但是貌似经常有bug , 再说数据放在家里是最安全的 。 前段时间看头条上面说花生壳的内网穿透 , 虽然没用过也不想花钱 , 就想能不能自己搞一个内网穿透 , 就想查查花生壳实现内网穿透的原理 , 百度了一批突然发现有个标题为“无需花生壳 , 阿里云解析实现内网穿透”的文章 , 好好拜读了一下 , 觉得自己应该也可以弄 , 因为我有一个阿里云的虚拟服务器正在使用 , 设置个二级域名就可以了 , 这里需要谢谢 “没文化的查哥”看了他的文章才知道该怎么做 , 他是用Python 实现的 , 而我了 又不会Python , 所以了不管怎么样先试试 。
这里了需要先说说实现内网穿透所需要的条件 , 如果阁下不具备就随便看看吧 。
1.你需要有个域名 , 如果没有也可以买一个 , 那种一般的域名一年也就十几块 , 几块的 , 买个十年也花不了多少钱 。

2.既然要做内网穿透 , 那你需要一个公网IP , 现在多数家里的网都是私网 , 需要去申请 , 我家里用的是电信的 , 我打了个客服10000号申请了一下 , 第三天就给我搞定了 , 联通移动的网络是否好申请 , 我不知道 , 听说不好申请 , 因为分给他们的地址少 。 这里什么是私网什么是公网呢?举个例子 你家里有台路由器, 家里的电脑电视手机获取到的ip就是路由器分配的ip地址是私网ip , 但是路由器拨号上网获得的ip地址是电信公司分配的 , 那么如果说路由器使用的ip地址是公网 。 同样道理好比说电信公司就有一台巨大路由器 , 然后家家户户用的路由器上获得的ip地址就是电信公司这个大路由器分配的 。 而电信公司的路由器就是使用公网IP , 我们的路由器上拨号获取的ip是私网 , 我们想要使用公网ip就得向人家申请 。 中国电信握有大量公网ip所以好申请一些 , 那么为什么不给家家分配公网IP呢?是因为用户太多了 公网IP不够用 , 再说公网ip比私网IP要好 要更快 。 扯远了... 。

3.不管你内网穿透要干啥 , 家里总是需要一台服务器 , 例如闲置多年的烂笔记本 , 扔了可惜 , 用又用不着的那种 , 最好功耗低一点的 , 不费电 。 我家里有两台旧笔记本(只能运行winxp系统的) , 一台windows平板 , 有一台是个华硕的上网本 , 功耗低 , 一台是上学时买的好像09年买的吧 。windows 平板是山寨的那种运行的windows 8 但是没有网线插口 , 做服务器功耗挺美 , 但是网络可能不行 , 就选择华硕上网本安装centOs
4.其他比如说家里没网没路由器 那那就...
说说实现原理
即使是公网ip它也是会改变的 , 不会一直不变 , 具体原因就不说了 , 因此我们需要利用阿里云的云解析API做一个动态改变解析值的这么一个组件 , 然后在服务器上设置定时执行这个组件 , 当发现公网ip变了以后立即把解析值给修改成最新的ip , 以保证域名解析始终指向你家里的服务器 。
一、实现步骤:
1.申请一个公网ip
2.阿里云域名(要备案 , 过程麻烦但是也是比较好备案的) , 把需要解析的域名解析值设置为这个公网ip

3.设置路由器 , 路由器的端口映射可以把网络上的请求指向你局域网的服务器 , 注意路由器要根据mac地址给服务器分配静态ip , 不能让服务器自动获取ip 当然 你也可以把你的服务器就放在猫旁边 , 直接连接猫获取ip , 就省去了端口映射 。
4.服务器,可以是linux 或者windos , 不管是要用web ftp server...
5.把开发好的组件放进服务器
以上步骤简单就这样 , 我们下面重点说这个组件开发 , 开发组件用的是Python, 搭建Python服务器的方法就不说了 , 我Python 也是小白 , 只花了两天看了看runoob的python3的教程 , 我主要是做php和前段的 , 下面代码写的不好的或者注释不正确的希望大牛不要笑话,指正一下 。
实现的思路都是来源于阿里云的API文档
二、实现原理:
先获取当前公网ip 然后获取阿里云域名列表 , 找出要修改的域名解析值 , 然后跟公网ip做对比 , 如果两个ip不一样说明公网ip变心了 就需要把解析值修改成新来的ip
现在开始直接贴代码:
#1 获取公网ip
import requests #异步请求库 安装方法终端运行: pip install requests
import re
def get_local_ip(self):
#通过向 网站发送get请求 , 会获取到当前局域网所在外网(公网)ip信息 , 返回的是一串字符串 , 注意使用异步请求需要requests库支持

text = requests.get("").text
#通过正在表达式解析出返回的ip地址
ip = re.findall(r'\d+.\d+.\d+.\d+',text)
return ip[0]
#2 获取域名列表及修改解析值
#阿里云云解析库 以下4个库安装方法
#pip install aliyun-python-sdk-core
#pip install aliyun-python-sdk-domain
#pip install aliyun-python-sdk-alidnsb
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest
import json #系统带有 如果没有请下载安装
''' AccessKeyId 阿里云后台获取
AccessKeySecret 阿里云后台获取
RegionId 一般默认为 zh-hangzhou
DomainName 要获取的域名 如 xxx.cn 、xxx.com
RrName 解析主记录 可以通过阿里云后台解析列表查看 , 例如 www.xxx.com 的 主记录为www home.xxx.com 主记录为 home
PageSize 获取解析列表每页显示的数量 , 默认20 最多200
'''
client = AcsClient(AccessKeyId, AccessKeySecret, RegionId)
request = DescribeDomainRecordsRequest()
request.set_accept_format('json') #返回的数据格式 为json

request.set_DomainName('你要解析的域名DomainName ') # 要获取的域名
request.set_PageSize('每页显示记录的数量值PageSize ') # 每页显示记录数量
response = client.do_action_with_exception(request)
dns_list = str(response, encoding='utf-8') #获取得到json字符
list_boj = json.loads(dns_list); #将json字符串转为python字典
record = list_boj['DomainRecords']['Record']; #获取dns列表中的需要修改的dns组 格式如{"RR": "xx","Line": "default","Status": "ENABLE","Locked": false,"Type": "A","DomainName": "xxx.cn","Value": "0.0.0.0","RecordId": "123456789...",...} ,{"":"",....}
#需要得到的参数
RecordId = ''
Type = ''
RR = ''
ThisIp = ''
#遍历record 得到RR:主记录 RecordId:记录id Type:记录类型 ThisIp:当前解析的值
for x in record:
rtop = x['RR']; #主记录 用于下面判断是不是与修改设置的RrName 一致 , 如果一致就把所需要的参数拿出来并跳出循环
if(rtop == RrName ):
RecordId = x['RecordId'];
Type = x['Type'];
RR = x['RR'];
ThisIp = x['Value'];
break;
if(‘公网ip’ != ThisIp):
requests = UpdateDomainRecordRequest()
requests.set_accept_format('json')
requests.set_RecordId(RecordId) #记录id
requests.set_RR(RR) #主记录
requests.set_Type(Type) #记录类型如 A

requests.set_Value('新的公网ip') #修改为当前公网IP
responses = client.do_action_with_exception(requests)
infJson = str(responses, encoding='utf-8')
infObj = json.loads(infJson); # 把返回值解析一下 , 如果成功返回则返回 此记录值的 RecordId
if(RecordId == infObj['RecordId']):
inf = 'IP修改成功!RecordId:'+infObj['RecordId']
else:
inf = 'IP修改失败'
else:
inf = 'ip相同不用修改!'
return inf;
以上代码为解决思路 , 使用此代码注意自己的使用逻辑 , 需要按照自己的逻辑修改一下 , 注意缩进问题 。
部分代码截图如下:
笑看尘世|利用阿里云API实现内网穿透,不用花钱再用花生壳花生棒了
本文插图

class
笑看尘世|利用阿里云API实现内网穿透,不用花钱再用花生壳花生棒了
本文插图

希望能帮助到有需求的人 。 不正确的请指正 。
后续做好了整个流程可以的话再分享
需要源码的可以私信哦
【笑看尘世|利用阿里云API实现内网穿透,不用花钱再用花生壳花生棒了】


    推荐阅读