编写 java 程序,为家用电脑 ipv6 自动更新 goddy dns 记录(ddns)

Posted Jacklondon Chen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编写 java 程序,为家用电脑 ipv6 自动更新 goddy dns 记录(ddns)相关的知识,希望对你有一定的参考价值。

家里放了一台旧 acer 笔记本电脑,外挂几个硬盘盒,插上几个硬盘,组成硬盘盒。

因笔记本电脑的耗电较小,硬盘盒有自动休眠省电模式,所以长期开机。此笔记本电脑,使用家庭的移动宽带,会自动分配 IPv6 , 可远程连接。

之前,自动分配 IPv6,很长时间不变。当然,我不可能去记这个 IPv6,所以找个 DNS 服务器,记在 AAAA 记录里。

最近好像不停地变化,这就麻烦了。用 cn.bing.com 网上搜索一番, 找到有脚本可自动更新 goddy dns 记录(ddns)。恰好我购买了一个goddy 的域名,附送 DNS 管理,也有免费的 DDNS 编程接口。脚本语言我不太熟悉,于是就改成用 java 重写了一次。

程序分两部分:

a. 主控 main 类 UpdateDdns,负责反复循环,每间隔 5 秒,检查 IP 地址是否变化。

b. 业务操作类 UpdateSrv, 负责单次循环中的业务。

 

代码比较简单,直接贴上,以下是 UpdateDdns.java :

 package update_godaddy_ddns;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class UpdateDdns {
 
     public static void main(String[] args) {
         Logger log = LoggerFactory.getLogger(UpdateDdns.class);
         log.info("main begin...");
         String domain = args[0]; // "mydomain.com" # your domain
         String typeMulti = args[1]; // ="A" # Record type A, CNAME, MX, etc.
         String name = args[2]; // "sip" # name of record to update
         String ttl = args[3]; // "3600" # Time to Live min value 600
         String port = args[4]; // "1" # Required port, Min value 1
         String weight = args[5]; // "1" # Required weight, Min value 1
         String key = args[6]; // "abc" # key for godaddy developer API
         String secret = args[7]; // "efg" # secret for godaddy developer API
 
         String[] typeArrr = typeMulti.split("/");
         UpdateSrv srv = new UpdateSrv();
 
         log.info("start work loop");
         while (true) {
             try {
                 for (String type : typeArrr) {
                     srv.doUpdate(domain, type, name, ttl, port, weight, key, secret);
                 }
 
                 Thread.sleep(5000);
             } catch (Exception err) {
                 //err.printStackTrace();
                 log.error(err.getMessage(),err);
             }
         }
         // log.info("main end");
     }
 
 }

 

以下是 UpdateSrv.java

 package update_godaddy_ddns;
 
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Enumeration;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.StatusLine;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPut;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import net.sf.json.JSONArray;
 import net.sf.json.JSONObject;
 
 public class UpdateSrv {
     private String lastUpdatedIpToDnsServer;
 
     public void doUpdate(String domain, String type, String name, String ttl, String port, String weight, String key,
             String secret) throws ClientProtocolException, IOException {
         Logger log = LoggerFactory.getLogger(UpdateSrv.class);
         log.info("doUpdate begin...");
 
         if (this.lastUpdatedIpToDnsServer == null) {
             String ipFromDns = getIpFromDnsServer(domain, type, name, ttl, port, weight, key, secret);
             this.lastUpdatedIpToDnsServer = ipFromDns;
         }
 
         ArrayList<InetAddress> ipListForInternet = new ArrayList<InetAddress>();
 
         // getFromLocalMachine(ipListForInternet);
         getInternetIpsFromLocalMachine(ipListForInternet);
 
         if (ipListForInternet.isEmpty()) {
             log.warn("cannot find ipv6 for internet");
             return;
         }
 
         // check if already send ip of local machine public ip(in used) to DDNS server
         if (StringUtils.isNotEmpty(this.lastUpdatedIpToDnsServer)) {
             for (InetAddress ia : ipListForInternet) {
                 // String ip = ia.getHostAddress();
                 String ip = getIp(ia);
                 if (ip.equalsIgnoreCase(this.lastUpdatedIpToDnsServer)) {
                     log.info("local machine ip not changed,no need to update:" + ip);
                     return;
                 }
             }
         }
 
         String newIp = pickUpOneIpV6(ipListForInternet);
         if (StringUtils.isEmpty(newIp)) {
             log.warn("cannot find ipv6 for internet,2");
             return;
         }
 
         log.info("try update for newIp:" + newIp);
         tryUpdateIpForDns(newIp, domain, type, name, ttl, port, weight, key, secret);
         log.info("after update for newIp:" + newIp);
 
         // if no error
         this.lastUpdatedIpToDnsServer = newIp;
 
     }
 
     public void tryUpdateIpForDns(String newIp, String domain, String type, String name, String ttl, String port,
             String weight, String key, String secret) throws ClientProtocolException, IOException {
         Logger log = LoggerFactory.getLogger(UpdateSrv.class);
         log.info("tryUpdateIpForDns begin..." + newIp);
 
         // 1.获得一个httpclient对象
         try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
 
             // 2.生成一个 put 请求
             String url = "https://api.godaddy.com/v1/domains/" + domain + "/records/" + type + "/" + name;
             HttpPut httpput = new HttpPut(url);
             httpput.setHeader("Content-Type", "application/json");
             httpput.setHeader("Authorization", "sso-key " + key + ":" + secret);
 
             String strJson = "[{\\"data\\":\\"" + newIp + "\\",\\"ttl\\":" + ttl + "}]";
             StringEntity stringEntity = new StringEntity(strJson, "utf-8");
             httpput.setEntity(stringEntity);
 
             // 3.执行 put 请求并返回结果
             try (CloseableHttpResponse response = httpclient.execute(httpput)) {
                 log.info("after httpclient.execute");
 
 //                try {
                 // 4.处理结果
                 StatusLine sl = response.getStatusLine();
                 log.info("getStatusLine:" + sl);
                 // HTTP/1.1 401 Unauthorized
                 if (sl.getStatusCode() == 200) {
                     log.info("updated success");
                     StringBuilder sbBuffer = new StringBuilder();
 
                     try (InputStream is = response.getEntity().getContent()) {
                         try (InputStreamReader isr = new InputStreamReader(is)) {
                             try (BufferedReader reader = new BufferedReader(isr)) {
                                 String line;
                                 while ((line = reader.readLine()) != null) {
                                     log.info("strResponse:" + line);
                                     sbBuffer.append(line);
                                 }
                             }
                         }
                     }
 
                     String strResponse = sbBuffer.toString();
                     // should be empty
                     log.info("strResponse:" + strResponse);
                 } else {
 
                 }
             }
         }
     }
 
     // private void getFromLocalMachine(ArrayList<String> ipListForInternet) throws
     // SocketException {
     private void getInternetIpsFromLocalMachine(ArrayList<InetAddress> ipListForInternet) throws SocketException {
         Logger log = LoggerFactory.getLogger(UpdateSrv.class);
         log.info("getInternetIpsFromLocalMachine begin...");
 
         // get ip-v6 only
         Enumeration<NetworkInterface> ints = NetworkInterface.getNetworkInterfaces();
         while (ints.hasMoreElements()) {
             // each network card
             NetworkInterface it = ints.nextElement();
 
             Enumeration<InetAddress> adds = it.getInetAddresses();
             while (adds.hasMoreElements()) {
                 // each ip
                 InetAddress ia = adds.nextElement();
                 // String ip = ia.getHostAddress();
                 String ip = getIp(ia);
 //                if (ia instanceof Inet4Address) {
 //                    continue;
 //                } else if (ia instanceof Inet6Address) {
                 if (ia.isAnyLocalAddress()) {
                     continue;
                 } else if (ia.isLoopbackAddress()) {
                     continue;
                 } else if (ia.isLinkLocalAddress()) {
                     continue;
                 } else if (ia.isSiteLocalAddress()) {
                     continue;
                 }
 
                 if (ip.startsWith("fe80:")) {
                     continue;
                 }
                 // ipListForInternet.add(ip);
                 ipListForInternet.add(ia);
 //                } else {
 //                    // should not goes here.
 //                }
 
             }
         }
     }
 
     private String getIpFromDnsServer(String domain, String type, String name, String ttl, String port, String weight,
             String key, String secret) throws ClientProtocolException, IOException {
         Logger log = LoggerFactory.getLogger(UpdateSrv.class);
         log.info("getIpFromDns begin...");
 
         // 1.获得一个httpclient对象
         try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
 
             // 2.生成一个get请求
             String url = "https://api.godaddy.com/v1/domains/" + domain + "/records/" + type + "/" + name;
             HttpGet httpget = new HttpGet(url);
             httpget.addHeader("Authorization", "sso-key " + key + ":" + secret);
             // 3.执行get请求并返回结果
             try (CloseableHttpResponse response = httpclient.execute(httpget)) {
                 log.info("after httpclient.execute");
 
 //                try {
                 // 4.处理结果
                 StatusLine sl = response.getStatusLine();
                 log.info("getStatusLine:" + sl);
                 // HTTP/1.1 401 Unauthorized
                 if (sl.getStatusCode() == 200) {
                     StringBuilder sbBuffer = new StringBuilder();
 
                     try (InputStream is = response.getEntity().getContent()) {
                         try (InputStreamReader isr = new InputStreamReader(is)) {
                             try (BufferedReader reader = new BufferedReader(isr)) {
                                 String line;
                                 while ((line = reader.readLine()) != null) {
                                     log.info("strResponse:" + line);
                                     sbBuffer.append(line);
                                 }
                             }
                         }
                     }
 
                     String strResponse = sbBuffer.toString();
                     // [{"data":"2409:8a1e:90ad:a1e0:dd40:8bcd:xxx","name":"abc-ipv6","ttl":1800,"type":"AAAA"}]
                     log.info("strResponse:" + strResponse);
 
                     // parse
                     String ip = parseIpFromGodaddyResponse(strResponse);
                     return ip;
                 } else {
 
                 }
             }
         }
 
         return null;
     }
 
     public String parseIpFromGodaddyResponse(String strResponse) {
         Logger log = LoggerFactory.getLogger(UpdateSrv.class);
         log.info("parseIpFromGodaddyResponse begin..." + strResponse);
 
         // [{"data":"2409:8a1e:90ad:a1e0:dd40:8bcd:xxx","name":"abc-ipv6","ttl":1800,"type":"AAAA"}]
         // JSONObject obj = JSONObject.fromObject(strResponse);
         JSONArray arr = JSONArray.fromObject(strResponse);
 
         for (Object object : arr) {
             JSONObject obj = (JSONObject) object;
 
             // Set keys = obj.keySet();
             String name = (String) obj.get("name");
             Number ttl = (Number) obj.get("ttl");
             String type = (String) obj.get("type");
             String data = (String) obj.get("data");
 
             log.info("name:" + name + ",ttl:" + ttl + ",type:" + type + ",data:" + data);
 
             if (StringUtils.isNotEmpty(data)) {
                 return data;
             }
         }
         // log.info(arr.toString());
 
         return null;
     }
 
     private String pickUpOneIpV6(Collection<InetAddress> ipListForInternet) {
         Logger log = LoggerFactory.getLogger(UpdateSrv.class);
         log.info("pickUpOneIpV6 begin...");
 
         for (InetAddress ia : ipListForInternet) {
             if (ia instanceof Inet4Address) {
                 continue;
             } else if (ia instanceof Inet6Address) {
                 String ip = getIp(ia);
                 return ip;
             } else {
                 // should not goes here.
             }
         }
         return null;
     }
 
     private String getIp(InetAddress ia) {
         String ip = ia.getHostAddress();
         // 2409:891e:9340:xxx:xxx:xxx:f3c7:xxx%wlp4s0
         int pos = ip.lastIndexOf("%");
         if (pos > 0) {
             ip = ip.substring(0, pos);
         }
         return ip;
     }
 }

 

 

编译后,在 ubuntu 下,使用命令行运行:

export CLASSPATH=".:../bin:../lib/slf4j-api-1.7.25.jar:../lib/httpclient-4.5.2.jar:../lib/httpcore-4.4.4.jar:../lib/jcl-over-slf4j-1.7.25.jar:../lib/logback-classic-1.2.3.jar:../lib/logback-core-1.2.3.jar:../lib/json-lib-2.4-jdk15.jar:../lib/commons-lang-2.4.jar:../lib/commons-lang3-3.0.1.jar:../lib/ezmorph-1.0.6.jar:../lib/commons-collections-3.2.2.jar:../lib/commons-beanutils-1.9.3.jar"

java update_godaddy_ddns.UpdateDdns some.com AAAA zg_xxx 1800 1 1 xxx yyy

 

命令行参数的含义,见 UpdateDdns.java 中的 main 函数。

 

--------------欢迎转载,转载请注明出处: https://www.cnblogs.com/jacklondon

转载请注明出处: http://www.cnblogs.com/jacklondon ; 欢迎访问 http://www.zheguisoft.com/ 并提建议。

以上是关于编写 java 程序,为家用电脑 ipv6 自动更新 goddy dns 记录(ddns)的主要内容,如果未能解决你的问题,请参考以下文章

win10电脑连接路由器和光猫后不能连网,IPV4和IPV6无网络访问权限,DNS设为自动显示错误

Window配置网络设定IPv6的固定IP自动被修改为169.254.*.*的问题

使用 Java Swing 编写 IpChat, 基于 IP Messenger 协议,支持 IPv6

如何编写木马程序?

苹果手机开启wifi,电脑连上之后,没网络不能上网,无线网络状态ipv6无网络访问权限

路由器ipv6功能关闭还是开启 怎样把路由器设置成IPv6