樹莓派 + DDNS 綁定域名實現外網訪問


來自 yoyolife 的投稿。

目前的資料收集情況來說,只有中國電信可以開通外網IP。另外,不能使用80端口。如果你要80就不用往下看了。

我的開通過程是。微信找到中國電信公眾號,找到客服,和他說你要開通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代碼

先安裝

1
2
pip3 install aliyunsdkcore
pip3 install aliyun-python-sdk-alidns
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# 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 文件

在同級目錄輸入

1
2
touch ip
touch RecordId

然后運行

1
python3 ddns.py

就會每10秒刷新一次ip 有改變就會去修改ddns

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

也可以放到 /etc/rc.local啟動運行

也可以放到后台進程

1
nuhup python3 ddns.py &

守護這東西我就不詳細說了。

這樣你就有了 全速的網絡,你可以做 NAS 或網盤 或什么你喜歡。

來自 yoyolife 的投稿,出處:http://www.yoyolife.fun:9000/blog/post/5e0d9acd9b86720030000154

出處:https://shumeipai.nxez.com/2020/01/10/raspberry-pi-ddns-for-external-network-access.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM