家庭公网IP动态解析之阿里云DNS
此服务使用Java开发,每隔10分钟进行阿里云dns解析。如果解析地址未变更,则不出发修改解析操作。
代码
1. AliClient 代码 获取指定域名的解析记录和修改
/**
* 阿里云客户端
*
* @author Created by Harry Ma on 2021-01-26
*/
@Component
public class AliClient {
private static IAcsClient client;
public AliClient() {
IClientProfile profile = DefaultProfile.getProfile(Constants.REGION_ID, AliDnsApplication.aliConfig.getAccessKey(), AliDnsApplication.aliConfig.getAccessSecret());
// 若报Can not find endpoint to access异常,请添加以下此行代码
// DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", "Alidns", "alidns.aliyuncs.com");
client = new DefaultAcsClient(profile);
}
public String getFirstDomain() {
DescribeDomainsRequest request = new DescribeDomainsRequest();
DescribeDomainsResponse response;
try {
response = client.getAcsResponse(request);
List<DescribeDomainsResponse.Domain> domains = response.getDomains();
if (domains.size() > 0) {
return domains.get(0).getDomainName();
}
} catch (ClientException e) {
e.printStackTrace();
}
return "";
}
/**
* 获取指定解析记录
*
* @param domainName 域名
* @param filterRR 获取的解析记录
* @return 解析记录
*/
public DescribeDomainRecordsResponse.Record getRecord(String domainName, String filterRR) {
DescribeDomainRecordsRequest describeDomainRecordsRequest = new DescribeDomainRecordsRequest();
describeDomainRecordsRequest.setDomainName(domainName);
DescribeDomainRecordsResponse describeSubDomainRecordsResponse;
try {
describeSubDomainRecordsResponse = client.getAcsResponse(describeDomainRecordsRequest);
for (DescribeDomainRecordsResponse.Record domainRecord : describeSubDomainRecordsResponse.getDomainRecords()) {
if (filterRR != null && filterRR.equals(domainRecord.getRR())) {
return domainRecord;
}
}
} catch (ClientException e) {
e.printStackTrace();
}
return null;
}
public void updateRecordIp(String ip, String recordId, String rR) {
UpdateDomainRecordRequest request = new UpdateDomainRecordRequest();
request.setRR(rR);
request.setRecordId(recordId);
request.setType(Constants.TYPE);
request.setValue(ip);
try {
HttpResponse response = client.doAction(request);
if (response.isSuccess()) {
System.out.println("DNS解析成功^_^");
return;
}
if (response.getHttpContentString().contains("The DNS record already exists.")){
System.err.println("当前解析记录已存在...");
}
System.err.println("DNS解析失败,请检查$_$");
} catch (ClientException e) {
System.err.println(e.getErrMsg());
}
}
}
2. 定时任务类
/**
* 定时修改阿里云动态DNS
*
* @author Created by Harry Ma on 2021-01-26
*/
@Component
@EnableScheduling
public class DnsSchedule {
@Resource
private AliClient aliClient;
/**
* 每10分钟修改一次云解析记录
*/
@Scheduled(fixedRate = 1000 * 60 * 10)
private void dnsTasks() {
String nowIp = getNowIp();
if (nowIp == null || nowIp.equals("")) {
System.err.println("获取当前IP为空,请检查");
return;
}
String firstDomain = aliClient.getFirstDomain();
System.out.printf("获取到的domain为: %s%n", firstDomain);
DescribeDomainRecordsResponse.Record record = aliClient.getRecord(firstDomain, AliDnsApplication.aliConfig.getRr());
System.out.printf("获取到指定RR(%s)为: %s%n", AliDnsApplication.aliConfig.getRr(), JSONObject.toJSONString(record));
if (!nowIp.equals(record.getValue())){
aliClient.updateRecordIp(nowIp, record.getRecordId(), AliDnsApplication.aliConfig.getRr());
}
System.out.println("当前IP与解析IP相同,无需更新...");
}
private String getNowIp() {
HttpGet httpGet = new HttpGet(Constants.REQUEST_IP_URL);
httpGet.addHeader(Constants.ACCEPT_STR, Constants.ACCEPT_VALUE);
httpGet.addHeader(Constants.CONNECTION_STR, Constants.CONNECTION_VALUE);
httpGet.addHeader(Constants.USER_AGENT_STR, Constants.USER_AGENT_VALUE);
CloseableHttpClient client = HttpClients.createDefault();
try {
CloseableHttpResponse response = client.execute(httpGet);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String result = EntityUtils.toString(response.getEntity());
return Objects.requireNonNull(JSONObject.parseObject(result)).getString(Constants.IP_STR);
}
} catch (IOException e) {
System.err.println(e.getMessage());
}
return "";
}
}
3. 常量类
/**
* @author Created by Harry Ma on 2021-01-26
*/
public interface Constants {
String TYPE = "A";
String REGION_ID = "cn-hangzhou"; //地域ID 默认
String IP_STR = "ip";
String REQUEST_IP_URL = "https://api.ipify.org/?format=json";
String ACCEPT_STR = "Accept";
String CONNECTION_STR = "Connection";
String USER_AGENT_STR = "User-Agent";
String ACCEPT_VALUE = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
String CONNECTION_VALUE = "Keep-Alive";
String USER_AGENT_VALUE = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0";
String SEPARATOR_STR = ":";
String COMMA = ",";
String BLANK_STR = "";
}
如有不依赖jdk运行需求,请自行查找解决方法