根据服务器是否能 ping 通自动修改域名解析
饱受 ddos 攻击的烦恼,上次将网站放在果核大佬那里有一份,但是由于诸多原因,最大的问题就是 ftp 不方便和自己不能在服务器上进行一些操作,还是将网站放在了自己的服务器。
泄露了 ip 为什么不换,原因就是我用 zerotier 搭建了异地组网,换 ip 是小事,因为重新搭建一个也不费时间,但是手机上操作会比较麻烦。
所以选择了将果核那边的网站当作一个备用站点,服务器进黑洞了就直接切换解析,于是想到了写 python 脚本来解决这个问题。
说明一下,阿蛮君这边使用的是腾讯云的 dnspod 域名解析,所以需要安装相关模块。
pip3 install --upgrade tencentcloud-sdk-python
python 脚本内容如下:
import json
import subprocess
import time
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
# 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
secret_id = "xxx"
secret_key = "xxx"
endpoint = "dnspod.tencentcloudapi.com"
# 填写自己的域名相关信息,domain_id 就是域名的主键,在dnspod域名列表可以通过f12查看
domain = "test.com"
domain_id = 91234862
# 这是自己服务器的 ip,是否修改解析看这个ip是否能ping通
ip_address = "127.0.0.1"
# 这个是域名解析记录对应的id,在dnspod域名解析列表可以通过f12获取查看
record_ids = {
"test1": 1504279986,
"test2": 1504280312
}
record_line = "境内"
# 防止多次解析设置的变量
flag = '';
def init_flag():
# 初始化状态,不进行初始化会不清楚开始的状态
global flag
if check_ip_reachability(ip_address):
print(print_time() + "[初始化]服务器正常,准备修改解析记录...")
flag = True
update_normal_record()
else:
print(print_time() + "[初始化]服务器异常,准备修改解析记录...")
update_abnormal_record()
flag = False
print(print_time() + "初始化状态成功")
def print_time():
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + " "
def check_ip_reachability(ip_address):
# 尝试ping命令的最大次数
max_attempts = 30
# 每次尝试之间的等待时间(秒)
wait_time = 1
for _ in range(max_attempts):
# 使用subprocess模块执行ping命令
ping_process = subprocess.Popen(["ping", "-c", "1", ip_address], stdout=subprocess.PIPE)
ping_output, _ = ping_process.communicate()
ping_exit_code = ping_process.returncode
if ping_exit_code == 0:
# 如果ping成功,则返回True
return True
# 如果ping失败,则等待一段时间再进行下一次尝试
time.sleep(wait_time)
# 在指定次数的尝试之后,仍然ping失败,则返回False
return False
def modify_dns_record(record, record_type, value):
try:
# 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
# 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
# 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
cred = credential.Credential(secret_id, secret_key)
# 实例化一个http选项,可选的,没有特殊需求可以跳过
httpProfile = HttpProfile()
httpProfile.endpoint = endpoint
# 实例化一个client选项,可选的,没有特殊需求可以跳过
clientProfile = ClientProfile()
clientProfile.httpProfile = httpProfile
# 实例化要请求产品的client对象,clientProfile是可选的
client = dnspod_client.DnspodClient(cred, "", clientProfile)
# 实例化一个请求对象,每个接口都会对应一个request对象
req = models.ModifyRecordRequest()
params = {
"Domain": domain,
"DomainId": domain_id,
"SubDomain": record,
"RecordType": record_type,
"RecordLine": record_line,
"Value": value,
"RecordId": record_ids[record],
}
req.from_json_string(json.dumps(params))
# 返回的resp是一个ModifyRecordResponse的实例,与请求对象对应
resp = client.ModifyRecord(req)
print(print_time() + f"域名解析修改成功:{record}, {record_type}, {value}")
except TencentCloudSDKException as err:
print(print_time() + f"域名解析修改失败:{err}")
def update_dns_record(ip_address):
global flag
if check_ip_reachability(ip_address):
if flag == True:
print(print_time() + "服务器持续正常,解析无需更改")
return
# IP地址可达,执行相应的解析修改
print(print_time() + "服务器状态变更为正常,准备修改解析记录...")
update_normal_record()
flag = True
else:
if flag == False:
print(print_time() + "服务器持续异常,解析无需更改")
return
# IP地址不可达,执行相应的解析修改
print(print_time() + "服务器状态变更为异常,准备修改解析记录...")
update_abnormal_record()
flag = False
def update_normal_record():
modify_dns_record("test1", "CNAME", "test1.11dundns.com.")
modify_dns_record("test2", "CNAME", "test2.11dundns.com.")
def update_abnormal_record():
modify_dns_record("test1", "CNAME", "test1.hcnamecdns.com.")
modify_dns_record("test2", "CNAME", "test2.hcnamecdns.com.")
init_flag()
while True:
update_dns_record(ip_address)
time.sleep(5)
这里的参数根据自己的实际情况填写,并且如果你是直接解析 IP 的话,需要把 CNAME 改为 A 记录。test1 和 test2 这里是作为示例,实际一般使用 @ 和 www 解析记录。
运行脚本,服务器尝试禁 ping 和解除禁 ping,结果如下:
阅读剩余
THE END