通過 DDNS 解決寬帶撥號 ip 變化問題


前面你的文章我已經寫了 寫了 DMZ 內網映射的 方式。 這樣內網主機已經暴露在外網中了。 但是 撥號上網我們的ip是 會變化的。大概規律就是 每次撥號都會變化。如果不撥號,每 24 小時 ip也會自動變化一次。

怎么解決呢? 那就是使用域名。 我們通過域名 來訪問 這台機子。並且在 ip 變化的時候 ,讓 讓域名對應的ip 也跟着變化。 這個過程叫做 DDNS 。就是動態域名解析。

 

DDNS 很多地方都有提供 。阿里有。騰訊雲也有。我目前有的域名是騰訊的。所以就用騰訊 實現好了。首先找到騰訊 yun api。

 

這個接口就是給我們 修改 域名和ip對應關系的。 所有我們只需要獲取到本地的外網ip然后調用這個接口 就可以了。 

 

我的實現方式 是通過 java 程序 。每隔一段時間取獲取本地ip,和上一次的ip做比較,如果不一樣,就 調用騰訊雲的接口。並且把這個程序加入到開機啟動。

 

代碼實現:

package com.sbl.pay.subaccount;

public class DDNSParam {
    
    
    public String Action = "RecordModify";
    public Long Nonce = (long) (Math.random()*10000);
    //public String Region = "ap-chengdu";
    public Long Timestamp = System.currentTimeMillis()/1000;
    public String SecretId = "填你自己的id";
    public String SignatureMethod = "HmacSHA1";
    public String Signature = "";
    
    
    
    
    
    
    public String domain = "zhangyukun.club";
    public int recordId  = 380731049;
    public String subDomain = "home";
    public String recordType = "A";
    public String recordLine = "默認";
    public String value = "112.193.146.167";
    
    
    
    
    public String getDomain() {
        return domain;
    }
    public void setDomain(String domain) {
        this.domain = domain;
    }
    public String getRecordLine() {
        return recordLine;
    }
    public void setRecordLine(String recordLine) {
        this.recordLine = recordLine;
    }
    public String getRecordType() {
        return recordType;
    }
    public void setRecordType(String recordType) {
        this.recordType = recordType;
    }
    public String getSubDomain() {
        return subDomain;
    }
    public void setSubDomain(String subDomain) {
        this.subDomain = subDomain;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getAction() {
        return Action;
    }
    public void setAction(String action) {
        Action = action;
    }
    public Long getNonce() {
        return Nonce;
    }
    public void setNonce(Long nonce) {
        Nonce = nonce;
    }
    public Long getTimestamp() {
        return Timestamp;
    }
    public int getRecordId() {
        return recordId;
    }
    public void setRecordId(int recordId) {
        this.recordId = recordId;
    }
    public void setTimestamp(Long timestamp) {
        Timestamp = timestamp;
    }
    public String getSecretId() {
        return SecretId;
    }
    public void setSecretId(String secretId) {
        SecretId = secretId;
    }
    public String getSignatureMethod() {
        return SignatureMethod;
    }
    public void setSignatureMethod(String signatureMethod) {
        SignatureMethod = signatureMethod;
    }
    public String getSignature() {
        return Signature;
    }
    public void setSignature(String signature) {
        Signature = signature;

    }

}

 

package com.sbl.pay.subaccount;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import com.sbl.pay.subaccount.util.BeanUtils;
import com.sbl.pay.subaccount.util.Core;
import com.sbl.pay.subaccount.util.HttpUtils;

public class Main {

	public static void main(String[] args) {
		
		String url = "https://cns.api.qcloud.com/v2/index.php";

		Map<String, String> params = new HashMap<String, String>();

		DDNSParam param = new DDNSParam();
		
		String urlStr = Core.createLinkString(   BeanUtils.objectToMap( param ) );
		urlStr = "GETcns.api.qcloud.com/v2/index.php?" + urlStr;
		
		String signature = hmacSha1(urlStr, "你的密鑰" );
		param.setSignature( signature  );
		params = BeanUtils.objectToStringMap(param);

		String s = HttpUtils.get(url, params);
		System.out.println(s);
		
	}

	public static String hmacSha1(String src, String key) {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(key.getBytes("utf-8"), "HmacSHA1");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(signingKey);
            byte[] rawHmac = mac.doFinal(src.getBytes("utf-8"));
            return Base64.getEncoder().encodeToString( rawHmac );
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

  

結果 : {"code":0,"message":"","codeDesc":"Success","data":[]}

 

 

下面就是 獲取公網ip:  中秋 有空 ,所以搞了一下獲取公網IP。百度搜索IP。頁面會顯示你的公網IP 。所以把這個拔下來就可以了。 如果 你覺得百度 公網Ip 不正確 。那么你可以拔你們家路由器管理界面的。

package com.sbl.pay.subaccount;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;

import org.apache.commons.io.IOUtils;
import org.htmlparser.Parser;
import org.htmlparser.filters.AndFilter;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

public class IPGet {

	public static void main(String[] args) throws Exception {
		System.out.println( getPublicNetworkIP() );
	}

	/**
	 * 得到公網IP
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws ParserException
	 */
	public static String getPublicNetworkIP() throws FileNotFoundException, IOException, ParserException {
		Parser parser = new Parser( new URL("https://www.baidu.com/s?ie=UTF-8&wd=ip").openConnection() );

		String a = IOUtils.toString(new FileInputStream(new File("C:\\Users\\ZHANGYUKUN\\Desktop\\aaa.html")));

		parser.setInputHTML(a);

		AndFilter filter = new AndFilter(new TagNameFilter("span"), new HasAttributeFilter("class", "c-gap-right"));

		NodeList nodeList = parser.parse(filter);

		String ipStr = nodeList.elementAt(0).getChildren().elementAt(0).getText() ;
		ipStr = ipStr.replaceAll("本機IP: ", "");
		return ipStr;
	}

}

  

結果如下:

獲取公網IP和 修改IP的接口都搞定了。那么后面就是 吧 這個程序結合起來做成開機啟動就可以了

 參考一篇別人的文章。吧jar 做成啟動服務。https://blog.csdn.net/razeSpirit/article/details/78046475

 

 

 

上面的都是 實現原理。現在說一個簡單的方式。檢查一下你的路由器里面有沒有關於ddns 的設置。

我用的小米路由器。正好有這個設置。

 

 

 

 

 

 

 

 

說明一下 。如果使用花生殼的話,那么這里只能使用花生殼的 殼域名。親測我的騰訊域名不能用。估計只能域名提供商才能向 dns 服務商修改域名和ip的對應關系吧。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM