最近又折騰了一個其實沒什麼需求的東西,把家裡Windows服務器的ip通過DDNS連接,使我在外面也能通過遠程桌面連回家裡。
其實我的路由器本身就有華碩官方的ddns,也安裝了支持cf的ddns插件,而且家裡也有公網ipv4和ipv6,所以平時我都是wg直接連回家使用家裡的遠程桌面。但是總覺得還要連一個wg有點麻煩,直接ipv4端口映射又不安全。所以想把家裡Windows服務器的ipv6直接用cf的api做成ddns。
其他小夥伴也可以參考,適用於家中有ipv6公網地址且會分配給下面的設備,想通過域名直接連回家中Windows遠程桌面的情況。需要準備:cf的域名,ipv6防火牆放行相關端口(如3389),Windows的機器安過Python。
在需要連接的機器上創建以下兩個文件:
1 2 3 4 5 6 7 |
@echo off :loop echo [%date% %time%] 正在更新 IPv6 地址... python update_ipv6.py echo 等待一小時... ping -n 3600 127.0.0.1 > nul goto loop |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
import requests import socket import re import time API_TOKEN = "你的API令牌" DNS_NAME = "你的完整域名" # 如 sub.example.com def get_ipv6_address(): try: for info in socket.getaddrinfo(socket.gethostname(), None, socket.AF_INET6): addr = info[4][0] if not addr.startswith("fe80"): # 排除 link-local 地址 return addr except Exception as e: print("獲取IPv6失敗:", e) return None def get_zone_id(session, headers, zone_name): url = f"https://api.cloudflare.com/client/v4/zones?name={zone_name}" resp = session.get(url, headers=headers).json() if resp.get("success"): return resp["result"][0]["id"] print("獲取 Zone ID 失敗:", resp.get("errors")) return None def get_record(session, headers, zone_id, dns_name): url = f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records?type=AAAA&name={dns_name}" resp = session.get(url, headers=headers).json() if resp.get("success") and resp["result"]: return resp["result"][0] return None def update_record(session, headers, zone_id, record_id, dns_name, ipv6, proxied): url = f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{record_id}" data = { "type": "AAAA", "name": dns_name, "content": ipv6, "ttl": 600, "proxied": proxied } resp = session.put(url, json=data, headers=headers).json() return resp.get("success", False) def create_record(session, headers, zone_id, dns_name, ipv6): url = f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records" data = { "type": "AAAA", "name": dns_name, "content": ipv6, "ttl": 600, "proxied": False } resp = session.post(url, json=data, headers=headers).json() return resp.get("success", False) def main(): headers = { "Authorization": f"Bearer {API_TOKEN}", "Content-Type": "application/json" } zone_name = ".".join(DNS_NAME.split(".")[-2:]) with requests.Session() as session: ipv6 = get_ipv6_address() if not ipv6: print("未找到有效的 IPv6 地址") return print(f"當前 IPv6:{ipv6}") zone_id = get_zone_id(session, headers, zone_name) if not zone_id: return record = get_record(session, headers, zone_id, DNS_NAME) if record: if record["content"] == ipv6: print("IPv6 地址未變,無需更新") else: print("IPv6 地址已變,正在更新...") if update_record(session, headers, zone_id, record["id"], DNS_NAME, ipv6, record["proxied"]): print("更新成功") else: print("更新失敗") else: print("未找到記錄,正在創建...") if create_record(session, headers, zone_id, DNS_NAME, ipv6): print("創建成功") else: print("創建失敗") if __name__ == "__main__": main() |
update_ipv6.bat 是用來循環執行 update_ipv6.py 的,當然如果你更喜歡用計劃任務定時運行也一樣。個人愛好,我比較喜歡開機自啟bat然後能看見一個窗體讓我知道它在運行。
運行 update_ipv6.bat 即可每小時更新一次相關的dns記錄。該腳本只更新AAAA記錄,也就是ipv6,因為個人感覺ipv6連內網安全一點,如果需要連同A記錄也更新,可以自行修改,但需要通過第三方網站獲得本機外網ip(因為網卡上的ipv4是內網地址,不能直接獲得)。
以上。凜。