Dynamic DNS resolution of home broadband using Tencent cloud API Explorer Based on python

abstract

Firstly, it introduces the application background: it is used to make the domain name correspond to the dynamic IP correctly. Then it introduces the API interfaces needed to complete this function, and simply implements the corresponding API interface call framework. Finally, in order to use more concise, the program logic is further optimized. Practice proves that truth is in practice!

introduction

As we all know, the general home broadband is that many lines share one exit IP. However, for Telecom broadband, due to the large number of Telecom IP, it is an excuse to apply for public IP by installing home cameras. However, in order to prevent users from using IP to build indescribable services at home, the public network IP given by Telecom is generally dynamic IP, and port 804438080 is blocked. According to the author's observation, the broadband export IP is changed every three days, that is, every 72 hours. At the same time, if the light cat at home restarts within three days, or encounters an accident of power failure and then calls, the IP address will also change. Therefore, when using home broadband to provide Internet services, the first thing to be solved is the problem of changing IP address.

At present, there are many dynamic domain name resolution services (DDNS) on the market, that is, modify the A record of the corresponding domain name on the public name server in real time according to your current IP address, so that users can correctly reach your server address when accessing your domain name. More famous are:

  1. Ali DDNS (same principle as this article)
  2. Peanut shell (intranet penetration, content exchange through third-party server)
  3. 3322 (free secondary domain name)
  4. FreeDDns (free secondary domain name)
  5. WingDNS (full function!)
  6. Meibu (secondary domain name is free, top-level domain name is charged)

It can be seen from the market research that the market related to DDNS has been quite mature and users tend to be saturated. Therefore, this paper is suitable for students who do not want to use the services of the above platform providers but like DIY fooling around. As can be seen from the search results of cloud + community (as shown in the figure below), the community has not taught you how to realize dynamic domain name resolution. Therefore, the main purpose of this paper is to use python to realize free dynamic domain name resolution. Because the cloud API function of Tencent cloud improves development efficiency, the development artifact of cloud API is worthy of further promotion.

Implementation method

stores reserve

First, you need to have a domain name resolved on Tencent cloud (I really have only one), as shown in the figure below:

Then click the avatar in the upper right corner to enter the API key page, as shown in the following figure:

Just find the ID and Key corresponding to APPID in Tencent cloud API Key interface, as shown in the figure below:

Keep your Key for future use! In this paper, the secret ID is used in place of the secret ID; In all places where the secret Key appears, the Key is used instead.

Assumptions of the whole process

All experimental methods and results in this paper are based on the following assumptions:

  1. Suppose your current IP is the one that needs to be dynamically resolved
  2. It is assumed that the target domain name has been filed and will not be blocked
  3. It is assumed that the reader has a certain ability to write python
  4. It is assumed that readers are familiar with the nouns in this article

DDNS request framework based on API Explorer

First, log in to Tencent cloud and check the relevant documents of DNSPod. The document address is: https://cloud.tencent.com/document/product/1427/56194 . It lists a series of related interfaces. We may need to use the following related API interfaces, as shown in the table below:

API name

describe

Get the resolution record of the domain name

Add record

Modify record

Update dynamic DNS records

My understanding is that the third interface is a combination of the first interface and the second interface: first obtain the existing resolution list, and then find out whether there is a resolution record for the corresponding subdomain name. If so, modify the record value of the subdomain name. If not, add a new record. The third interface is implemented in combination with Tencent cloud API explorer. The address of cloud API Explorer is: ModifyDynamicDNS . The operation interface is shown in the figure below:

Observe the necessary parameters and find that one parameter RecordId is the ID to be modified. This parameter is obtained through the DescribeRecordList interface. If I need to modify the existing records directly, record the ID that needs to be modified, and then call the ModifyDynamicDNS interface. If you need to create a new record and dynamically update the created record value, you can first use the CreateRecord interface to record the created record ID and directly use it in the modifydynamicdns interface.

This example is to dynamically modify existing records. Therefore, the dynamic domain name resolution capability is realized by combining the DescribeRecordList interface and ModifyDynamicDNS interface. First from DescribeRecordList On the interface document page, enter the API Explorer interface and configure relevant parameters, as shown in the following figure:

After configuring the parameters, the corresponding request code will be generated on the right. This example tutorial uses the Python SDK, so copy the Python code locally and create a DDNS.py file, as shown in the following figure:

Tencent cloud.common, a public request module of Tencent cloud, can be installed via pip command. Document address: python SDK , the installation command is as follows:

$ pip install --upgrade tencentcloud-sdk-python

We change the "secret ID" and "secret Key" in line 9 of the above figure to the ID and Key we saved before, and directly run to get a lot of JSON. Here we show some properties of the Response object returned normally:

"Response": {
  "RequestId": "a3bee0a2-bac6-43db-b76d-a4ce11cec0c7",
  "RecordCountInfo": {
    "SubdomainCount": 23,
    "TotalCount": 23,
    "ListCount": 23
  },
  "RecordList": [
    {
      "Value": "59.52.241.247",
      "Status": "ENABLE",
      "UpdatedOn": "2021-08-13 20:03:43",
      "Name": "homesource",
      "Line": "default",
      "LineId": "0",
      "Type": "A",
      "Weight": null,
      "MonitorStatus": "",
      "Remark": "",
      "RecordId": 760223447,
      "TTL": 600,
      "MX": 0
    }
  ]
}

The record named homesource is the record we need to update, and the corresponding RecordId is 760223447. We save this value for standby.

Then do the same and substitute the obtained RecordId into the ModifyDynamicDNS interface. The API Explorer address of the interface is: ModifyDynamicDNS As shown in the figure below:

After testing, it is found that the SubDomain parameter should be required. If this parameter is not added, the interface will modify the parameter value of @ host record by default. Copy the generated code locally, remove the duplicate modules, and import the rest, as shown in the following figure:

Replace your ID and Key with "secret ID" and "secret Key" in the code and directly run the code. The request result is as follows:

{
  "RecordId": 760223447,
  "RequestId": "2542afb0-bc7c-4c2e-b864-ca1d73795cdf"
}

Go back to DNSPod console to view API operation results, as shown in the following figure:

It can be seen that the value of the record has been successfully modified to 127.0.0.1. In practical application, the IP address can be modified to other IP addresses. The DDNS request framework based on API Explorer has been built. The following is further optimized based on the progressive application mode.

Automatic domain name resolution based on DDNS request framework

Because the current content has only a simple framework, more content needs to be added in order to make it easier to use.

Automatically get the RecordId of the specified subdomain name

In the above, we visually find the resolution record RecordId to be modified in a large number of resolution records. However, this method is inefficient. The implementation here automatically returns the specified sub domain name RecordId according to the request result.

Implementation logic:

  1. Declare a variable that specifies the host record value that needs to get RecordId
  2. Traverse the request result, find the record with the same Name as the specified host record, and return RecordId
  3. The module is functionalized for easy calling

The modified code for obtaining the record list of the domain name is changed as follows:

def ReturnRecordId(Domain, SubDomain):
    try:
        cred = credential.Credential(SecretId, SecretKey)
        httpProfile = HttpProfile()
        httpProfile.endpoint = "dnspod.tencentcloudapi.com"

        clientProfile = ClientProfile()
        clientProfile.httpProfile = httpProfile
        client = dnspod_client.DnspodClient(cred, "", clientProfile)

        req = models.DescribeRecordListRequest()
        params = {
            "Domain": Domain
        }
        req.from_json_string(json.dumps(params))

        resp = client.DescribeRecordList(req)
        for record in resp.RecordList:
            if record.Name == SubDomain:
                return record.RecordId
        print("No corresponding record value found, please create corresponding host record first!")
        return -2

    except TencentCloudSDKException as err:
        print("Failed to get the record list of domain name, please try again!")
        return -1

ModifyDynamicDNS interface is encapsulated into a function for easy calling

The encapsulated ModifyDynamicDNS function is as follows:

def ModifyDynamicDNS(RecordId, Domain ,SubDomain, Ip):
    try:
        cred = credential.Credential(SecretId, SecretKey)
        httpProfile = HttpProfile()
        httpProfile.endpoint = "dnspod.tencentcloudapi.com"

        clientProfile = ClientProfile()
        clientProfile.httpProfile = httpProfile
        client = dnspod_client.DnspodClient(cred, "", clientProfile)

        req = models.ModifyDynamicDNSRequest()
        params = {
            "Domain": Domain,
            "SubDomain": SubDomain,
            "RecordId": RecordId,
            "RecordLine": "default",
            "Value": Ip
        }
        req.from_json_string(json.dumps(params))

        resp = client.ModifyDynamicDNS(req)
        if str(RecordId) in resp.to_json_string():
            print("Update succeeded!")
        return 1
    except TencentCloudSDKException as err:
        return 0

Get the current IP address regularly

To realize dynamic DNS resolution, first obtain the current local public IP, and then submit the changed IP to the corresponding API. At present, there are many free public local IP query interfaces. Here we choose: https://ip.tool.lu/ , the results returned by this website are faster, but the results returned are not in standard JSON or other standard data formats, as shown below:

current IP: 59.52.217.194 Place of ownership: Nanchang, Jiangxi, China

Therefore, we first process the data and extract the IP address.

Then, after obtaining the IP address, compare it with the previous IP address to determine whether the IP has changed. If it has changed, submit the change through the API. IP check runs every other period of time to ensure that IP detection has no dead angle in all directions! Here, the regular expression and request module are used to complete the IP extraction method. The code is as follows:

import requests
import re 
def GetCurrentIP():
    resp = requests.get('https://ip.tool.lu/').content
    resp = resp.decode('utf8')
    IPPattern = '\d+.\d+.\d+.\d+' 
    matchObj = re.search(IPPattern, resp)
    return matchObj.group()

ip = GetCurrentIP()

Check whether the current IP is the same as the previous IP every once in a while. The time interval specified here is 10 minutes. The implementation code is shown in the figure below:

import time
interval = 600 # Check IP every 10 minutes
OldIP = ""
while True:
    CurrentIP = GetCurrentIP()
    if OldIP != CurrentIP:
        res = ModifyDynamicDNS(RecordId=RecordId, Domain=Domain, SubDomain=SubDomain, Ip = CurrentIP)
        if res:
            print(f'IP Successfully updated! primary IP:{OldIP},new IP:{CurrentIP}')
            OldIP = CurrentIP
        else:
            print('Dynamic domain name resolution API Something's wrong, trying again!')
            continue
    time.sleep(interval)

It can be seen from this logic that when the program runs for the first time, the original IP is not displayed, but when the IP is modified, the original IP can be displayed normally. Sort out the above IP update logic and update it to DDNS.py file. The main function code is as follows:

if __name__ == "__main__":
    SecretId = ""
    SecretKey = ""
    Domain = "eatrice.cn" # Primary domain name
    SubDomain = "homesource" # Specify the subdomain name to modify
    interval = 600 # Check IP every 10 minutes
    RecordId = ReturnRecordId(Domain=Domain, SubDomain=SubDomain)
    if RecordId == -1:
        print("RecordList There is a problem with the request!")
        exit()
    if RecordId == -2:
        print("The subdomain you want is not found. Please create a new one first!")
    OldIP = ""
    while True:
        CurrentIP = GetCurrentIP()
        if OldIP != CurrentIP:
            res = ModifyDynamicDNS(RecordId=RecordId, Domain=Domain, SubDomain=SubDomain, Ip = CurrentIP)
            if res:
                print(f'IP Successfully updated! primary IP:{OldIP},new IP:{CurrentIP}')
                OldIP = CurrentIP
            else:
                print('Dynamic domain name resolution API Something's wrong, trying again!')
                continue
        time.sleep(interval)

So far, the tutorial of local implementation of dynamic domain name resolution based on API Explorer has been completed. The complete source code has been open source to GitHub, address: QiQiWan/PythonDDNS

Summary

Home IP is dynamic, which is really annoying, but it can be combined with DNSPod to save the country. Practice has proved that the method is much more difficult than that! In addition, it is worth mentioning that API Explorer is really an artifact. Mom doesn't have to worry about problems when making API requests anymore. It saves a lot of things. It's really good!

Posted by pplexr on Thu, 04 Nov 2021 05:24:00 -0700