joeseesun
joeseesun
Jul 7, 2016 · 6 min read

之前写了教程通过发邮件方式获取树莓派公网IP地址,虽然可以解决问题,但是每天收到一大堆邮件,而且每次都要通过IP地址进行访问,实在不是一个好的解决方案。

经过大家的留言提醒,告知可以借助DNSPOD的API来更新域名解析,实现DDNS。

如何做呢?

创建Token

登录Dnspod账户:https://www.dnspod.cn/console/dashboard

没有账号的可以注册一个,顺便买个域名使用Dnspod解析吧,相当不错。

网上很多教程都是使用用户名和密码来访问Dnspod API,这个感觉不太安全,建议使用token方式访问。

2016-07-05_23:17:14.jpg
2016-07-05_23:17:14.jpg

点击用户中心->安全设置->API Token->创建API Token

注意存储保存,因为只显示一次。重点记住ID和Token两个值,因为后续使用的登录Token需要由这两个数字使用英文逗号组合而成。

创建A记录域名解析

在你的Dnspod解析的某个域名里添加一个子域名(新买个独立域名也行),如下图所示:

2016-07-05_23:21:46.jpg
2016-07-05_23:21:46.jpg

创建一个A记录,主机名使用一个你喜欢而且不与其他子域名冲突的,这里我使用了ddns,记录值可以随便写(如何8.8.8.8),因为后续会不断通过API改变。

域名解析更新Python代码

为了实现获取公网IP地址并更新到Dnspod刚才创建的A记录中,需要写如下代码:

#!/usr/bin/env python2
# -*- coding:utf-8 -*-

import httplib
import urllib
import socket
import time

ID = "xxx" # 替换成上面你创建Token时获取的ID。
Token = "xxx" # 替换成上面你创建的Token。

params = dict(
login_token=("%s,%s" % (ID, Token)),
format="json",
domain_id=xxx, # 换成你的domian_id,待会下面讲如何通过Domain.List API获取
record_id=xxx, # 换成你的record_id,待会下面讲如何通过Record.List API获取
sub_domain="xxx", # 换成你上面创建的子域名
record_line="默认", #
)
current_ip = None


def ddns(ip):
params.update(dict(value=ip))
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/json"}
conn = httplib.HTTPSConnection("dnsapi.cn")
conn.request("POST", "/Record.Ddns", urllib.urlencode(params), headers)

response = conn.getresponse()
print response.status, response.reason
data = response.read()
print data
conn.close()
return response.status == 200


def getip():
sock = socket.create_connection(('ns1.dnspod.net', 6666), 20)
ip = sock.recv(16)
sock.close()
return ip

if __name__ == '__main__':
while True:
try:
ip = getip()
print ip
if current_ip != ip:
if ddns(ip):
current_ip = ip
except Exception as e:
print e
pass
time.sleep(30)

如何获取你的domian_id

参考DNSPOD API说明:https://www.dnspod.cn/docs/domains.html#domain-list

在Terminal中输入以下命令即可获取你的所有域名列表和domain_id信息,从结果中找到你设置了A记录解析的那个域名,记录下domain_id

curl -X POST https://dnsapi.cn/Domain.List -d ‘login_token=LOGIN_TOKEN&format=json’

注意:LOGIN_TOKEN是由ID和Token加英文逗号组合而成,即 LOGIN_TOKEN = ”ID,Token“

如何获取你的record_id

参考DNSPOD API说明:https://www.dnspod.cn/docs/records.html#record-list

在Terminal中输入以下命令即可获取所有的record_id信息,从结果中找到你新添加的那个子域名的record_id。

curl -X POST https://dnsapi.cn/Record.List -d ‘login_token=LOGIN_TOKEN&format=json&domain_id=xxx’

注意:domain_id就是上面你获取到的domain_id,LOGIN_TOKEN是由ID和Token加英文逗号组合而成,即 LOGIN_TOKEN = ”ID,Token“

如何定时更新域名解析?

把上面的域名解析Python代码存下来,我命名为ddns.py,放在/home/pi/ddns/目录下(或者你放到其他位置)

然后在终端运行:

sudo crontab -e

然后增加以下代码:

*/30 * * * * python /home/pi/ddns/ddns.py >> /home/pi/ddns/ddns.log 2>&1

意思是每隔30分钟运行一次,以便更新DNS记录。

完成

以后就可以使用自己的子域名访问到树莓派了,再也不用查看邮件里的IP地址了。

ssh pi@ddns.xxx.com

甚至你可以借助Ngnix或Apache在树莓派上搭建一个小网站让大家访问。(因为80和8080端口被联通封了,需要反向代理解析80端口)

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store