背景
公司电信宽带(PPoE)分配了一个公网IP,但它每过一段时间就变了,如果我要用它远程桌面,意味着每过一段时间就要改一次IP,记一个新的IP,非常复杂,该如何用一个固定的地址来替代这些变化的IP并且实现定时自动替换呢?虽然可以通过购买EIP来固定这个地址,但是成本稍微高了。替代的办法就是动态解析,用一个别名代替变换的IP。而别名就是域名,用一个固定的域名,解析到这些IP,即可实现DDNS。
原理
基本流程就是获取公网IP,然后修改某个域名的解析为获得的IP
流程图如下
实施
网络:
将服务器网络出口NAT到动态IP线路上(其他设置可自行科普,以下仅供参考)
此处已Cisco路由器为例:
ip nat inside source static tcp 192.168.0.217 80 interface Dialer1 11180
#Dialer1为PPOE拨号线路
access-list 100 permit ip host 192.168.0.217 any
#ACL 100为PPOE拨号线路
密钥:
在确定服务器经由PPoE线路上网后,需要在DNSPod上申请API密钥,从而获取SecretId以及SecretKey
环境:
Ubuntu 20.04 + Python 3.8.10
安装依赖包:
pip install tencentcloud-sdk-python
pip install tencentcloud-sdk-python-dnspod
**详细脚本如下: **
Ref: 腾讯云 API Explorer
import json
import requests
import logging
from datetime import datetime
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.dnspod.v20210323 import dnspod_client, models
############################################
#此处需要按照实际情况修改
Domain = "*****.com" #修改域
SubDomain = "p1234" #修改域名
SecretId = "SecretId"
SecretKey = "SecretKey"
############################################
filename = "./" + datetime.now().strftime("%Y%m%d") + "-" + SubDomain + "-DDNS-Log.log"
logging.basicConfig(filename=filename, level=logging.INFO,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
logging.info("脚本开始运行...")
#获取当前公网IP地址,通过AWS提供的服务。
def get_external_ip():
try:
ip = requests.get('https://checkip.amazonaws.com/').text.strip()
return ip
logging.info("成功获取当前公网地址...")
except:
return None
logging.info("获取当前公网地址失败...")
CurrentGlobalIP = get_external_ip()
try:
cred = credential.Credential(SecretId, SecretKey) #修改成你获得的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,
"Subdomain": SubDomain
}
req.from_json_string(json.dumps(params))
resp = client.DescribeRecordList(req)
RecordID = resp.RecordList[0].RecordId
RecordValue = resp.RecordList[0].Value
RecordLine = resp.RecordList[0].Line
RecordType = resp.RecordList[0].Type
logging.info("成功获取域名信息...")
logging.info("域名信息: " + SubDomain+"."+Domain+" "+RecordValue)
except TencentCloudSDKException as err:
logging.info("获取域名信息失败..." + err)
if CurrentGlobalIP == RecordValue:
logging.info("域名信息未发生变动...")
else:
logging.info("域名信息发生变动...")
try:
req = models.ModifyRecordRequest()
params = {
"Domain": Domain,
"RecordId": RecordID,
"RecordLine": RecordLine,
"RecordType": RecordType,
"SubDomain": SubDomain,
"Value": CurrentGlobalIP
}
req.from_json_string(json.dumps(params))
resp = client.ModifyRecord(req)
logging.info("新域名信息: " + SubDomain + "." + Domain + " " + CurrentGlobalIP)
except TencentCloudSDKException as err:
logging.info("修改域名信息失败..." + err)
logging.info("脚本结束运行...")
将脚本设置成定时运行
此处是将脚本设置为每小时的10分运行一次,也可按照自己需求进行修改。
日志输出:
到此,就完成了动态公网解析,更多可能,需要我们一起继续探索…