海外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.pswp.cn/news/905685.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/905685.shtml
英文地址,請注明出處:http://en.pswp.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原因分析及解決…