文章目录
前言一、场景二、名词解释1.什么是Godaddy?2.什么是DDNS?3.什么是公网IP?4.什么是A记录?5.什么是HTTP?三、动手实现1.获取API Key2.观摩API文档3.使用CURL测试4.客户端实现5.服务端实现总结前言
当你有了一个公网IP,又购买了一个域名,想让域名指向你的IP当然很简单,但公网IP总变就会让简单的事变复杂。为了让人继续偷懒,所以有了DDNS。本文用了一种匪夷所思的方式实现了DDNS,可能大家看了觉得多少沾点还能这么玩儿,多少能给世界增添一丝乐趣也是极好的。
一、场景
有一个公网IP,该IP的某些端口可通过路由映射到某台Windows机器的某些端口上,但该公网动态IP隔一段时间就会因为租约到期更换IP。现在有一个Godaddy购买的域名,想稳定的指向这台Windows机器,于是在这台机器上写一个bat脚本隔一小段时间就会curl到另一台VPS的接口服务上,该VPS有稳定的域名并提供稳定的服务,该服务使用Java编写,逻辑就是获取来访IP并存入数据库中,在存入库中之前先和之前存的最新IP对比,如果不同,则使用HTTP请求到Godaddy,刷新A记录,实现闭环DDNS。
二、名词解释
1.什么是Godaddy?
不对
还是不对
是这个↑
你可以从godaddy上买到域名
2.什么是DDNS?
Dynamic Domain Name Server,动态域名服务
如果DNS是一本将域名翻译成IP的字典,DDNS就是雇了一个人帮你自动翻字典。
3.什么是公网IP?
在互联网上能被认可的IP。IPV4的IP在公网上就那么多,不够用了所以挺珍贵的。相对就是局域网IP,一般用192.168开头。你家开的网如果没跟运营商说过一般都不是公网IP,而是运营商给你开的一个和邻居啥的共用的局域网,最后这群人共用一个公网IP作为出口进入互联网。用这种IP你可以上网,但网络上的人可找不到你。
4.什么是A记录?
A (Address) 记录是用来指定主机名(或域名)对应的IP地址记录。
简单说就是你这个域名要对应到哪个IP。
5.什么是HTTP?
HTTP是一种网络传输协议,简单理解浏览网页使用的就是HTTP协议,使用浏览器发送请求给某个服务器,服务器回复给你响应信息,浏览器会把响应信息翻译成你能看得懂的网页。HTTP只是协议,不用浏览器,用CURL命令,用PostMan等工具,也可以使用HTTP发送信息。我们本文使用Java自带的HTTPUrlConnection发送和接收HTTP消息。
三、动手实现
1.获取API Key
这里默认你已经注册了godaddy账号并购买了一个域名,下面要获取一个key-secret。
申请key链接:/keys
点击右上Create New API Key
可以起一个名,下面的Environment选择Production(生产环境)即可。(ote是业务测试环境)
弹框会显示一组key-secret,key是公钥,secret是私钥,其中私钥只会显示这一次,如果不小心掉到弹窗外空白的地方弹窗关掉了就没了(别问我怎么知道的),保存在比较保险的地方,一会要用。
2.观摩API文档
这一步来研究这个文档:/doc/endpoint/domains#/v1/recordReplace
(所有接口的前缀是)
我们用到的接口是/v1/domains/{domain}/records 它的作用是替换某具体域名下所有DNS记录,接口里的花括号domain是域名,记得替换。
下面来看一下参数:
X-Shopper-Id是字符串类型的放到header里的一个参数,只有当你是经销商管理不在你账号下的域名时需要这个字段balabalabala,我们用不到,不用管。
doamin是字符串类型的api路径里的参数,就是上面提醒你替换成你域名的那个地方。
records是body里的请求体,可使用json格式编写,格式是一个数组[]里包含一个或多个对象{}对应一个或多个记录。每个对象里我们用到的参数有data(值),name(名称),type(类型),ttl(TTL)。可对应下图记录中各字段。
关于响应返回消息,正常code就是200,响应体没有信息,更多返回code可参考接口文档。
3.使用CURL测试
这一步测试拼起来的请求参数是不是好用,肥肠自信的同学可以跳过这一步。
CURL命令(centOS 7):
curl -X PUT “/v1/domains/域名/records” -H “accept: application/json” -H “Content-Type: application/json” -H “Authorization: sso-key 公钥:私钥” -d ‘[{“data”:“A记录IP”,“name”:"@",“ttl”:600,“type”:“A”},{“data”:“”,“name”:"@",“ttl”:3600,“type”:“NS”},{“data”:“”,“name”:"@",“ttl”:3600,“type”:“NS”},{“data”:"@",“name”:“www”,“ttl”:3600,“type”:“CNAME”},{“data”:"_domainconnect",“name”:"_domainconnect.",“ttl”:3600,“type”:“CNAME”}]’
坑:-d后面跟的json参数用单引号括起来,否则报422 "code":"INVALID_BODY","message":"invalid character 'd' looking for beginning of object key string"ttl的参数值不要用引号括起来
4.客户端实现
windows端编辑一个文档,保存扩展名为.bat:
@echo off:startcurl -s 接口服务URLecho ----- %DATE:~4,4%%DATE:~9,2%%DATE:~12,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%choice /t 300 /d y /n >nullgoto start
点开之后就自动循环请求,以上样例代码循环时间间隔为300秒。
5.服务端实现
Java实现,项目啥的自己搭,只贴关键代码
@RequestMapping({"接口名"})public int updateRecord(HttpServletRequest request) {//recordIPService.getRecordIP()是拿库中最新的IPif(!recordIPService.getRecordIP().equals(request.getRemoteAddr())) {LOGGER.info("updating Record...");HttpURLConnection conn = null;String payload = "[{\"data\":\"" + request.getRemoteAddr() + "\",\"name\":\"@\",\"ttl\":600,\"type\":\"A\"},{\"data\":\"\",\"name\":\"@\",\"ttl\":3600,\"type\":\"NS\"},{\"data\":\"\",\"name\":\"@\",\"ttl\":3600,\"type\":\"NS\"},{\"data\":\"@\",\"name\":\"www\",\"ttl\":3600,\"type\":\"CNAME\"},{\"data\":\"_domainconnect\",\"name\":\"_domainconnect.\",\"ttl\":3600,\"type\":\"CNAME\"}]";try {URL url = new URL("/v1/domains/域名/records");conn = (HttpURLConnection) url.openConnection();conn.setDoInput(true);conn.setDoOutput(true);conn.setRequestMethod("PUT");conn.setRequestProperty("Accept", "application/json");conn.setRequestProperty("Content-Type", "application/json");//这里公钥和私钥之间是英文冒号,注意格式conn.setRequestProperty("Authorization", "sso-key 公钥:私钥");OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);writer.write(payload);writer.close();conn.connect();} catch (IOException e) {e.printStackTrace();} finally {if( null != conn ) {conn.disconnect();}}}//将最新IP入库int result = recordIPService.insertRecordIP(request.getRemoteAddr());LOGGER.info("Result:" + result);return result;}
总结
以上就是一个非常奇特的DDNS实现,实际上可以把请求修改域名的服务放在本机上,又不是不能上网这样用到了另一个已经有DDNS的VPS上多少沾点一般人不会这么干,至于本机上获取外网IP,网上搜一下到处都有。本机上实现起来用python会方便一点。
参考文章:/network/1633.html