利用IPV6搭建一个家庭服务器

1.1. 序言

众所周知,中国移动宽带没有给家庭用户分配一个ipv4的公网账号,但是会给一个动态的公网IPV6账号,我们接下来就用这个IPV6搭建一个家庭服务器了

1.2. 查看公网IPV6信息

 1.2.1. 打开cmd查看IPV6信息

在cmd中使用命令`ipconfig`查看IPV6,可以看到有一个临时 IPV6 地址

利用IPV6搭建一个家庭服务器

为了验证我的猜想是正确的,我们打开网站 (https://test-ipv6.com/index.html.zh_CN%20) ,此处可使用各类测试ipv6测试网站

利用IPV6搭建一个家庭服务器

上方显示我是有IPV6公网IP的

需要提醒:如果你用的是移动宽带,且还是没法得到IPV6地址,可能原因是你的路由器不支持IPV6协议,此时需要将电脑网线直连到光猫上,进行测试IPV6是否可以获取

1.2.2. 购买腾讯云或者阿里云域名

可以在域名商城购买一些比较便宜的域名,当然购买域名后需要进行实名认证等,会有一些步骤

利用IPV6搭建一个家庭服务器

1.2.3. 配置域名

上述步骤完成后,可在工作台,域名列表中所购买的域名信息了

利用IPV6搭建一个家庭服务器

将域名和IPV6地址进行绑定,绑定完成后,即可使用域名访问自己的主机了

利用IPV6搭建一个家庭服务器

访问测试主机,如果能ping通,则代表配置成功

利用IPV6搭建一个家庭服务器

需要提醒:阿里云或者腾讯云dns配置完成后需要等待一段时间使配置生效,在此期间可能无法ping通主机;此外因为IPV4和IPV6协议不兼容,因此如果想让其它电脑也能测试,需要保证其它电脑也有独立的IPV6地址,一般情况下,手机使用**移动数据网络**时其有IPV6地址,可用手机进行测试,或者手机开热点给笔记本进行测试,这说目前尚未解决的问题。

1.2.4. 动态域名绑定

因为前面提到的家庭IPV6地址是变动的,我们不可能每隔一段时间就配置一次域名,这样太麻烦了,此时我们可以使用阿里云或者腾讯云提供的SDK进行动态修改域名配置信息

利用IPV6搭建一个家庭服务器

1.2.5. 获取本机IPV6地址

判断获取的ipv6是否发生变化


 /**
     * @return 如果ip发生改变,返回true  如果没有则false
     */
    public static boolean getIpV6ChangeStatus() {
        boolean startLineFlag = false;

        //判断服务器类型
        OsInfo osInfo = SystemUtil.getOsInfo();
        if (osInfo.isWindows()) {
            List<String> list = RuntimeUtil.execForLines("ipconfig");
            for (int i = 0; i < list.size(); i++) {
                String line = list.get(i);
                if (StrUtil.isEmpty(line)) {
                    continue;
                }
                if (StrUtil.contains(line, IP_ADAPTER_NAME)) {
                    startLineFlag = true;
                    continue;
                }

                if (startLineFlag) {
                    if ((!StrUtil.contains(line, ". . :")) && startLineFlag) {
                        break;
                    }
                    List<String> splitList = StrUtil.split(line, ". . :");
                    if (CollUtil.isEmpty(splitList)) {
                        continue;
                    }
                    if (splitList.size() < 2) {
                        continue;
                    }
                    String name = splitList.get(0);
                    String value = splitList.get(1);
                    if (name.contains("临时 IPv6 地址")) {
                        if (currentIp.equalsIgnoreCase(value)) {
                            //IP地址没有改变,不用更新
                            return false;
                        } else {
                            //IP改变
                            currentIp = value;
                            return true;
                        }
                    }
                }
            }
        }

        if (osInfo.isLinux()) {
            //直接获取第四行数据
            List<String> list = RuntimeUtil.execForLines("ifconfig");
            if (CollUtil.isEmpty(list) || list.size() < 4) {
                System.err.println("从linux上获取ipv6地址失败");
                return false;
            }
            String ipv6Line = list.get(3);
            if (ipv6Line.contains("inet6") && ipv6Line.contains("global")) {
                ipv6Line = ipv6Line.trim();
                ipv6Line = StrUtil.removePrefix(ipv6Line, "inet6 ");
                ipv6Line = StrUtil.removeSuffix(ipv6Line, "  prefixlen 64  scopeid 0x0<global>");
                if (currentIp.equalsIgnoreCase(ipv6Line)) {
                    //IP地址没有改变,不用更新
                    return false;
                } else {
                    //IP改变
                    currentIp = ipv6Line;
                    return true;
                }
            }
        }

        return false;
    }

获取电脑或者服务器上的IPV6地址信息

    public static String getCurrentIp() {
        if (StrUtil.isEmpty(currentIp)) {
            getIpV6ChangeStatus();
        }
        return currentIp;
    }

将ipv6地址发送钉钉上

 /**
     * 发送ipv6到dingding
     *
     * @param ip
     */
    public static void sendIPToDingDing(String ip) {
        JSONObject root = new JSONObject();
        root.set("msgtype", "text");

        JSONObject object = new JSONObject();
        object.set("content", "我的IP是:" + ip);

        root.set("text", object);

        HttpRequest.post(WEB_HOOK_URL)
                .header("Content-Type", "application/json; charset=utf-8")
                .body(root.toString())
                .execute()
                .body();
    }

开启定时任务,如果ipv6地址发生变化,将消息发送到dingding和修改aliyun上的dns信息

public static void getIpV6Server() {
        ThreadUtil.execute(() -> {
            while (true) {
                boolean changeFlag = getIpV6ChangeStatus();
                //ip发生改变,把改变的发送到钉钉
                if (changeFlag) {
                    //将消息发送到钉钉上
                    sendIPToDingDing(getCurrentIp());

                    //将消息同步到aliyun上
                    IAcsClient client = AliyunDnsUtils.getIAcsClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET);
                    String recordId = AliyunDnsUtils.uploadIpv6ToAliyun(client, getCurrentIp(), DOMAIN_NAME);
                    System.err.println("更新完成...");
                }

                ThreadUtil.sleep(1000 * 60);
            }
        });
    }
上一篇:Java输入输出流


下一篇:ECS使用感受