使用树莓派和路由器DMZ穿透外网并使用DDNS绑定域名
2020-01-02 08:37:57    915    0    0
jeiry

前提条件,你是中国电信光纤用户。如果不是就不用往下看了。你不能使用80端口。如果你要80就不用往下看了。

 

前段时间用frp ngrok做穿透,发现都受线上服务器的带宽限制。你家用100m光纤,但是服务器只有1m的话,那么你的上传只有 150k左右。这尼玛的怎么玩。所以,你要买100m的服务器,一年下来10来20万,又或者你用流量计费,一G几毛钱。但对于我这样一个有追求的人来说,花钱是没必要的。

 

目前的资料收集情况来说,只要中国电信可以开通外网IP。

我的开通过程是。微信找到 中国电信公众号,找到客服,和他说你要开通IP回退(公网IP),他问你必须的验证资料后,然后等那个半天。电信小哥会到你的社区里面,把你的网口从一个盒子换到另外一个盒子,然后他会打电话给你。你重启一下。进入路由,看到的外网的ip,和你去baidu 打 ip 看到的ip是一样的了。如果不这么做,你得到的只是一个大局域网的ip。外面是不能访问的。

 

当你有了外网ip。然后你就要开始设置你的光猫和路由器。我用的是TPLink路由,你们用啥基本上是大同小异。

我们要做的事情是,关闭光猫的自动拨号功能,用路由器来拨号。现在默认光猫出厂,就能自己上网,因为光猫会自动帮你拨号了。我们要换成自己的路由器拨号,并开启DMZ公开你的树莓派到网外。

 

进入192.168.0.1 进入超级管理员 

username="telecomadmin"
web_passwd="nE7jA%5m"

然后到 -- 网络 -- 宽带设置 把你拨号模式改成Bridge模式VLAN ID 设为41 如图

然后进入你的路由器192.168.1.1 进入WAN设置,使用PPPoE拨号

 

这个时候,你的IP和你外网的IP是一样了。

然后进去DMZ主机

把树莓派内网地址写上去。

这个时候,你用你的外网IP 就能进入ssh

 

重点来了。现在你要设置DDNS让你的域名当IP改变时可以自己绑定新的IP

 

登陆阿里云后

进入 https://ram.console.aliyun.com/users RAM访问控制

新建立用户给权限

把这4个权限选上。然后开始跑我下面的python代码

先安装 

pip3 install aliyunsdkcore

pip3 install aliyun-python-sdk-alidns

 

# coding: utf-8
from aliyunsdkcore.client import AcsClient
from aliyunsdkalidns.request.v20150109.DescribeSubDomainRecordsRequest import DescribeSubDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest
from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest

import time
import json
import urllib.request

##这里要换成自己的哟
client = AcsClient('AccessKey ID', 'Access Key', 'cn-hangzhou')

def get_internet_ip():
    with urllib.request.urlopen('http://www.3322.org/dyndns/getip') as response:
        html = response.read()
        ip = str(html, encoding='utf-8').replace("\n", "")
    return ip




def Describe_SubDomain_Records(client,record_type,subdomain):
    request = DescribeSubDomainRecordsRequest()
    request.set_accept_format('json')

    request.set_Type(record_type)
    request.set_SubDomain(subdomain)

    response = client.do_action_with_exception(request)
    response = str(response, encoding='utf-8')
    relsult = json.loads(response)
    return relsult


def add_record(client,priority,ttl,record_type,value,rr,domainname):
    request = AddDomainRecordRequest()
    request.set_accept_format('json')

    request.set_Priority(priority)
    request.set_TTL(ttl)
    request.set_Value(value)
    request.set_Type(record_type)
    request.set_RR(rr)
    request.set_DomainName(domainname)

    response = client.do_action_with_exception(request)
    response = str(response, encoding='utf-8')
    relsult = json.loads(response)
    return relsult


def update_record(client,priority,ttl,record_type,value,rr,record_id):
    request = UpdateDomainRecordRequest()
    request.set_accept_format('json')

    request.set_Priority(priority)
    request.set_TTL(ttl)
    request.set_Value(value)
    request.set_Type(record_type)
    request.set_RR(rr)
    request.set_RecordId(record_id)

    response = client.do_action_with_exception(request)
    response = str(response, encoding='utf-8')
    return response


def wirte_to_file(path,ip):
    f = open(path, 'w')  # 若是'wb'就表示写二进制文件
    f.write(ip)
    f.close()


def domains(domain):
    try:
        des_relsult = Describe_SubDomain_Records(client, "A", domain['full'])
        # 判断子域名解析记录查询结果,TotalCount为0表示不存在这个子域名的解析记录,需要新增一个
        if des_relsult["TotalCount"] == 0:
            add_relsult = add_record(client, "5", "600", "A", ip, domain['left'], domain['right'])
            record_id = add_relsult["RecordId"]
            print("域名解析新增成功!")
        # 判断子域名解析记录查询结果,TotalCount为1表示存在这个子域名的解析记录,需要更新解析记录,更新记录需要用到RecordId,这个在查询函数中有返回des_relsult["DomainRecords"]["Record"][0]["RecordId"]
        elif des_relsult["TotalCount"] == 1:
            record_id = des_relsult["DomainRecords"]["Record"][0]["RecordId"]
            update_record(client, "5", "600", "A", ip, domain['left'], record_id)
            print("域名解析更新成功!")
        else:
            record_id = 0
        path = './RecordId'
        wirte_to_file(path, record_id)
    except Exception as e:
        print(e)
while True:
    ip = get_internet_ip()
    with open("./ip", 'r') as f:
        old_ip = f.read()

    if ip == old_ip:
        print("noupdate" + "\nnew_ip:" + ip + "\nold_ip:" + old_ip)
    else:
        wirte_to_file("./ip", ip)

##多个域名
        domains({'full':"*.tunnel.xxx.fun",'left':"*.tunnel","right":"xxx.fun"})
        domains({'full':"tunnel.xxx.fun",'left':"tunnel","right":"xxx.fun"})
        domains({'full':"*.frp.xxx.fun",'left':"*.frp","right":"xxx.fun"})


    time.sleep(10)

保存为 ddns.py 文件

在同级目录输入

touch ip

touch RecordId

 

然后

python3 ddns.py

 

就会每10秒刷新一次ip 有改变就会去修改ddns

 

然后你可以把py放到supervisor里面守护

也可以放到 /etc/rc.local启动运行

也可以放到后台进程

nuhup python3 ddns.py &

守护这东西我就不详细说了。


这样你就有了 全速的网络,你可以做 NAS 或网盘 或什么你喜欢。

 

最后预祝大家新年快乐

RecordId

Pre: 用树莓派来实现钉钉打卡

Next: raspberry pi 4 安装 Firefox, Virtualdisplay, Selenium 做爬虫

915
Table of content