目录

1.创建一个springboot项目:

 2.添加依赖

3.添加代码

 4.创建定时任务

 5.获取token

6.修改配置

如果你有公网ip,或者可以通过ipv4地址访问设备,那到这一步就可以跳转到打包步骤了,需要解析ipv6的请继续往下看

7.修改代码获取ipv6地址

8.打包

9.添加手动更新(非必需)

10.最后


首先简单回顾一下整体思路:在服务器部署一个基于springboot的jar包,长期运行该jar包,在里面设置一个定时任务,定时执行函数实现dns解析的更新

1.创建一个springboot项目:

文件--->新建--->项目--->Spring Initializr

 

spring boot ip spring boot ipv6_java

 图中红线框内一般选择默认即可,若选择默认点击下一步后一直加载不出来,可以先择下面一个,换成阿里云的源https://start.aliyun.com/

接下来的参数看着填,只要合规就行,不影响整体

 2.添加依赖

向生成的pom.xml中添加依赖

实现动态域名解析DDNS (aliyun.com)

spring boot ip spring boot ipv6_阿里云_02

https://help.aliyun.com/document_detail/141482.html

这是阿里云官方的sdk演示文档,里面提供了需要的依赖项目以及代码

 

spring boot ip spring boot ipv6_dns服务器_03

 点击右上角可以快速复制代码

然后删除掉最外面的一层<dependencies></dependencies>标签,因为需要嵌入的代码中已经有了这个标签

spring boot ip spring boot ipv6_spring boot_04

 在项目文件中找到pom.xml,贴着</dependencies>上一行插进去

spring boot ip spring boot ipv6_dns服务器_05

注意下面的<dependencyManagement>中也有<dependencies>标签,不要放到这个里面,否则会报错

3.添加代码

在java文件夹下的包名文件夹下,创建一个类,类名“DDNS”,用官方文档中的Java代码覆盖该类,将这个类的main方法改成一个普通的方法,方便外部调用

 

spring boot ip spring boot ipv6_spring boot_06

 4.创建定时任务

在Java目录下自动生成的application类中添加@EnableScheduling注解,表示该项目允许使用定时任务

@SpringBootApplication
@EnableScheduling
public class PnonednsApplication {

    public static void main(String[] args) {
        SpringApplication.run(PnonednsApplication.class, args);
    }

}

然后再创建一个用于存放定时任务函数的类,比如UpdateTask

写一个方法调用之前官方给出的api函数,在它上面加注解@Scheduled(cron = "0 0 0/1 * * ? "),表示小时整点执行一次,具体执行规则由cron字符串所指定,最后通过log在服务器中记录更新日志

spring boot ip spring boot ipv6_阿里云_02

/**
 * @author Y.zero
 * @date 2021/9/16
 */
@Slf4j
@Component
@EnableScheduling
@Configuration
public class UpdateTask {
    @Scheduled(cron = "0 0 0/1 * * ? ")
    //定时任务,每隔一小时更新一次
    public void updateTest(){
        DDNS.go();
        log.info(time+"服务器ipv6地址dns解析更新");
    }
}

 5.获取token

到阿里云官网,登陆后鼠标放在头像上就可以看到“AccseeKey管理”选项

 点开后选择使用子账户,直接使用主体账号也行,但会有安全风险,推荐创建一个子账户,只给它修改dns的权限

spring boot ip spring boot ipv6_java_08

创建账号,然后将id和secrett复制,然后给账号添加权限,否则用此账号的token无法修改dns

 

spring boot ip spring boot ipv6_阿里云_09

spring boot ip spring boot ipv6_java_10

搜索框输入dns,然后添加“AliyunDNSFullAccess”权限

6.修改配置

 将获取到的账号信息粘贴到DDNS类中对应的位置 

 

spring boot ip spring boot ipv6_spring boot ip_11

 然后修改配置

spring boot ip spring boot ipv6_spring boot ip_12

以上信息是需要修改的,主域名填写你的域名 ,

主机记录这里需要注意,输入主机记录以后会将“主机记录.域名”的一个子域名绑定到该ip上

spring boot ip spring boot ipv6_java_13

 

设置解析类型,ipv4解析类型为“A”,ipv6解析类型为“AAAA”,按照自己的需求设置

如果你有公网ip,或者可以通过ipv4地址访问设备,那到这一步就可以跳转到打包步骤了,需要解析ipv6的请继续往下看

7.修改代码获取ipv6地址

        

spring boot ip spring boot ipv6_dns服务器_14

 官方文档上给出的获取ip的输出结果是ipv4地址,需要自己写方法获取ipv6

创建一个类,命名为“getIPv6”,用以下代码覆盖该类

package xyz.yzero.pnonedns.controller;

import java.io.IOException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

public class getIPv6 {
    public static String getLocalIPv6Address() throws IOException {
        InetAddress inetAddress = null;
        Enumeration<NetworkInterface> networkInterfaces =
                NetworkInterface
                        .getNetworkInterfaces();
        outer:
        while (networkInterfaces.hasMoreElements()) {
            Enumeration<InetAddress> inetAds =
                    networkInterfaces.nextElement()
                            .getInetAddresses();
            while (inetAds.hasMoreElements()) {
                inetAddress = inetAds.nextElement();
                //Check if it's ipv6 address and reserved address
                if (inetAddress instanceof Inet6Address
                        && !isReservedAddr(inetAddress)) {
                    break outer;
                }
            }
        }
        String ipAddr = inetAddress.getHostAddress();
        // Filter network card No
        int index = ipAddr.indexOf('%');
        if (index > 0) {
            ipAddr = ipAddr.substring(0, index);
        }
        return ipAddr;
    }

    private static boolean isReservedAddr(InetAddress inetAddr) {
        if (inetAddr.isAnyLocalAddress() || inetAddr.isLinkLocalAddress()
                || inetAddr.isLoopbackAddress()) {
            return true;
        }
        return false;
    }
}

 将原DDNS类中的


String currentHostIP = ddns.getcurrentHostIp();


注释掉,换成

String currentHostIP = null;
try {
    currentHostIP = getIPv6.getLocalIPv6Address();
} catch (IOException e) {
    e.printStackTrace();
}
if (currentHostIP==null){
    return ;
}

最后注意设置解析类型

8.打包

点击右上角添加配置

spring boot ip spring boot ipv6_java_15

 点击左上角加号,添加一个maven,名称随便写,在命令行里面输入“clean compile package -Dmaven.test.skip=true”,然后确定

spring boot ip spring boot ipv6_java_16

 然后运行这个maven,就会自动清除之前的版本并且打包



 这里会显示jar包所在的位置,将它传到服务器上并输入命令“nohup java -jar jar包路径 &”

例如:nohup java -jar /yzero/pnonedns-0.0.1-SNAPSHOT.jar &

然后回车两次。

它会默认启动在服务器8080端口,如果你的这个端口在用,可以通过resource文件夹下的application.properties文件修改端口

# 应用服务 WEB 访问端口
server.port=8090

记得在服务器端放行端口!! 

不出意外的话定时任务已经可以运行了,如果程序判断当前设备的地址与dns的记录一致的话是不会执行更新指令的,所以阿里云不会显示执行日志,只有修改记录才会留下日志,亲测用手机装linux deploy App做成的服务器不能执行自带的crontab定时任务,但这个可以。

9.添加手动更新(非必需)

再创建一个类,给他类上面添加@Controller注解,然后在类中添加以下代码

@GetMapping("/ddns")
    @ResponseBody
    //手动实现一次动态域名解析更新
    public String goDDNS(){
        DDNS.go();
        return "已向dns服务商发起了一次dns记录更新操作";
    }

然后在浏览器访问服务器地址:端口号/ddns,就可以实现一次手动更新,这里只要能连到服务器就行,ipv4,ipv6,域名访问都可以

例如 http://192.168.1.199:8090/ddns

10.最后

我将我遇到几乎所有短时间解决不了的问题都列在了这里,但还有许多情况是我想不到的,请善用各类搜索引擎,如果要做ipv4和v6双解析,将代码复制一份,修改一下解析类型和地址获取,换个名字,在定时任务里面都加上即可。