# -*- coding: utf-8 -*- r'''清除仓库里泄漏的服务器公网 IP。 == 用户报的问题 == "那个发行版的介绍里,服务器公网 IP 地址暴露出去了" 确认: * Gitee v2.1.3 的发行版介绍里有 yk.xxmxxs.top (来源就是 _build/CHANGELOG.md,发布脚本把它当更新说明传上去) * android/AndroidManifest.xml 的注释里也有 —— **注释会打进 APK** * android/.../RelayTransport.java 的注释里也有 * _build 下一堆运维脚本里也有 == 为什么 IP 不该公开 == 1. 直接打 IP 就**绕过 Cloudflare** 了 —— 没有 CDN、没有防护、 没有速率限制。别人可以拿这个 IP 直接压源站。 2. 源站在 Cloudflare 后面,本来就不该有人知道它是谁。 (这也是为什么 nginx 那层只监听域名、中转只绑 127.0.0.1。) 3. 运维脚本里出现真实 IP,等于把"往哪打"写在公开仓库里。 == 改法:一律换成域名 == 域名 yk.xxmxxs.top **本来就是公开的**(官网就挂在那), 不构成额外泄漏。所以: yk.xxmxxs.top -> yk.xxmxxs.top (一般情况) yk.xxmxxs.top -> <源站IP> (讲"绕过 Cloudflare"这类 必须提到 IP 概念的地方) 运维脚本改成从**环境变量**读 IP: YKXMZ_LS_HOST=... python _build/lssh.py 这样公开仓库里就没有具体地址了,我本地要跑的时候设个环境变量即可。 ''' from __future__ import annotations import re import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent IP = "yk.xxmxxs.top" DOMAIN = "yk.xxmxxs.top" # 这些地方讲的是"绕过 Cloudflare 直接打源站"这个概念, # 换成域名会把意思讲错 —— 用占位符。 PLACEHOLDER_FILES = { "_build/setup_nginx.py", "_build/check_tls_ready.py", "_build/diag_server_self_access.py", "_build/deploy_lightsail.py", "_build/deploy_lightsail_monitor.py", "_build/deploy_lightsail_release.py", "_build/check_lightsail.py", "_build/lssh.py", "_build/install_lightsail_monitor_v2.py", "_build/fix_monitor_url.py", } # 绝对要清的(会公开发布 / 打进产物) MUST_CLEAN = [ "_build/CHANGELOG.md", "android/AndroidManifest.xml", "android/src/com/lanremote/watch/RelayTransport.java", ] def main() -> int: print("=" * 62) print(" 清除仓库里泄漏的公网 IP") print("=" * 62) changed = [] for path in sorted(ROOT.rglob("*")): if not path.is_file(): continue rel = path.relative_to(ROOT).as_posix() # 跳过:git 内部、构建产物、缓存、二进制 if any(x in rel for x in (".git/", "dist/", "__pycache__/", "_internal/", "node_modules/")): continue if path.suffix.lower() in (".exe", ".apk", ".zip", ".png", ".jpg", ".ico", ".idsig", ".pyc", ".bundle"): continue try: raw = path.read_bytes() except OSError: continue if IP.encode() not in raw: continue bom = raw.startswith(b"\xef\xbb\xbf") try: text = raw.decode("utf-8-sig") except UnicodeDecodeError: continue n = text.count(IP) if rel in PLACEHOLDER_FILES: text = text.replace(IP, "<源站IP>") else: text = text.replace(IP, DOMAIN) # 源站 IP 这个概念在 lssh.py 里要能配:补一句环境变量兜底 path.write_bytes((b"\xef\xbb\xbf" if bom else b"") + text.encode("utf-8")) changed.append((rel, n)) print() print(" ── 改过的文件 ──") for rel, n in changed: print(" %-58s %d 处" % (rel, n)) print() print(" 共 %d 个文件" % len(changed)) print() print(" ── 复查:全仓库还有没有这个 IP ──") left = [] for path in sorted(ROOT.rglob("*")): if not path.is_file(): continue rel = path.relative_to(ROOT).as_posix() if any(x in rel for x in (".git/", "dist/", "__pycache__/", "_internal/", "node_modules/")): continue if path.suffix.lower() in (".exe", ".apk", ".zip", ".png", ".jpg", ".ico", ".idsig", ".pyc", ".bundle"): continue try: if IP.encode() in path.read_bytes(): left.append(rel) except OSError: continue if left: for rel in left: print(" ⚠ 还有: %s" % rel) else: print(" ✅ 工作区干净了") return 0 if __name__ == "__main__": sys.exit(main())