需求
自己有一個樹莓派,在家可以拿到公網(wǎng)IPv6地址丹禀。
但I(xiàn)Pv6地址經(jīng)常變化粤铭,所以需要將IPv6地址映射到域名上吴侦。這樣后面配置各種服務(wù)會方便很多屋休。
參考內(nèi)容:
[1] 知乎專欄, "基于 Cloudflare DNS API 部署 IPv6 DDNS", https://zhuanlan.zhihu.com/p/69379645
[2] Cloudflare API v4 Documentation, "Update DNS Record", https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record
[3] Cloudflare API v4 Documentation, "List DNS Records", https://api.cloudflare.com/#dns-records-for-a-zone-list-dns-records
本文基本上是按照文章[1]做的,只是稍有一些細(xì)節(jié)的更新备韧。除此之外具體的API細(xì)節(jié)還參考了官方的API Doc[2, 3]劫樟。
需求資源
- 一個域名,并且已經(jīng)托管到Cloudflare织堂。我們這里假設(shè)是
114514.love
叠艳。 - 擁有公網(wǎng)IPv6的一個server。我的是一臺裝好了官方系統(tǒng)的Raspberry Pi 3B易阳。
主要流程
1. 獲取相關(guān)的Key
進(jìn)入cloudflare的主頁 -> 左側(cè)Websites -> 點擊中間的域名附较,進(jìn)入域名設(shè)置部分。Overview的右側(cè)有一欄是API潦俺,在這里看到ZoneID和AccountID拒课。而API Key則需要點擊API token的獲取徐勃,會要求驗證密碼。
請務(wù)必保存好自己的這些Key早像,并記錄下如下內(nèi)容:
- 你注冊Cloudflare的郵箱僻肖。例:
senpei@imn.org
- Zone ID。每一個域名為一個Zone卢鹦,這個ID則代表了是哪個域名下臀脏。比如我們假設(shè)這里Zone ID是
Sleep-Black_Tea-ZoneID
。 - API token冀自。通過上面Get your API token獲取到揉稚。我們假設(shè)咱們的token是
nnnaaaAAAA!!!-APIToken
。 - 除此之外我們還需要一個DNS Record ID熬粗。請參考下面的過程獲取到這個ID窃植。我們先假設(shè)這個ID是
OneSummerDREAM-RecordID
。
2. 添加AAAA記錄并獲取其ID
進(jìn)入cloudflare的主頁 -> 左側(cè)Websites -> 點擊中間的域名荐糜,進(jìn)入域名設(shè)置部分巷怜。點擊DNS,右側(cè)選擇Add record暴氏。我們增加一條DNS解析記錄延塑。如下圖所示(圖是P的)。
解釋一下每個部分的含義:
- Type:AAAA表示為ipv6的解析。
- Name:這里寫了summer沼撕,那么我們之后使用域名的時候就是輸入
summer.114514.love
宋雏。 - Content: 這里先寫一個空白的v6地址。之后我們會使用自己的API對其進(jìn)行修改务豺。
- Proxy Status:把橘紅色可以點掉磨总,我們這里只需要它做DNS解析。
- TTL:可以設(shè)置一個你認(rèn)為合適的時間笼沥。時間越長蚪燕,DNS服務(wù)更新的就越慢。
搞定了之后奔浅,我們需要參考官方API文檔[2]里面的內(nèi)容馆纳,使用GET方法獲得這個summer.114514.love
所對應(yīng)的Record ID。你可以使用任何一種你習(xí)慣的方式汹桦。官方樣例里面直接用的是curl鲁驶。既然我們都在樹莓派下是一個linux環(huán)境,那么這里就直接運行curl進(jìn)行結(jié)果的獲任杪妗:
curl -X GET "https://api.cloudflare.com/client/v4/zones/Sleep-Black_Tea-ZoneID/dns_records?type=AAAA&name=summer.114514.love&page=1&per_page=100&order=type&direction=desc&match=all" \
-H "X-Auth-Email: senpei@imn.org" \
-H "X-Auth-Key: nnnaaaAAAA!!!-APIToken" \
-H "Content-Type: application/json"
url里面具體的參數(shù)請參考doc里面的說明钥弯∫挤#總之應(yīng)該可以拿到一個返回值的結(jié)果,結(jié)果直接打印在terminal里面會比較亂寿羞,但整理之后應(yīng)該大概長成下面這個樣子:
{
"success": true,
"errors": [],
"messages": [],
"result": [
{
"id": "OneSummerDREAM-RecordID",
"zone_id": "Sleep-Black_Tea-ZoneID",
"zone_name": "114514.love",
"name": "summer.114514.love",
"type": "AAAA",
"content": "::1",
... # 以下省略
}
]
}
我們需要的是result下面的id猖凛,這個就是該條目的Identifier。請記錄下來绪穆。
3. 寫DNS更新腳本并定時運行
更新現(xiàn)有的DNS條目可以參考官方文檔[3]辨泳。寫一個PUT即可完成。我們本地的腳本需要完成的工作為:
- 獲取本機(jī)的IPv6地址玖院。
- 調(diào)用官方給的API菠红,用PUT更新上去。
- 能跑通后难菌,把這個腳本設(shè)成每x分鐘運行一次试溯。
當(dāng)然更優(yōu)的方式是保存下來IPv6地址,只在變化的時候運行更新腳本郊酒。不過我懶了暫時沒寫這個遇绞。由于個人更熟悉Python操作,所以這個腳本我是用的Python寫的燎窘,放出來僅供參考摹闽。Python版本3.6,由于用到了f-string更低的版本請自行修改褐健。
import request
def update_addr(ipv6):
email = 'senpei@imn.org'
zone_id = 'Sleep-Black_Tea-ZoneID'
api_key = 'nnnaaaAAAA!!!-APIToken'
record_id = 'OneSummerDREAM-RecordID'
url_target = f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{record_id}'
headers = {
'X-Auth-Email': email,
'X-Auth-Key': api_key,
'Content-type': 'application/json',
}
data = {
'type': 'AAAA',
'name': 'blackpi.100097.xyz',
'content': ipv6,
'ttl': 300,
'proxied': False,
}
resp = requests.put(url_target, headers=headers, json=data)
return resp
而其中ipv6的地址則是使用了正則表達(dá)式獲雀堵埂:
import os
import re
def get_ipv6():
command = 'ip -6 addr show dev eth0 | grep global'
x = os.popen(command).read()
result = re.findall(r'(([a-f0-9]{1,4}:){7}[a-f0-9]{1,4})', x, re.I)
ipv6 = result[0][0]
return ipv6
以上。