海外IP被误封解决方案

这里使用Google Cloud和Cloudflare来实现,解决海外服务器被误封IP,访问不到的问题。

这段脚本的核心目的,是自动监测你在 Cloudflare 上管理的 VPS 域名是否可达,一旦发现域名无法 Ping 通,就会帮你更换IP:

  1. 重置该实例的外部 IP(通过 gcloud compute instances delete-access-config + add-access-config),

  2. 把新分配到的 IP 同步到 Cloudflare DNS

  3. 刷新本地 DNS 缓存

  4. 并且全程将操作日志保存到按天分文件的 info_YYYYMMDD.log 中,方便你审计和排查。

—— 具体是这样解决问题的 ——

问题场景代码模块解决办法
VPS 外网 IP 被 GCP 回收或被 ISP 屏蔽is_ping_reachable()用系统 ping 命令检测域名连通性,如果返回码≠0,就判定“被屏蔽/不可达”。
需要把 VPS 的新外网 IP 同步到用户的域名update_external_ip()调用 gcloud compute instances delete-access-config + add-access-config,强制给实例分配一个新的外网 IP;再用 gcloud compute instances list 把这个 IP 取出来。
要让域名马上解析到新的 IPupdate_dns()通过 Cloudflare REST API,查询并更新(或新建)对应 A 记录,把最新 IP 写入 DNS。
本地可能还在缓存旧的 DNS 记录flush_local_dns()在 Windows 下执行 ipconfig /flushdns,Linux 下尝试刷新 systemd-resolve/nscd/dnsmasq 的缓存,确保下一次访问能拿到新 IP。
整个流程要长期自动运行while True / time.sleep(300)把上面所有逻辑放到一个无限循环里,每轮处理完等待 5 分钟(300 秒)再重新「读配置 → 逐条处理」。
运维过程中出现任何错误也不影响后续try/except + 日志记录每次对单个 VPS 的操作都包在 try…except 中,捕获异常后用 logging.error 把错误写日志,但不抛出,保证后面的 VPS 还能继续被处理。

总结

  • 监控(Ping)→ 修复(重置 IP + 更新 DNS)→ 验证(本地 DNS 刷新),

  • 全程自动化可重试有日志,从根本上解决了 VPS 外网 IP 不可用时,域名无法访问的问题。

import os
import sys
import requests
import json
import platform
import subprocess
import re
import shutil
import time
from datetime import datetime
from pathlib import Path
import logging"""
脚本功能:
1. 轮询 vps.config.json 中的 VPS 列表;
2. 若域名无法 ping 通,则重置实例外网 IP(gcloud)并同步到 Cloudflare;
3. 成功后刷新本地主机 DNS 缓存(Windows / Linux 通用);
4. 所有日志按日期写入当前目录的 info_YYYYMMDD.log,并保留 print 直观输出;
5. 出现任何异常仅记录日志,不影响继续处理下一条 VPS;
6. 每完成一轮后暂停 5 分钟,重新加载配置再开始下一轮。
"""# === Cloudflare 相关参数 ===
API_TOKEN   = "HGccH7pI34n65ZAz3MkBM1QGAQB7xo69_40J1"  # 具有 DNS 编辑权限
ZONE_NAME   = "askdfjsdd5.xyz"                          # 顶级域名
PROXIED     = False                                       # 关闭橙云(CDN)
TTL_SECONDS = 60                                          # TTL 最小值 60 秒CF_API  = "https://api.cloudflare.com/client/v4"
HEADERS = {"Authorization": f"Bearer {API_TOKEN}","Content-Type": "application/json"
}# ================ 日志配置 ================
log_file = Path(__file__).with_name(f"info_{datetime.now():%Y%m%d}.log")
logging.basicConfig(level=logging.INFO,format="[%(asctime)s] %(message)s",datefmt="%Y-%m-%d %H:%M:%S",handlers=[logging.FileHandler(log_file, encoding="utf-8")]
)# ================ 数据结构 ================
class VPSInfo:"""保存单个 VPS/域名 的相关信息"""def __init__(self, proId: str, area: str, vpsId: str, dn: str):self.proId = proId  # GCP 项目 IDself.area  = area   # GCP 可用区self.vpsId = vpsId  # 实例名称self.dn    = dn     # 对应域名def __repr__(self) -> str:return f"VPSInfo(proId={self.proId}, area={self.area}, vpsId={self.vpsId}, dn={self.dn})"# ================ 工具函数 ================
def load_vps_list(path: str = "vps.config.json"):"""加载配置文件并返回 VPSInfo 列表"""with open(path, "r", encoding="utf-8") as f:data = json.load(f)return [VPSInfo(item["proId"], item["area"], item["vpsId"], item["dn"]) for item in data]def is_ping_reachable(domain: str) -> bool:"""ping 判断域名可达性"""count_param = "-n" if platform.system().lower() == "windows" else "-c"try:res = subprocess.run(["ping", count_param, "1", domain],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)return res.returncode == 0except Exception:return Falsedef cf(method: str, path: str, **kw):"""调用 Cloudflare API,成功返回 result"""url = CF_API + pathresp = requests.request(method, url, headers=HEADERS, timeout=30, **kw)resp.raise_for_status()data = resp.json()if not data.get("success"):raise RuntimeError(f"Cloudflare API 调用失败: {data.get('errors')}")return data["result"]def update_dns(record_name: str, new_ip: str):"""创建或更新 A 记录"""zone = cf("GET", f"/zones?name={ZONE_NAME}&status=active&per_page=1")if not zone:raise RuntimeError(f"未找到域 {ZONE_NAME} 对应的 Zone")zone_id = zone[0]["id"]body = {"type": "A", "name": record_name, "content": new_ip,"ttl": TTL_SECONDS, "proxied": PROXIED}recs = cf("GET", f"/zones/{zone_id}/dns_records?type=A&name={record_name}&per_page=1")if recs:rec_id = recs[0]["id"]cf("PUT", f"/zones/{zone_id}/dns_records/{rec_id}", json=body)print(f"已更新 DNS:{record_name} → {new_ip}")logging.info(f"已更新 DNS:{record_name} → {new_ip}")else:rec = cf("POST", f"/zones/{zone_id}/dns_records", json=body)print(f"已创建 DNS:{record_name} → {new_ip} (id={rec['id']})")logging.info(f"已创建 DNS:{record_name} → {new_ip} (id={rec['id']})")def flush_local_dns():"""刷新本机 DNS 缓存(Windows / Linux)"""system = platform.system().lower()cmds = [["ipconfig", "/flushdns"]] if system == "windows" else [["systemd-resolve", "--flush-caches"],["resolvectl", "flush-caches"],["service", "nscd", "restart"],["service", "dnsmasq", "restart"],]for argv in cmds:if shutil.which(argv[0]):res = subprocess.run(argv, stdout=subprocess.PIPE,stderr=subprocess.PIPE, text=True)if res.returncode == 0:print(f"已刷新本地 DNS:{' '.join(argv)}")logging.info(f"已刷新本地 DNS:{' '.join(argv)}")returnprint("刷新本地 DNS 失败:未找到可用命令")logging.warning("刷新本地 DNS 失败:未找到可用命令")def update_external_ip(vps: VPSInfo) -> str:"""重置外网 IP 并返回新的 IP"""gcloud = shutil.which("gcloud") or shutil.which("gcloud.cmd")if not gcloud:raise RuntimeError("找不到 gcloud,可执行文件不在 PATH 中")cmds = [[gcloud, "compute", "instances", "describe", vps.vpsId,f"--project={vps.proId}", f"--zone={vps.area}","--format=get(networkInterfaces[0].accessConfigs[0].name)"],[gcloud, "compute", "instances", "delete-access-config", vps.vpsId,f"--project={vps.proId}", f"--zone={vps.area}","--access-config-name=External NAT"],[gcloud, "compute", "instances", "add-access-config", vps.vpsId,f"--project={vps.proId}", f"--zone={vps.area}","--access-config-name=External NAT"],[gcloud, "compute", "instances", "list",f"--filter=name={vps.vpsId}"]]last_output = ""for idx, argv in enumerate(cmds, 1):proc = subprocess.run(argv, stdout=subprocess.PIPE,stderr=subprocess.PIPE, text=True)if proc.returncode != 0:raise RuntimeError(f"第 {idx} 步命令失败: {' '.join(argv)}\n{proc.stderr.strip()}")last_output = proc.stdoutprint(f"第 {idx} 步命令执行成功")logging.info(f"第 {idx} 步命令执行成功")ips = re.findall(r"\b(?:\d{1,3}\.){3}\d{1,3}\b", last_output)if not ips:raise RuntimeError("未在实例列表输出中找到 IP")new_ip = ips[-1]print(f"获得新外部 IP: {new_ip}")logging.info(f"获得新外部 IP: {new_ip}")return new_ip# ================ 主流程 ================
def process_once():"""处理一轮:读取配置并遍历所有 VPS"""vps_list = load_vps_list()for vps in vps_list:print(f"开始处理: {vps}")logging.info(f"开始处理: {vps}")try:if is_ping_reachable(vps.dn):print(f"{vps.dn} 可 ping,跳过")logging.info(f"{vps.dn} 可 ping,跳过")else:print(f"{vps.dn} 不可 ping,准备重置 IP")logging.info(f"{vps.dn} 不可 ping,准备重置 IP")new_ip = update_external_ip(vps)update_dns(vps.dn, new_ip)flush_local_dns()print("等待 60 秒以确保解析生效")logging.info("等待 60 秒以确保解析生效")time.sleep(60)except Exception as e:print(f"处理 {vps.dn} 时发生异常: {e}")logging.error(f"处理 {vps.dn} 时发生异常: {e}")finally:print(f"完成处理: {vps}\n")logging.info(f"完成处理: {vps}\n")if __name__ == "__main__":while True:  # 无限循环,每轮结束休眠 5 分钟try:process_once()except Exception as e:print(f"脚本发生致命错误: {e}")logging.critical(f"脚本发生致命错误: {e}")print("=== 本轮结束,暂停 5 分钟 ===\n")logging.info("=== 本轮结束,暂停 5 分钟 ===\n")time.sleep(300)  # 300 秒 = 5 分钟

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/905685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个基于 Spring Boot 的实现,用于代理百度 AI 的 OCR 接口

一个基于 Spring Boot 的实现,用于代理百度 AI 的 OCR 接口 BaiduAIController.javaBaiduAIConfig.java在 application.yml 或 application.properties 中添加配置:application.yml同时,需要在Spring Boot应用中配置RestTemplate:…

GPT-4o 遇强敌?英伟达 Eagle 2.5 视觉 AI 王者登场

前言: 在人工智能领域,视觉语言模型的竞争愈发激烈。GPT-4o 一直是该领域的佼佼者,但英伟达的 Eagle 2.5 横空出世,凭借其 80 亿参数的精简架构,在长上下文多模态任务中表现出色,尤其是在视频和高分辨率图像…

将语言融入医学视觉识别与推理:一项综述|文献速递-深度学习医疗AI最新文献

Title 题目 Integrating language into medical visual recognition and reasoning: A survey 将语言融入医学视觉识别与推理:一项综述 01 文献速递介绍 检测以及语义分割)是无数定量疾病评估和治疗规划的基石(利特延斯等人&#xff0c…

Ubuntu24.04版本解决RK3568编译器 libmpfr.so.4: cannot open shared object

问题描述 在Ubuntu24.04版本上编译RK3568应用程序关于libmpfr.so.4: cannot open shared object问题,如下所示: /tools/ToolsChain/rockchip/rockchip_rk3568/host/bin/../libexec/gcc/aarch64-buildroot-linux-gnu/9.3.0/cc1plus: error while loadin…

产线视觉检测设备技术方案:基于EFISH-SCB-RK3588/SAIL-RK3588的国产化替代赛扬N100/N150全场景技术解析

一、核心硬件选型与替代优势‌ ‌1. 算力与AI加速能力‌ ‌异构八核架构‌:采用4Cortex-A76(2.4GHz)4Cortex-A55(1.8GHz)设计,支持视觉算法并行处理(如模板匹配、缺陷分类) 相机采…

python如何合并excel单元格

在Python中合并Excel单元格,常用openpyxl库实现。以下是详细步骤和示例代码: 方法一:使用 openpyxl 库 步骤说明: 安装库: pip install openpyxl导入库并加载文件: from openpyxl import load_workbook# …

高考备考1-集合

高考数学知识点总结—快手视频讲解 高考数学集合—快手视频讲解

Rust 数据结构:Vector

Rust 数据结构:Vector Rust 数据结构:Vector创建数组更新数组插入元素删除元素 获取数组中的元素迭代数组中的值使用枚举存储多个类型删除一个数组会删除它的元素 Rust 数据结构:Vector vector 来自标准库,在内存中连续存储相同类…

深度学习入门:深度学习(完结)

目录 1、加深网络1.1 向更深的网络出发1.2 进一步提高识别精度1.3 加深层的动机 2、深度学习的小历史2.1 ImageNet2.2 VGG2.3 GoogleNet2.4 ResNet 3、深度学习的高速化3.1 需要努力解决的问题3.2 基于GPU的高速化3.3 分布式学习3.4 运算精度的位数缩减 4、深度学习的应用案例4…

如何利用 Python 爬虫按关键字搜索京东商品:实战指南

在电商领域,京东作为国内知名的电商平台,拥有海量的商品数据。通过 Python 爬虫技术,我们可以高效地按关键字搜索京东商品,并获取其详细信息。这些信息对于市场分析、选品上架、库存管理和价格策略制定等方面具有重要价值。本文将…

‌JMeter聚合报告中的任务数和并发数区别

‌JMeter聚合报告中的任务数和并发数有本质的区别。‌ 任务数(样本数) 任务数或样本数是指在性能测试中发出的请求数量。例如,如果模拟20个用户,每个用户发送100次请求,那么总的任务数或样本数就是2000次请求‌ 并发…

Java 框架配置自动化:告别冗长的 XML 与 YAML 文件

在 Java 开发领域,框架的使用极大地提升了开发效率和系统的稳定性。然而,传统框架配置中冗长的 XML 与 YAML 文件,却成为开发者的一大困扰。这些配置文件不仅书写繁琐,容易出现语法错误,而且在项目规模扩大时&#xff…

OpenShift AI - 用 ModelCar 构建容器化模型,提升模型弹性扩展速度

《OpenShift / RHEL / DevSecOps 汇总目录》 说明:本文已经在 OpenShift 4.18 OpenShift AI 2.19 的环境中验证 文章目录 什么是 ModelCar构建模型镜像在 OpenShift AI 使用模型镜像部署模型扩展速度对比 参考 什么是 ModelCar KServe 典型的模型初始化方法是从 S…

C#+WPF+prism+materialdesign创建工具主界面框架

代码使用C#WPFprismmaterialdesign创建工具主界面框架 主界面截图:

在选择合适的实验室铁地板和铸铁试验平板,帮分析​

铸铁测试底板是一种采用铸铁材料经过加工制成的基准测量工具,主要用于工业检测、机械加工和实验室等高精度要求的场合。其核心功能是为各类测量、检验、装配工作提供稳定的水平基准面,确保测量数据的准确性和一致性。 一、铸铁测试底板的基本特性 1.材质…

C++匿名函数

C 中的匿名函数(Lambda 表达式)是 C11 引入的一项重要特性,它允许你在需要的地方定义一个临时的、无名的函数对象,使代码更加简洁和灵活。 1. 基本语法 Lambda 表达式的基本结构: [capture list](parameter list) -…

LabVIEW机械振动信号分析与故障诊断

利用 LabVIEW 开发机械振动信号分析与故障诊断系统,融合小波变换、时频分布、高阶统计量(双谱)等先进信号处理技术,实现对齿轮、发动机等机械部件的非平稳非高斯振动信号的特征提取与故障诊断。系统通过虚拟仪器技术将理论算法转化…

湖北理元理律师事务所:债务优化如何实现“减负不降质”?

在债务压力普遍加剧的背景下,如何平衡债务清偿与生活质量,成为个人及企业关注的焦点。湖北理元理律师事务所基于多年实务经验,总结出一套“法律财务”双轨制债务优化模型,其核心在于通过科学规划,帮助债务人在法律框架…

多链互操作性标准解析:构建下一代区块链互联生态

引言 在区块链技术快速演进的今天,“多链宇宙”已成为不可逆的趋势。然而,链与链之间的孤立性导致流动性割裂、开发成本高昂和用户体验碎片化。互操作性标准的制定,正是打破这一僵局的核心钥匙。本文将深入探讨主流互操作性协议的技术架构、…

电脑开机提示按f1原因分析及解决方法(6种解决方法)

经常有网友问到一个问题,我电脑开机后提示按f1怎么解决?不管理是台式电脑,还是笔记本,都有可能会遇到开机需要按F1,才能进入系统的问题,引起这个问题的原因比较多,今天小编在这里给大家列举了比较常见的几种电脑开机提示按f1的解决方法。 电脑开机提示按f1原因分析及解决…