好物优选点击查看详情 京东购买

暂无内容

阿里云域名动态DDNS配置

一、设置阿里云域名管理账号

为了安全,我们新建一个子账号,仅编程访问且只有域名修改的权限。

1.1 登录阿里云控制台

1.2 在产品与服务中搜“访问控制”

阿里云域名动态DDNS配置插图

1.3 创建新用户,只勾选编程访问。

这里要记住AccessKeyID和AccessKey Secret,后面需要用到。

阿里云域名动态DDNS配置插图1

1.4 添加DNS管理权限

找到AliyunDNSFullAccess权限,并添加。

阿里云域名动态DDNS配置插图2

二、编写程序实时判断本地公网IP并修改阿里云域名解析IP

2.1 新建maven项目,并添加阿里云开发工具包。

<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-alidns</artifactId> <version>2.0.10</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.3.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency> 

2.2 配置文件

{ "regionId": "cn-hangzhou", "accessKeyId": "前面创建账号的AccessKeyID", "secret": "前面创建账号的AccessKey Secret", "tld":"zengwu.com.cn", "rr": "a", "dnsInterval": 86400, "ipInterval": 10 } 
  • regionId: 区域,域名管理一般是杭州”cn-hangzhou”
  • accessKeyId: 前面创建账号的AccessKeyID
  • secret: 前面创建账号的AccessKey Secret
  • tld: 顶级域名
  • rr: 主机名
  • dnsInterval: 检查阿里云DNS配置的间隔时间(秒)
  • ipInterval: 检查本地公网IP的间隔时间(秒)

2.3 程序代码

package com.zngw.aliddns; import com.alibaba.fastjson.JSON; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.alidns.model.v20150109.DescribeSubDomainRecordsRequest; import com.aliyuncs.alidns.model.v20150109.DescribeSubDomainRecordsResponse; import com.aliyuncs.alidns.model.v20150109.UpdateDomainRecordRequest; import com.aliyuncs.alidns.model.v20150109.UpdateDomainRecordResponse; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.profile.DefaultProfile; import com.google.gson.Gson; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * DDNS class * * @author 55 * @date 2021/6/28 */ public class DDNS { private String recordsIp = ""; // 域名IP private long lastDnsTime = 0; // 上次域名查询时间 private long lastIpTime = 0; // 上次公网ip查询时间 private String host = null; // 完整域名 private Config cfg = null; // 配置文件 /** * 初始化 */ private void init(String filename){ String cfgStr = readJsonFile(filename); cfg = JSON.parseObject(cfgStr, Config.class); if (cfg == null){ System.out.println("读取配置文件"+filename+"失败"); return; } cfg.dnsInterval *= 1000; cfg.ipInterval *= 1000; host = cfg.rr + "." +cfg.tld; if (cfg.rr == null || cfg.rr.length() == 0 || "@".equals(cfg.rr)){ // 顶级域名处理 cfg.rr = "@"; host = cfg.tld; } } /** * 获取当前主机公网IP */ private String getCurrenHostIp() { // 这里使用jsonip.com第三方接口获取本地IP String jsonip = "https://jsonip.com"; // 接口返回结果 String result = ""; BufferedReader in = null; try { // 使用HttpURLConnection网络请求第三方接口 URL url = new URL(jsonip); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.connect(); in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); String line; while((line = in.readLine()) != null) { result += line; } } catch (Exception e) { e.printStackTrace(); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } // 正则表达式,提取xxx.xxx.xxx.xxx,将IP地址从接口返回结果中提取出来 String rexp = "(\\d{1,3}\\.){3}\\d{1,3}"; Pattern pat = Pattern.compile(rexp); Matcher mat = pat.matcher(result); String res = ""; while (mat.find()) { res = mat.group(); break; } return res; } /** * 获取主域名的所有解析记录列表 */ private DescribeSubDomainRecordsResponse describeSubDomainRecords(DescribeSubDomainRecordsRequest request, IAcsClient client) { try{ // 调用SDK发送请求 return client.getAcsResponse(request); } catch (ClientException e) { e.printStackTrace(); // 发生调用错误,抛出运行时异常 throw new RuntimeException(); } } /** * 修改解析记录 */ private UpdateDomainRecordResponse updateDomainRecord(UpdateDomainRecordRequest request, IAcsClient client) { try { // 调用SDK发送请求 return client.getAcsResponse(request); } catch (ClientException e) { e.printStackTrace(); // 发生调用错误,抛出运行时异常 throw new RuntimeException(); } } /** * 检测IP是否改变,改变了就修改 */ private void check(String ip){ // 设置鉴权参数,初始化客户端 DefaultProfile profile; profile = DefaultProfile.getProfile(cfg.regionId,cfg.accessKeyId,cfg.secret); IAcsClient client = new DefaultAcsClient(profile); //查询指定域名的最新解析记录 DescribeSubDomainRecordsRequest describeSubDomainRecordsRequest = new DescribeSubDomainRecordsRequest(); describeSubDomainRecordsRequest.setSubDomain(host); DescribeSubDomainRecordsResponse describeSubDomainRecordsResponse = describeSubDomainRecords(describeSubDomainRecordsRequest, client); List<DescribeSubDomainRecordsResponse.Record> domainRecords = describeSubDomainRecordsResponse.getDomainRecords(); //最新的一条解析记录 if (domainRecords.size() != 0) { DescribeSubDomainRecordsResponse.Record record = domainRecords.get(0); // 记录ID String recordId = record.getRecordId(); // 记录值 recordsIp = record.getValue(); if (!ip.equals(recordsIp)) { // 修改解析记录 UpdateDomainRecordRequest updateDomainRecordRequest = new UpdateDomainRecordRequest(); // 主机记录 updateDomainRecordRequest.setRR(cfg.rr); // 记录ID updateDomainRecordRequest.setRecordId(recordId); // 将主机记录值改为当前主机IP updateDomainRecordRequest.setValue(ip); // 解析记录类型 updateDomainRecordRequest.setType("A"); UpdateDomainRecordResponse updateDomainRecordResponse = updateDomainRecord(updateDomainRecordRequest, client); System.out.println("域名 "+host+" 解析地址已修改为:" + ip); recordsIp = ip; } } } /** * 运行检测 */ private void run(){ while (true){ long now = System.currentTimeMillis(); // 当前主机公网IP String ip = getCurrenHostIp(); // 查询域名服务器值是否改变 if (lastDnsTime < now){ check(ip); lastIpTime = now + cfg.ipInterval; lastDnsTime = now + cfg.dnsInterval; } // 公网IP是否发生改变 if (lastIpTime < now){ if (ip!=null && !ip.equals(recordsIp)){ check(ip); lastDnsTime = now + cfg.dnsInterval; } lastIpTime = now + cfg.ipInterval; } try { // 进程睡眠释放CPU并达到延迟效果 Thread.sleep(Math.min( lastIpTime,lastDnsTime) - now -1); }catch(InterruptedException e) { e.printStackTrace(); } } } /** * 读取json文件,返回json串 * @param fileName * @return */ public String readJsonFile(String fileName) { String jsonStr = ""; try { File jsonFile = new File(fileName); FileReader fileReader = new FileReader(jsonFile); Reader reader = new InputStreamReader(new FileInputStream(jsonFile), "utf-8"); int ch = 0; StringBuffer sb = new StringBuffer(); while ((ch = reader.read()) != -1) { sb.append((char) ch); } fileReader.close(); reader.close(); jsonStr = sb.toString(); return jsonStr; } catch (IOException e) { e.printStackTrace(); return null; } } public static void main(String[] args) { String filename = "./config.json"; DDNS ddns = new DDNS(); ddns.init(filename); ddns.run(); } } 

三、运行

编译好jar程序,将jar和config.json放到同一目录下,直接后台运行jar就可以了。

附:完整mavn项目

原文链接:https://www.jianshu.com/p/b8e01206f58c

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享