Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9376e35025 | ||
|
|
110a526fc6 | ||
|
|
9b7b817cb7 | ||
|
|
a39647d46f |
@@ -1,9 +1,11 @@
|
||||
# Royirin Rosmontis Private Proxy
|
||||
Supported by Global Rosmanka Cloud Nexus Inc. —— https://rosmanka.rrrosmontis.icu
|
||||
## 警告
|
||||
- 包含 WireGuard 的 common 版本转发器永久不再维护,推荐使用 Lite 版本
|
||||
> common 版本现在有许多未修复的 bug (如部分 UI 的显示问题) 、令人难以忍受的代码逻辑 (如 PAC 规则直接写在代码里)和安全性问题 (认证凭据的暴露与证书忽略),而 Lite 版本修复了这些问题,并会收到持续的更新
|
||||
- 本程序完全没有 Linux 与 CLI 功能兼容,默认构建为带有图形界面的 Windows .exe
|
||||
|
||||
## 如何区分 common 版本与 Lite 版本
|
||||
### 如何区分 common 版本与 Lite 版本
|
||||
- Lite 版本的版本号前四位固定为 9999,后续为从月份开始的构建时间戳,而 common 版本的版本号为包含年份的完整的构建时间戳
|
||||
|
||||
## 服务器侧配置手册 (部分内容过时)
|
||||
|
||||
+66
-11
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys, os, subprocess, time, ctypes, threading, functools, base64, bisect
|
||||
import sys, os, subprocess, time, ctypes, threading, functools, base64, bisect, re
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5.QtWidgets import (
|
||||
@@ -832,8 +832,17 @@ def _is_private_ip(host: str) -> bool:
|
||||
_CN_RANGES = None # 合并排序后的 (start, end) 整数段
|
||||
_CN_RANGES_LOADED = False
|
||||
_FORCE_PROXY_SUFFIXES = None
|
||||
_FORCE_PROXY_EXACT = None
|
||||
_FORCE_PROXY_REGEXES = None
|
||||
_FORCE_PROXY_LOADED = False
|
||||
|
||||
# PAC 数据由 CDN 独立下发;此处保留登录/AI 服务的关键后缀兜底。
|
||||
# 即使远端表暂时未更新或不可读,这些域名也不能因解析到中国 CDN IP 而直连。
|
||||
_CORE_FORCE_PROXY_SUFFIXES = frozenset((
|
||||
"anthropic.com", "chatgpt.com", "claude.ai", "googlecdn.com",
|
||||
"oaistatic.com", "oaiusercontent.com", "openai.com",
|
||||
))
|
||||
|
||||
def _data_path(name: str):
|
||||
"""数据文件路径:只取打包内置目录(config.json 随 exe 内置)。"""
|
||||
p = Path(BASE_DIR) / name
|
||||
@@ -1318,8 +1327,13 @@ def _load_cn_ranges():
|
||||
return _CN_RANGES
|
||||
|
||||
def _load_force_proxy_suffixes():
|
||||
"""加载 pac_domains.json:命中这些域名后缀的连接强制走隧道(优先于 IP 判定)。"""
|
||||
global _FORCE_PROXY_SUFFIXES, _FORCE_PROXY_LOADED
|
||||
"""加载 pac_domains.json 的后缀、精确和正则规则。
|
||||
|
||||
domain-list-community 的三种规则语义:普通域名匹配自身及子域;
|
||||
``full:`` 仅匹配该主机;``regexp:`` 按正则匹配。旧逻辑把后两类
|
||||
当成带冒号的普通后缀,导致它们永远不命中。
|
||||
"""
|
||||
global _FORCE_PROXY_SUFFIXES, _FORCE_PROXY_EXACT, _FORCE_PROXY_REGEXES, _FORCE_PROXY_LOADED
|
||||
if _FORCE_PROXY_LOADED:
|
||||
return _FORCE_PROXY_SUFFIXES
|
||||
_FORCE_PROXY_LOADED = True
|
||||
@@ -1327,14 +1341,51 @@ def _load_force_proxy_suffixes():
|
||||
import json
|
||||
path = _user_path("pac_domains.json")
|
||||
if path is None:
|
||||
return _FORCE_PROXY_SUFFIXES # 可选文件,缺失不影响 IP 分流
|
||||
_FORCE_PROXY_SUFFIXES = sorted(_CORE_FORCE_PROXY_SUFFIXES)
|
||||
_FORCE_PROXY_EXACT = frozenset()
|
||||
_FORCE_PROXY_REGEXES = ()
|
||||
log(f"未找到 pac_domains.json,使用 {len(_FORCE_PROXY_SUFFIXES)} 条关键域名兜底")
|
||||
return _FORCE_PROXY_SUFFIXES
|
||||
data = json.loads(Path(path).read_text("utf-8"))
|
||||
suffixes = sorted({str(d).strip().lower().lstrip("*.")
|
||||
for d in (data.get("domains") or []) if str(d).strip()})
|
||||
suffixes = set(_CORE_FORCE_PROXY_SUFFIXES)
|
||||
exact = set()
|
||||
regexes = []
|
||||
invalid_regexes = 0
|
||||
for raw in data.get("domains") or []:
|
||||
raw_rule = str(raw).strip()
|
||||
rule = raw_rule.lower()
|
||||
if not raw_rule:
|
||||
continue
|
||||
if rule.startswith("full:"):
|
||||
host = rule[len("full:"):].rstrip(".")
|
||||
if host:
|
||||
exact.add(host)
|
||||
continue
|
||||
if rule.startswith("regexp:"):
|
||||
# 正则本身可能含大写字符类或大小写敏感字面量;只忽略匹配时的
|
||||
# 域名大小写,不能在编译前改写 pattern。
|
||||
pattern = raw_rule[len("regexp:"):]
|
||||
if not pattern:
|
||||
invalid_regexes += 1
|
||||
continue
|
||||
try:
|
||||
regexes.append(re.compile(pattern, re.IGNORECASE))
|
||||
except re.error:
|
||||
invalid_regexes += 1
|
||||
continue
|
||||
suffixes.add(rule.lstrip("*.").rstrip("."))
|
||||
suffixes.discard("")
|
||||
_FORCE_PROXY_SUFFIXES = suffixes
|
||||
log(f"已加载强制代理域名: {len(suffixes)} 条 (pac_domains.json)")
|
||||
_FORCE_PROXY_EXACT = frozenset(exact)
|
||||
_FORCE_PROXY_REGEXES = tuple(regexes)
|
||||
log(f"已加载强制代理规则: 后缀 {len(suffixes)} 条、精确 {len(exact)} 条、"
|
||||
f"正则 {len(regexes)} 条 (pac_domains.json)" +
|
||||
(f",跳过 {invalid_regexes} 条非法正则" if invalid_regexes else ""))
|
||||
except Exception as e:
|
||||
log_red(f"pac_domains.json 加载失败: {e}")
|
||||
_FORCE_PROXY_SUFFIXES = sorted(_CORE_FORCE_PROXY_SUFFIXES)
|
||||
_FORCE_PROXY_EXACT = frozenset()
|
||||
_FORCE_PROXY_REGEXES = ()
|
||||
return _FORCE_PROXY_SUFFIXES
|
||||
|
||||
def _is_private_int(n: int) -> bool:
|
||||
@@ -1386,12 +1437,16 @@ def _is_china_ip(host: str):
|
||||
|
||||
@functools.lru_cache(maxsize=8192)
|
||||
def _is_force_proxy(host: str) -> bool:
|
||||
"""pac_domains.json 命中的域名强制走隧道(如 claude.ai:国内可连但显示拒绝页)。"""
|
||||
"""PAC 强制规则命中的域名走隧道(后缀 / full / regexp)。"""
|
||||
suffixes = _load_force_proxy_suffixes()
|
||||
if not suffixes:
|
||||
exact = _FORCE_PROXY_EXACT or ()
|
||||
regexes = _FORCE_PROXY_REGEXES or ()
|
||||
if not suffixes and not exact and not regexes:
|
||||
return False
|
||||
h = host.rstrip(".").lower()
|
||||
return any(h == s or h.endswith("." + s) for s in suffixes)
|
||||
return (any(h == s or h.endswith("." + s) for s in suffixes) or
|
||||
h in exact or
|
||||
any(pattern.search(h) is not None for pattern in regexes))
|
||||
|
||||
def _resolve_host_ips(host: str):
|
||||
"""解析域名的 IPv4/IPv6 地址集合(字面量 IP 返回自身);解析失败返回空集合。"""
|
||||
@@ -3092,4 +3147,4 @@ def main():
|
||||
os._exit(ret)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<span class="code-label">Error code 200</span>
|
||||
</h1>
|
||||
<div>
|
||||
Visit <a href="https://example.com" target="_blank" rel="noopener noreferrer">example.com</a> for more information.
|
||||
Visit <a href="https://rrrosmontis.icu" target="_blank" rel="noopener noreferrer">rrrosmontis.icu</a> for more information.
|
||||
</div>
|
||||
<div class="mt-3">2026-06-28 05:00:19 UTC</div>
|
||||
</header>
|
||||
@@ -90,7 +90,7 @@
|
||||
<span class="cf-footer-separator sm:hidden">•</span>
|
||||
</span>
|
||||
|
||||
<span class="cf-footer-item sm:block sm:mb-1"><span>Performance & security by</span> <a rel="noopener noreferrer" href="https://example.com" id="brand_link" target="_blank">Example Site</a></span>
|
||||
<span class="cf-footer-item sm:block sm:mb-1"><span>Performance & security by</span> <a rel="noopener noreferrer" href="https://rrrosmontis.icu" id="brand_link" target="_blank">Royirin Rosmontis</a></span>
|
||||
</p>
|
||||
</div><!-- /.error-footer -->
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user