WechatOnCloud/bridge/s6/woc-bridge/run

71 lines
2.8 KiB
Plaintext
Raw Normal View History

#!/usr/bin/with-contenv bash
# 等待微信主界面登录完成(检测到足够大的主窗口),避免未登录时 bridge
# 狂刷日志/任务失败。超时 10 分钟仍未登录则放弃启动。
WAITED=0
MAX_WAIT=600
while true; do
# 通过 wechat 进程 PID 查找窗口,过滤出面积足够大的主窗口
wid=""
area=0
pid=$(pgrep -f "/config/wechat/opt/wechat/wechat" | head -1)
if [ -n "$pid" ]; then
for candidate in $(xdotool search --pid "$pid" 2>/dev/null); do
info=$(xdotool getwindowgeometry --shell "$candidate" 2>/dev/null)
if [ -n "$info" ]; then
eval "$info"
a=$((WIDTH * HEIGHT))
if [ "$a" -gt "$area" ]; then
area=$a
wid=$candidate
fi
fi
done
fi
# 登录后主窗口面积通常 > 300000登录窗口/扫码窗口面积较小
if [ "$area" -ge 300000 ]; then
echo "woc-bridge: 检测到微信已登录主窗口area=${area}),等待 60s 让微信完全就绪后再启动 bridge" >&2
sleep 60
echo "woc-bridge: 等待结束,启动 bridge" >&2
break
fi
sleep 3
WAITED=$((WAITED + 3))
if [ "$WAITED" -ge "$MAX_WAIT" ]; then
echo "woc-bridge: 等待微信登录超时(${WAITED}s暂不启动 bridge" >&2
# s6 服务退出码 0 会被视为正常结束并自动重启;用 sleep + 退出 0
# 让服务进入休眠,用户登录后可通过重启容器或手动 s6-svc -u 唤醒
sleep infinity
exit 0
fi
done
# 以 abc 用户身份运行(与微信同 X 会话,才能操作微信窗口)
# s6-setuidgid 不接受 VAR=value 参数,须先用 s6-env 设环境变量再切用户
# 校验 ptrace 权限key_extractor 读微信进程内存需要)
PTRACE_SCOPE="/proc/sys/kernel/yama/ptrace_scope"
if [ -e "$PTRACE_SCOPE" ]; then
if echo 0 > "$PTRACE_SCOPE" 2>/dev/null; then
echo "woc-bridge: ptrace_scope 已设置为 0" >&2
else
echo "woc-bridge: 无法写入 ptrace_scope可能需要 --privileged 或 SYS_PTRACE capability" >&2
fi
else
# 通过 CapEff 检查是否持有 SYS_PTRACE (bit 12)
CAP_EFF=$(awk '/^CapEff:/{print $2}' /proc/self/status 2>/dev/null)
if [ -n "$CAP_EFF" ] && [ $((0x${CAP_EFF} & 0x1000)) -ne 0 ]; then
echo "woc-bridge: 宿主机未启用 YAMA但容器已持有 SYS_PTRACEkey 提取仍可尝试" >&2
else
echo "woc-bridge: 宿主机未启用 YAMA 且容器未持有 SYS_PTRACE自动 key 提取可能不可用" >&2
fi
fi
exec s6-env DISPLAY=${DISPLAY:-:1} XAUTHORITY=/config/.Xauthority \
s6-setuidgid abc \
python3 /opt/woc-bridge/server.py \
--listen 0.0.0.0:8088 \
--wechat-db /config \
--display ${DISPLAY:-:1}