基于Cloudflare DNS 部署 IPv6 DDNS

需求

自己有一个树莓派,在家可以拿到公网IPv6地址。
但IPv6地址经常变化,所以需要将IPv6地址映射到域名上。这样后面配置各种服务会方便很多。

参考内容:

[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]做的,只是稍有一些细节的更新。除此之外具体的API细节还参考了官方的API Doc[2, 3]。

需求资源

  • 一个域名,并且已经托管到Cloudflare。我们这里假设是 114514.love
  • 拥有公网IPv6的一个server。我的是一台装好了官方系统的Raspberry Pi 3B。

主要流程

1. 获取相关的Key

进入cloudflare的主页 -> 左侧Websites -> 点击中间的域名,进入域名设置部分。Overview的右侧有一栏是API,在这里看到ZoneID和AccountID。而API Key则需要点击API token的获取,会要求验证密码。


API部分长成这样

请务必保存好自己的这些Key,并记录下如下内容:

  • 你注册Cloudflare的邮箱。例:senpei@imn.org
  • Zone ID。每一个域名为一个Zone,这个ID则代表了是哪个域名下。比如我们假设这里Zone ID是Sleep-Black_Tea-ZoneID
  • API token。通过上面Get your API token获取到。我们假设咱们的token是nnnaaaAAAA!!!-APIToken
  • 除此之外我们还需要一个DNS Record ID。请参考下面的过程获取到这个ID。我们先假设这个ID是 OneSummerDREAM-RecordID

2. 添加AAAA记录并获取其ID

进入cloudflare的主页 -> 左侧Websites -> 点击中间的域名,进入域名设置部分。点击DNS,右侧选择Add record。我们增加一条DNS解析记录。如下图所示(图是P的)。

一个解析的样例。(图是P的!)

解释一下每个部分的含义:

  • Type:AAAA表示为ipv6的解析。
  • Name:这里写了summer,那么我们之后使用域名的时候就是输入 summer.114514.love
  • Content: 这里先写一个空白的v6地址。之后我们会使用自己的API对其进行修改。
  • Proxy Status:把橘红色可以点掉,我们这里只需要它做DNS解析。
  • TTL:可以设置一个你认为合适的时间。时间越长,DNS服务更新的就越慢。

搞定了之后,我们需要参考官方API文档[2]里面的内容,使用GET方法获得这个summer.114514.love所对应的Record ID。你可以使用任何一种你习惯的方式。官方样例里面直接用的是curl。既然我们都在树莓派下是一个linux环境,那么这里就直接运行curl进行结果的获取:

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里面具体的参数请参考doc里面的说明。总之应该可以拿到一个返回值的结果,结果直接打印在terminal里面会比较乱,但整理之后应该大概长成下面这个样子:

{
  "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更新脚本并定时运行

更新现有的DNS条目可以参考官方文档[3]。写一个PUT即可完成。我们本地的脚本需要完成的工作为:

  1. 获取本机的IPv6地址。
  2. 调用官方给的API,用PUT更新上去。
  3. 能跑通后,把这个脚本设成每x分钟运行一次。

当然更优的方式是保存下来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的地址则是使用了正则表达式获取:

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

以上。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容