IPV6 阿里DDNS

IPV6 阿里DDNSIPV6阿里DDAS因为需要在家搭建一套环境,并且需要公网能访问。国内的ipv4的地址,各大运营商基本都不会分配ipv4地址(电信宽带好像有地方可以,但是听说很贵),而且是动态的,每过段时间就会改变。发现移动宽带的公网ipv6地址是可以获取到的,但是也会动态刷新。想稳定访问就加上阿里的ddns的域名访问。###1.准备工作因为宽带接入家里基本是都是需要通过光猫拨号后,再接入路由器。这样就拿不到真实的公网ipv6地址,需要先将光猫中的设置改为桥接模式,再让路由器输入宽带账户和密码拨号。这个过程我调

大家好,又见面了,我是你们的朋友全栈君。

IPV6 阿里DDNS

因为需要在家搭建一套环境,并且需要公网能访问。国内的ipv4的地址,各大运营商基本都不会分配ipv4地址(电信宽带好像有地方可以,但是听说很贵),而且是动态的,每过段时间就会改变。
  发现移动宽带的公网ipv6地址是可以获取到的,但是也会动态刷新。想稳定访问就加上阿里的ddns的域名访问。
  有时候电脑的mac地址在路由器注册上,公网会访问不了。我也不知道是什么原因。但是晚上凌晨4点或者5点时候定时重启路由器,基本上就没问题。

1.改光猫信息和设置路由器拨号

因为宽带接入家里基本是都是需要通过光猫拨号后,再接入路由器。这样就拿不到真实的公网ipv6地址,需要先将光猫中的设置改为桥接模式,再让路由器输入宽带账户和密码拨号。
  改光猫和路由器这个步骤,确实很多坑,需要看网上的很多教程。光猫的型号和地区不一样,设置的方式也不一样,所以这一步就不详细介绍。

2.准备阿里云域名和获取阿里开发AccessKeyID和AccessKeySecret

2.1 准备域名

注册一个阿里云账号,购买域名,可以买个比较便宜的一级域名。购买完成后
在这里插入图片描述
在这里插入图片描述
购买以后需要看看dns服务器设置是否成功。阿里免费的ddns解析,修改ip后,大概10分钟左右生效。
然后进入左侧的 “域名解析” 菜单
在这里插入图片描述
主机记录是二级域名前缀,@表示是主域名
记录类型 A是ipv4地址 AAAA是ipv6地址
TTL 生效时间

2.2 获取阿里开发AccessKeyID和AccessKeySecret

在这里插入图片描述

3.开始脚本项目

3.1 引入阿里的sdk包

引入阿里现成的maven包,里面封装好的接口

 <dependencies>
        <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>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.12</version>
        </dependency>
    </dependencies>

3.2 加载配置信息

域名,AccessKeyID和AccessKeySecret

初始化下配置信息

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

import java.io.*;
import java.nio.charset.StandardCharsets;


public class Config { 
   
    //这读取的是json文件配置,也可以直接输入域名,AccessKeyID,和AccessKeySecret
    public static  String host="";

    public static  String AccessKeyID="";

    public static  String AccessKeySecret="";

    public static void initConfig(){ 
   
        if(StrUtil.isNotBlank(host) && StrUtil.isNotBlank(AccessKeyID) && StrUtil.isNotBlank(AccessKeySecret)){ 
   
            LogUtil.logOut("host:"+host);
            LogUtil.logOut("AccessKeyID:"+AccessKeyID);
            LogUtil.logOut("AccessKeySecret:"+AccessKeySecret);
            return;
        }
        String jarPath= System.getProperty("user.dir");
        System.out.println(jarPath);
        File file=new File(jarPath+File.separator+"config.json");

        if(!file.exists()){ 
   
            LogUtil.logOut("initConfig config.json文件不存在");
            return;
        }
        JSONObject json= JSONUtil.readJSONObject(file, StandardCharsets.UTF_8);
        String host=json.getStr("host");
        String AccessKeyID=json.getStr("AccessKeyID");
        String AccessKeySecret=json.getStr("AccessKeySecret");
        if(StrUtil.isBlank(host) || StrUtil.isBlank(AccessKeyID) || StrUtil.isBlank(AccessKeySecret)){ 
   
            LogUtil.logOut("参数配置出现问题!!!!!!!!");
            throw new RuntimeException("参数配置出现问题!!!!!!!!");
        }
        Config.host=host;
        Config.AccessKeyID=AccessKeyID;
        Config.AccessKeySecret=AccessKeySecret;
    }
}


3.3 获取服务器ipv6地址



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** * @author liu * @time 2021/11/1 * @description */
public class IPv6 { 
   
    public static void main(String[] args) throws IOException { 
   
        /*获取本机所有ip地址(包括保留地址,ipv4,ipv6 如果安装了虚拟机会更多其他的地址) * try { InetAddress ads = null; Enumeration<NetworkInterface> adds = NetworkInterface.getNetworkInterfaces(); while(adds.hasMoreElements()) { Enumeration<InetAddress> inetAds = adds.nextElement().getInetAddresses(); while(inetAds.hasMoreElements()) { ads = inetAds.nextElement(); LogUtil.logOut(ads.getHostAddress()); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }*/

        //获取可用ipv6地址
// try { 
   
// LogUtil.logOut(getLocalIPv6Address());
// } catch (SocketException e) { 
   
// // TODO Auto-generated catch block
// e.printStackTrace();
// }


// LogUtil.logOut(l);
        
        getLocalIPv6Address();

    }
    public static String getLocalIPv6Address() throws SocketException { 
   
        InetAddress inetAddress =null;

        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
        outer:
        while(networkInterfaces.hasMoreElements()) { 
   
            Enumeration<InetAddress> inetAds = networkInterfaces.nextElement().getInetAddresses();
            while(inetAds.hasMoreElements()) { 
   
                inetAddress = inetAds.nextElement();
                //检查此地址是否是IPv6地址以及是否是保留地址
                if(inetAddress instanceof Inet6Address&& !isReservedAddr(inetAddress)) { 
   
                    break outer;

                }
            }
        }
        String ipAddr = inetAddress.getHostAddress();
        //过滤网卡
        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;
    }

    public static boolean ping(String ipAddress, int pingTimes) { 
   
        BufferedReader in = null;
        // 将要执行的ping命令,此命令是windows格式的命令
        Runtime r = Runtime.getRuntime();
        //String pingCommand = "ping " + ipAddress + " -n " + pingTimes + " -w " + timeOut;
        String pingCommand = "ping6 " + ipAddress +" -c " +pingTimes;

        try { 
      // 执行命令并获取输出
            LogUtil.logOut(pingCommand);
            Process p = r.exec(pingCommand);
            if (p == null) { 
   
                return false;
            }
            // 逐行检查输出,计算类似出现=23ms TTL=62字样的次数
            in = new BufferedReader(new InputStreamReader(p.getInputStream()));
            int connectedCount = 0;
            String line = null;
            while ((line = in.readLine()) != null) { 
   
                connectedCount += getCheckResult(line);
            }   // 如果出现类似=23ms TTL=62这样的字样,出现的次数=测试次数则返回真
            return connectedCount >= pingTimes;
        } catch (Exception ex) { 
   
            ex.printStackTrace();   // 出现异常则返回假
            return false;
        } finally { 
   
            try { 
   
                in.close();
            } catch (IOException e) { 
   
                e.printStackTrace();
            }
        }
    }


    /** * 若line含有=18ms TTL=16字样,说明已经ping通,返回1,否則返回0. */
    private static int getCheckResult(String line) { 
   
        LogUtil.logOut("控制台输出的结果为:"+line);
        String[] lines=line.split("=");
        String lessStr=lines[lines.length-1].split(" ")[0];
        try { 
   

            if(line.contains("Unreachable")){ 
   
                return 0;
            }
            if(line.contains("unreachable")){ 
   
                return 0;
            }
            if(Double.valueOf(lessStr)>0){ 
   
                return 1;
            }
        }catch (Exception e){ 
   
            return 0;
        }
        return 0;
    }


}

3.4 main启动类

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.alidns.model.v20150109.*;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;


import java.io.IOException;
import java.net.SocketException;

import java.util.List;

public class DDNS { 
   

    /** * 获取主域名的所有解析记录列表 */
    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();
        }
    }

    /** * 修改解析记录 */
    private AddDomainRecordResponse addDomainRecord(AddDomainRecordRequest request, IAcsClient client) { 
   
        try { 
   
            // 调用SDK发送请求
            return client.getAcsResponse(request);
        } catch (ClientException e) { 
   
            e.printStackTrace();
            // 发生调用错误,抛出运行时异常
            throw new RuntimeException();
        }
    }



    public static void main(String[] args) throws InterruptedException, IOException { 
   
        Config.initConfig();
        // 设置鉴权参数,初始化客户端
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou",// 地域ID
                Config.AccessKeyID,// 您的AccessKey ID
                Config.AccessKeySecret);// 您的AccessKey Secret
        IAcsClient client = new DefaultAcsClient(profile);
        while (true) { 
   
            try { 
   
                ddnsOp(client);
            } catch (Exception e) { 
   
                e.printStackTrace();
                LogUtil.logOut(e);
            }finally { 
   
                //这直接sleep 5分钟。这个时间可以调大些。
                Thread.sleep(1000 * 300);
            }
        }
    }

    private static void ddnsOp(IAcsClient client) throws SocketException { 
   
        DDNS ddns = new DDNS();

        //查询指定二级域名的最新解析记录
        DescribeSubDomainRecordsRequest describeSubDomainRecordsRequest = new DescribeSubDomainRecordsRequest();
        describeSubDomainRecordsRequest.setSubDomain(Config.host);
        DescribeSubDomainRecordsResponse describeSubDomainRecordsResponse = ddns.describeSubDomainRecords(describeSubDomainRecordsRequest, client);
        LogUtil.log_print("describeSubDomainRecords", describeSubDomainRecordsResponse);

        List<DescribeSubDomainRecordsResponse.Record> domainRecords = describeSubDomainRecordsResponse.getDomainRecords();
        //最新的一条解析记录
        if (domainRecords.size() != 0) { 
   

            DescribeSubDomainRecordsResponse.Record record = domainRecords.get(0);
            // 记录ID
            String recordId = record.getRecordId();
            // 记录值
            String recordsValue = record.getValue();
            // 当前主机公网IP
            String currentHostIP = IPv6.getLocalIPv6Address();
            LogUtil.logOut("-------------------------------当前主机公网IP为:" + currentHostIP + "-------------------------------");
            if (!currentHostIP.equals(recordsValue)) { 
   
                LogUtil.logOut("与记录不一致,尝试修改地址!");
                // 修改解析记录
                UpdateDomainRecordRequest updateDomainRecordRequest = new UpdateDomainRecordRequest();
                // 主机记录
                updateDomainRecordRequest.setRR("@");
                // 记录ID
                updateDomainRecordRequest.setRecordId(recordId);
                // 将主机记录值改为当前主机IP
                updateDomainRecordRequest.setValue(currentHostIP);
                // 解析记录类型
                updateDomainRecordRequest.setType("AAAA");
                UpdateDomainRecordResponse updateDomainRecordResponse = ddns.updateDomainRecord(updateDomainRecordRequest, client);
                LogUtil.log_print("updateDomainRecord", updateDomainRecordResponse);
            }
        }else{ 
   

            // 当前主机公网IP
            String currentHostIP = IPv6.getLocalIPv6Address();
            LogUtil.logOut("-------------------------------当前主机公网IP为:" + currentHostIP + "-------------------------------");
            AddDomainRecordRequest addDomainRecordRequest=new AddDomainRecordRequest();
            addDomainRecordRequest.setDomainName(Config.host);
            addDomainRecordRequest.setRR("@");

// // 修改解析记录
// UpdateDomainRecordRequest updateDomainRecordRequest = new UpdateDomainRecordRequest();
// // 主机记录
// updateDomainRecordRequest.setRR("@");
// // 记录ID
// updateDomainRecordRequest.setRecordId(recordId);
            // 将主机记录值改为当前主机IP
            addDomainRecordRequest.setValue(currentHostIP);
            // 解析记录类型
            addDomainRecordRequest.setType("AAAA");
            AddDomainRecordResponse updateDomainRecordResponse = ddns.addDomainRecord(addDomainRecordRequest, client);
            LogUtil.log_print("updateDomainRecord", updateDomainRecordResponse);
        }
    }
}

3.5 config.json配置文件

***这个配置文件需要和jar包同级目录***
  { 
   
	"host":"ljXXXX.top",
	"AccessKeyID":"LTAI5tPXXXXXXX",
	"AccessKeySecret":"FhkXXXXXX"
}

3.6 日志输出


import com.google.gson.Gson;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;


/** * @author fancy */
public class LogUtil { 
   
    private static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
    public static void logOut(Object info){ 
   
        String threadName=Thread.currentThread().getName();
        System.out.println(dtf.format(LocalDateTime.now())+"--线程名"+threadName+":::"+info);
    }
    public static void log_print(String functionName, Object result) { 
   
        Gson gson = new Gson();
        LogUtil.logOut("-------------------------------" + functionName + "-------------------------------");
        LogUtil.logOut(gson.toJson(result));
    }
}

3.7 启动脚本和stop脚本

aliDDns.sh 启动

#!/bin/bash

java -cp aliDDns-1.0-SNAPSHOT.jar DDNS start  > log.file  2>&1 &

echo "开始解析"

stop.sh 停止

PROCESS=`ps -ef|grep aliDDns|grep -v grep|grep -v PPID|awk '{ print $2}'`
for i in $PROCESS
do
  echo "Kill the $1 process [ $i ]"
  kill -9 $i
done

总结

如果不是做java研发,这个脚本跑起来有点难。这个是打包好的DDNS ipv6
如果没有积分可留言
代码地址源码

声明:该项目只是做个人学习使用,并未将域名暴露他人。网友其他行为与本人无关!!!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/130382.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java中如何定义一个数组「建议收藏」

    java中如何定义一个数组「建议收藏」数组的定义方法 int[]a;//定义一个数组a int[]b=newint[10];//定义一个长度为10的数组b int[]c={7,1,2,3,8};//定义一个数组c,并赋值,其中a[0]=7,a[4]=8; //以数组b为例,长度为10,分别是从b[0]-b[9];…

    2022年7月7日
    16
  • Ubuntu 12.04下SimpleScalar_PISA 的安装

    Ubuntu 12.04下SimpleScalar_PISA 的安装(1)首先准备需要的安装文件,如果没有可到以下地址下载:simpletools‐2v0.tgz:http://www.simplescalar.com/tools.htmlsimplesim‐3v0d‐with‐cheetah.tar.gz:http://www.ict.kth.se/courses/IS2202/softwaresimpleutils‐990811.tar.

    2022年6月5日
    30
  • strictmode android,Android 应用性能优化-StrictMode(严格模式)

    strictmode android,Android 应用性能优化-StrictMode(严格模式)UI线程如果被阻塞5秒的话,那么应用程序此时就会弹出ANR的对话框,ANR对应用程序来说是一个很严重的问题。如何防止应用程序出现ANR,怎么分析查看导致ANR问题的原因?我们来介绍Android的严格模式。怎样开启严格模式有两种开启方式。开发者选项进入开发者选项,里面找到启用严格模式,打开。当应用主线程执行长时间操作的话会闪锁屏幕。StrictModeAPI(代码调用)可以在Activit…

    2022年5月25日
    35
  • 进销存管理系统【源码开放】[通俗易懂]

    进销存管理系统【源码开放】[通俗易懂]进销存管理系统的功能需求:1,实现采购订单的持久化,对采购商品入库处理,还有就是采购的退货处理;2,实现商品的入库、出库操作,查询商品的库存信息,修改商品的仓库号3,实现销售订单的添加,销售发货处理,并且销售的退货处理4,实现新建员工培训信息和查询员工培训记录功能5,实现对商品、供应商、客户资料的管理,对员工用户的管理,最重要的是对系统数据的备份和恢复代码的截图如下所示:系统的截图如下所示:bean层manage的代码如下所示:packag.

    2022年5月31日
    27
  • java培训达内学费[通俗易懂]

    java培训达内学费[通俗易懂]达内教育Java培训费用是多少钱?哪个机构好?根据目前的行情来看,Java培训费用大概在1-3万左右,每个人根据个人不同的基础决定学习的课程,有些人基础差点的,学习的是基础课程,费用相对低一点。除了关心Java培训费用是多少钱我们还会关心学习的周期,具体要学习多久呢?一般来说Java培训的时间是4个月左右,具体看个人学习情况,如果学习学的好,那么就4个月就能毕业了,如果是觉得学习完了后自己还是不太了解,那么可以留级,免费在学习一遍,为自己去面试在铺垫一下。Java培训哪个机构好?达内达内的特色是..

    2022年7月8日
    44
  • Android 加载串口通信读取信息时 AndroidStudio loadLibrary失败「建议收藏」

    Android 加载串口通信读取信息时 AndroidStudio loadLibrary失败「建议收藏」static{ System.loadLibrary(“serial_port”); }今天想连接串口做一个新功能但是连接串口加载库的时候总是找不到serial_port库1:项目结构是这样的库文件不多说github很多Android.mk##Copyright2009CedricPriscal##LicensedundertheApacheLicense,Version2.0(the”License”);#you…

    2022年7月15日
    17

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号