Releases: weihang1258/socket_server
Releases · weihang1258/socket_server
Release list
v1.3.9
兼容 DPI 版本:v1.0.7.0
紧急修复:ETag 缓存变量未 global 导致 list/upgrade 崩溃
- 根因:
get_releases()/get_latest()引用模块级 ETag 缓存变量_releases_etag/_releases_cache/_latest_etag时未声明global,Python 将其视为局部变量。首次调用无异常(变量被赋值而非读取),第二次及并发调用时报local variable referenced before assignment。 - 影响:v1.3.7 所有依赖
get_releases()/get_latest()的功能(socket_server list、socket_server upgrade、自动升级下载阶段)均崩溃。 - 修复:
get_releases()和get_latest()内添加对应global声明。
v1.3.8
兼容 DPI 版本:v1.0.7.0
请求日志增加代理标识 + raw 失败重试(upgrader.py)
- 新增
_proxy_tag():所有请求日志末尾统一显示(via proxy http://...)或(直连),一眼判断是否走代理。支持 config 和 env 两种代理来源。 - raw 重试:
get_latest_version_raw()失败后最多重试 2 次(间隔 2s/4s)。raw 不占 API 限额,重试无成本,扛偶发抖动。 - 修复
_latest_cache未赋值:get_latest()304 分支返回的_latest_cache在首次成功时未保存,导致缓存始终为 None。 - 所有请求日志(get_releases / get_latest / _download_file / _verify_sha256 / show_current)统一使用
_proxy_tag()标识代理状态。
v1.3.7
兼容 DPI 版本:v1.0.7.0
解决 GitHub 未认证 API 60 次/小时共享限额(upgrader.py / autoupgrade.py)
内网多靶机共享同一出口 IP,GitHub 未认证 API 限额 60 次/小时易耗尽(403)。本次用两个不依赖 token 的方案彻底规避:
- 方案 1 — raw 文件查版本:新增
get_latest_version_raw(),自动升级检查时从raw.githubusercontent.com/.../version.py读版本号(走 CDN,不占 API 限额)。仅在确认有新版需下载时才调 API 拿 asset 信息。 - 方案 2 — ETag 条件请求:
get_latest()/get_releases()缓存响应的ETag,后续请求带If-None-Match,未变化返回 304(不计入限额)。 - 自动升级流程:raw 查版本 → 比对 → 有新版才调
get_latest()拿 asset → 下载。日常检查零限额消耗。
v1.3.6
兼容 DPI 版本:v1.0.7.0
升级代理与重试策略调整(upgrader.py)
- 实时读取代理:所有 GitHub 请求(list / upgrade / 自动升级 / 下载)每次都实时读
/opt/socket/config的proxy=,不缓存。proxy 有值即走代理,无值则直连。 - 失败不重试:
_download_file去掉原来的"直连失败后用代理重试一次"逻辑。请求失败直接抛出,由调用方等下个周期再试,避免短时间内重复消耗 GitHub API 限额。 - 首次启动即检查:autoupgrade 线程启动后立即触发一次版本检查(无前置等待),后续周期保持 1 小时。
- 检查周期:
CHECK_INTERVAL保持 3600 秒(1 小时)。
背景
v1.3.4/1.3.5 在内网多靶机环境下暴露两个问题:(1) 服务启动时若 config 尚未写入 proxy=,首次检查直连失败;(2) 所有靶机共享同一出口 IP,GitHub 未认证 API 60 次/小时限额被耗尽(403)。本次调整重试策略避免雪上加霜;根因的限流问题建议后续给 GitHub API 请求加 token 认证(5000 次/小时)。
v1.3.5
兼容 DPI 版本:v1.0.7.0
chromium 按需自动下载(boce.py / handlers.py)
- 背景:拨测(datatype 131)依赖 chromium,此前要求人工预先部署到
/opt/socket/chrome-linux/chrome,缺失时直接报错。 - 新增:
ensure_chromium()—— 拨测触发时若 chromium 不存在则自动下载,用到才下,不阻塞服务启动。 - 下载源:npmmirror 镜像(
registry.npmmirror.com/-/binary/chromium-browser-snapshots/Linux_x64),动态查询最新 revision,下载chrome-linux.zip解压到/opt/socket/chrome-linux/。 - 代理支持:复用
/opt/socket/config的proxy=配置,内网环境下载走代理。 - 失败兜底:下载失败时在日志和标准输出打印手动下载方法(含完整 wget/解压/chmod 步骤)。
- 线程安全:用
_browser_lock防止并发拨测重复下载。 - 缺依赖库的自动安装逻辑(yum/apt-get)保持不变,在 chromium 存在但缺 so 时触发。
v1.3.4
兼容 DPI 版本:v1.0.7.0
升级下载代理支持(upgrader.py)
- 背景:systemd 启动的服务不继承 shell 的
http_proxy/https_proxy环境变量,内网代理环境下自动升级下载 GitHub Release 会直连失败。 - 新增:
/opt/socket/config支持proxy=http://host:port字段。所有 GitHub API 请求与二进制下载显式带上该代理。 - 失败重试:
_download_file直连失败后,若 config 配置了proxy=,自动用代理重试一次。 - 优先级:config
proxy=优先;未配置时回退环境变量(适用于手动socket_server upgrade等非 systemd 场景)。 - 更新
docs/build-and-deploy.md说明proxy配置项。
打包环境变更
改用 CentOS 7 (glibc 2.17) 容器编译 Python 3.8 shared lib 后打包,修复 Ubuntu 打包机 glibc 2.31 导致二进制在 CentOS 7.5 (glibc 2.17) 上 GLIBC_2.29 not found 启动崩溃的问题。新二进制最高仅需 GLIBC_2.14。
v1.3.3
兼容 DPI 版本:v1.0.7.0
修复自动升级切换失效(supervisor.py / cli.py)
- 根因:
_find_current_binary()用os.path.realpath()把versions/current符号链接解析成具体版本目录(如/opt/socket/versions/1.3.0),写入 systemd unit 的ExecStart成为硬编码版本路径。switch_to()切换符号链接后systemctl restart仍按 unit 里写死的旧路径启动,导致自动升级"切换成功、重启后版本不变"的死循环。 - 修复 1:
_find_current_binary()不再realpath解析,直接返回versions/current/socket_server,使 unit 的ExecStart指向稳定的current链接,切换链接后重启即生效。 - 修复 2(自愈):新增
ensure_unit_correct(),在cmd_serve启动时检查 unit 文件的ExecStart是否指向current链接,若不是(历史版本写死的路径)则自动重写 +daemon-reload。已部署靶机升级到本版本后,下次重启即自愈,无需手动enable。 - 重构:抽取
_write_unit()供service_enable与ensure_unit_correct复用。
v1.3.2
兼容 DPI 版本:v1.0.7.0
子进程环境清理增强(netutils.py)
_clean_subprocess_env:在原有LD_LIBRARY_PATH+_PYI_*清理基础上,新增"任何值以sys._MEIPASS开头的变量一律清除"的规则,覆盖PLAYWRIGHT_BROWSERS_PATH及未来同源变量,无需逐个枚举。- 修复
PLAYWRIGHT_BROWSERS_PATH=/tmp/_MEIxxxx/ms-playwright泄漏到长驻子进程(如dpi_monitor)的问题:_MEI目录在 socket_server 退出即删,子进程持有的该路径会变成悬空引用。 PATH显式保留,即便其值引用了_MEIPASS也不动,避免子进程找不到命令。- 进程内代码(如 playwright)仍可直接读
os.environ,不受影响:本函数只改传给子进程的环境副本。
v1.3.1
v1.3.1
兼容 DPI 版本:v1.0.7.0
Bug 修复(抓包停止/启动,capture.py)
- tcpdump_stop:幂等 + 信号升级 SIGINT→SIGTERM→SIGKILL + 精确 PID kill(
os.kill)。原pkill -f把客户端传入的
path当扩展正则,存在注入风险且 SIGKILL 会误杀无关同名进程。 - tcpdump_isrun:改用
pgrep -x精确匹配进程名 +/proc/{pid}/cmdline字面子串校验 path,返回(running, pids)
元组,杜绝误杀同名 tcpdump/dumpcap。 - Tcpdump_scapy._sniff:删除
_sniff开头self.e=False的竞态覆盖(冷导入期间stop()设的 True 被覆盖);分段
sniff 循环(每轮≤1s),解决无包到达时stop_filter不触发导致 stop 卡死 30s。 - flush 校验:改用
_wait_file_stable轮询文件大小稳定(连续两次相同)。原getsize/os.access对 root
恒真,是空操作。
sudo 兼容(netutils.py)
_strip_sudo_if_root:root 下剥离裸sudo前缀,规避目标机 sudo 损坏(libldap/OpenSSL ABI 不匹配导致sudoers.so
加载失败)。
子进程环境清理(netutils.py)
_clean_subprocess_env:清除 PyInstaller 注入的LD_LIBRARY_PATH和_PYI_*,避免 DPI 的 xsa 从临时目录加载错版本
libcrypto 启动即崩、被 dpi_monitor 反复重启。
Shell 注入修复(客户端可控参数全部改 list args + shell=False)
tcpdump_start:path/extended/ethmtu:eth(同时去掉 grep/awk 管道,改 Python 解析)unzip:filename/passwd/outdirhandlers datatype 131:chromium_path
其他
wait_until/wait_not_until异常分支补sleep,避免 CPU 空转handlers datatype 122处理stop()返回值,停止失败时返回错误 JSON- 新增
test_e2e.py用于部署后回归测试
完整变更:v1.3.0...v1.3.1