Skip to content

Troubleshooting

AutoOps edited this page Oct 12, 2026 · 1 revision

中文 · English

故障排查

按「看到什么现象」查,每条都给出怎么判断和怎么修。先做三件通用的事,能省掉一半来回:curl -fsS http://127.0.0.1:5000/api/health 看后端活着没(正常回 {"success":true,...})、按 Ctrl + F5 强刷一次、再看「审计中心」里有没有对应的失败记录(几乎每种失败都会留痕)。

登录页报 404 / 502 / 连接被拒

  • 判断:直连 http://127.0.0.1:5000 能打开、走域名打不开 ⇒ 问题在反代;两边都打不开 ⇒ 后端没起或端口不对。
  • 修:确认后端进程在跑、监听 5000;前端开发服务器默认把 /api、/socket.io 代理到 127.0.0.1:5000(ant-design-pro/config/proxy.ts),后端在别的机器上就用 BASTION_API=http://<后端IP>:5000 npm run dev。Nginx 反代要转发 /api 与 /socket.io 两条。

登录成功又立刻跳回登录页(或接口 401)

  • 判断:浏览器 localStorage.bastion_token 有没有值;F12 看接口是不是 401。
  • 修:令牌过期重新登录;如果所有人同时被踢,通常是 instance/secret.key 被换掉或删掉了(JWT 用它签名,换了就等于全部失效),把备份里的 secret.key 放回去即可;.env 里显式写了 BASTION_JWT_SECRET 的话,优先检查它有没有变。

页面白屏、样式是旧的、或提示「未发现前端构建产物…仅提供 API」

  • 判断:后端日志里有没有这句「未发现前端构建产物」;ant-design-pro/dist/index.html 的时间戳是不是比你的改动还早。
  • 修:后端只在启动时检查 dist/index.html 是否存在 —— 先起后端、后构建的话,重启一次后端;样式旧一般是浏览器缓存,Ctrl + F5。改了前端代码记得重新 npm run build。

网页终端一直「连接中」

  • 判断:浏览器开发者工具的 Network 里能看到 /socket.io/?EIO=4&transport=polling 成功、但 transport=websocket 一直是 pending 或 400。
  • 修:反代没透传 WebSocket。Nginx 要在 location /socket.io/ 里带 proxy_http_version 1.1;、proxy_set_header Upgrade $http_upgrade;、proxy_set_header Connection "upgrade";(完整片段见 Install-and-Deploy)。云厂商的七层负载均衡也要显式打开 WebSocket。

终端进得去但没输出 / 提示符不来 / 过一会儿自己断了

  • 判断:终端顶部状态是「已连接」还是没有;会话记录里的结束原因写的是哪一条。
  • 修:连不上多半是目标机 sshd 没开、账号口令不对或端口填错;连上后长时间不动会被空闲清扫断开(默认 1800 秒,提示语是「空闲超时自动断开」),这是设计行为;命令敲下去被拒是命中命令策略,看「命令记录」里的拒绝原因。

Windows 主机连不上(WinRM)

  • 判断:「测试连接」里 winrm 端点的报错是连接超时、认证失败还是协议错。
  • 修:目标机执行 Enable-PSRemoting -Force;端口 5985(HTTP)/ 5986(HTTPS,填 5986 自动走 TLS);主机记录里的账号口令、WinRM 认证方式(默认 NTLM)要与目标机一致;跨网段还要看目标机防火墙的 WinRM 规则。

Windows 远程桌面连不上(RDP)

  • 判断:控制台顶部状态、以及会话记录里的结束原因(例如 [SSL: TLSV1_ALERT_INTERNAL_ERROR])。
  • 修:端口 3389 是否可达;目标机要求 NLA 时把主机级「RDP 安全层」改成「强制 SSL」,会改写 X.224 请求只报 PROTOCOL_SSL、绕开 NLA;Windows Server 2003 / XP 这类老系统即使会话建起来,浏览器客户端仍会 decode error,请改用系统自带「远程桌面连接」(这是已知能力边界,不是配置能解决的)。

命令被拒绝,但我觉得没问题

  • 判断:「审计中心 → 命令记录」里那条记录会写明命中了哪条策略、风险等级与拒绝原因。
  • 修:到「命令策略」看规则正则是怎么写的(默认策略是内置的,带版本号、升级会自动刷新,管理员自建的不受影响);需要放行就调规则或给它换个绑定范围。高危命令可以要求管理员当场二次确认,这类放行同样留痕。

菜单里少了主机 / 列表里看不到某台机器

  • 判断:用管理员账号登录能不能看到;能看到 ⇒ 是这个账号没有授权。
  • 修:在「访问授权」里补「用户 → 主机 → 账号」的授权行,并勾上要用的能力(网页终端 / 文件管理 / 远程桌面)。审计里会有对应的拒绝记录。前端菜单只按角色权限码显示,最终判定在后端,绕过前端也没用。

文件管理器报错:415、二进制文件、会话数上限

  • 判断:页面提示的原文(例如不支持的二进制类型、会话数已达上限)。
  • 修:文件策略会限制可碰的路径与操作;某些二进制类型被明确拒绝(返回 415);同一用户的并发会话数默认上限 8(MAX_SESSIONS_PER_USER=8),关掉不用的标签页即可。

审计链校验报异常

  • 判断:在 bastion-backend/ 下跑 python tools/verify_audit_chain.py,看它输出哪一行、哪个类别。
  • 修:链起步之前的空哈希行是老库升级遗留,合法,不用管;链起步之后出现空哈希行会被标成异常(把哈希清空也算改哈希),这时先别删数据,把输出和数据库一起留档,再按「审计与安全」的说明定位。

SSH 网关 2222 连不上

  • 判断:System Settings → SSH Gateway 里「运行状态」是运行还是未运行;服务端日志有没有写为什么没起。
  • 修:启动参数带了 --no-gateway、或环境变量 BASTION_GATEWAY_ENABLED=0,网关就不会起;确认服务器在 2222 上监听,再看云安全组与主机防火墙;公钥认证需要在网关页确认公钥认证开关是开的。连续输错口令会触发锁定(5 次 / 15 分钟),锁定期间正确口令也会被拒。

前端构建或类型检查失败

  • 判断:npx tsc --noEmit 与 npx biome check 的报错原文。
  • 修:依赖不一致先 npm ci;Umi 的临时目录 src/.umi/ 是生成物(已 gitignore),删掉它会自动重建,能治好一些「明明改了却没生效」的怪问题;npx biome check --write 可以自动格式化。四条门禁按顺序跑:npx biome check → npx tsc --noEmit → npx vitest run → npm run build。

后端服务或测试像是卡住了

  • 判断:进程 CPU 一直涨、日志不再新增。
  • 修:先看是不是在跑大查询或真的在等目标机超时;后端测试建议明确关掉随机顺序(python -m pytest tests -q -p no:randomly),本项目就遇到过一次随机顺序下某个用例长时间不返回,强制结束该进程后重跑即全绿。别在看不清状态时直接删库重来 —— 数据文件就一个,删了就没了。

AI 运维助手报 400 AI_NOT_CONFIGURED

  • 判断:接口返回体里的 message 与页面提示。
  • 修:把 DEEPSEEK_API_KEY 写进 bastion-backend/.env 然后重启服务(环境变量是启动时读的)。没配也不会影响其它功能。

Troubleshooting

Look up the symptom you are seeing; every entry gives you how to tell and how to fix. Three general steps save half the round trips: curl -fsS http://127.0.0.1:5000/api/health to confirm the backend is alive (a healthy one returns {"success":true,...}), a hard refresh with Ctrl + F5, and a look at the Audit Center for the matching failure entry — almost every failure leaves one.

The sign-in page returns 404 / 502 / connection refused

  • How to tell: it works against http://127.0.0.1:5000 but not through your domain ⇒ the reverse proxy is at fault; neither works ⇒ the backend is down or on another port.
  • Fix: confirm the backend process is running and listening on 5000. The dev server proxies /api and /socket.io to 127.0.0.1:5000 (ant-design-pro/config/proxy.ts); if the backend lives elsewhere, run BASTION_API=http://<backend-ip>:5000 npm run dev. An Nginx reverse proxy must forward both /api and /socket.io.

Sign-in succeeds but bounces straight back to the login page (or APIs return 401)

  • How to tell: does localStorage.bastion_token hold a value? Do the failing requests in the browser's F12 panel return 401?
  • Fix: an expired token just needs a fresh sign-in. If everyone was kicked at once, instance/secret.key was most likely replaced or deleted — JWTs are signed with it, so losing it invalidates them all; restore the key from a backup. If BASTION_JWT_SECRET is set explicitly in .env, check that value first.

Blank page, stale styles, or "未发现前端构建产物…仅提供 API"

  • How to tell: search the backend log for that "no frontend build output" line; compare the timestamp of ant-design-pro/dist/index.html with your last change.
  • Fix: the backend only checks for dist/index.html at startup — if you built after starting it, restart the backend once. Stale styles are usually browser cache: Ctrl + F5. Rebuild with npm run build after frontend changes.

The web terminal is stuck on "connecting"

  • How to tell: in the Network panel, /socket.io/?EIO=4&transport=polling succeeds but transport=websocket stays pending or returns 400.
  • Fix: the proxy is not passing WebSocket upgrades through. For Nginx, location /socket.io/ needs proxy_http_version 1.1;, proxy_set_header Upgrade $http_upgrade; and proxy_set_header Connection "upgrade"; (full snippet in Install-and-Deploy). Layer-7 cloud load balancers need WebSocket support switched on explicitly.

The terminal opens but shows no output, no prompt, or disconnects by itself

  • How to tell: does the status bar read "connected"? What does the session record list as the end reason?
  • Fix: no connection at all is usually a stopped sshd on the target, wrong credentials, or a wrong port. Sitting idle long enough triggers the idle sweeper (1800 seconds by default, with the message 「空闲超时自动断开」) — that is intended behaviour. A rejected command means a command policy matched; the command record states the reason.

A Windows host will not connect (WinRM)

  • How to tell: what exactly does the winrm endpoint say under "Test connection" — timeout, authentication failure, or protocol error?
  • Fix: run Enable-PSRemoting -Force on the target; port 5985 (HTTP) or 5986 (HTTPS — filling in 5986 switches to TLS); the account, password and WinRM auth method (NTLM by default) in the host record must match the target; across subnets, check the target's firewall rules for WinRM.

A Windows host will not connect (RDP)

  • How to tell: the console status line, plus the end reason in the session record (for example [SSL: TLSV1_ALERT_INTERNAL_ERROR]).
  • Fix: check reachability of 3389. When the target requires NLA, set the host's "RDP security layer" to "Force SSL": the X.224 request is rewritten to advertise PROTOCOL_SSL only, bypassing NLA. For legacy systems such as Windows Server 2003 / XP the session may establish but the browser client still ends in decode error — use the built-in Windows "Remote Desktop Connection" instead. That is a known capability boundary, not something a setting can fix.

A command was rejected, but it looks harmless to me

  • How to tell: the matching row under "Audit Center → Command records" names the policy that matched, its risk level and the reason.
  • Fix: review the rule's regex under "Command policies" (the defaults are built in and versioned — upgrades refresh them; administrator-created policies are untouched). To allow it, adjust the rule or change what it is bound to. High-risk commands can require an administrator's on-the-spot confirmation, and such approvals are audited too.

Hosts are missing from the menu / list

  • How to tell: can an administrator account see the host? If yes, this account simply lacks a grant.
  • Fix: add a "user → host → account" grant under "Access grants" and tick the capabilities you need (web terminal / file manager / remote desktop). The audit trail records the corresponding denials. The frontend menu only reflects role permission codes; enforcement is on the backend, so bypassing the UI changes nothing.

File manager errors: 415, binary files, session limit

  • How to tell: the exact message on screen (unsupported binary type, session limit reached).
  • Fix: file policies restrict which paths and operations are allowed; some binary types are explicitly refused (415); concurrent sessions per user default to 8 (MAX_SESSIONS_PER_USER=8) — close tabs you are not using.

The audit-chain verifier reports an anomaly

  • How to tell: run python tools/verify_audit_chain.py from bastion-backend/; note which row and category it prints.
  • Fix: empty hash rows before the chain starts are legitimate legacy rows from an older database — ignore them. An empty hash row after the chain started is reported as an anomaly (blanking a hash counts as changing it); do not delete anything yet — archive the output together with the database, then follow "Audit and security" to localise it.

Port 2222 (SSH gateway) refuses connections

  • How to tell: "System Settings → SSH Gateway" shows 运行状态 as running or not; the server log explains why it did not start.
  • Fix: the gateway does not start when --no-gateway was passed or BASTION_GATEWAY_ENABLED=0 is set. Confirm the server listens on 2222, then check the cloud security group and the host firewall. Public-key authentication must be switched on in the gateway page to be usable. Repeated wrong passwords trigger a lockout (5 failures / 15 minutes) during which even the correct password is refused.

Frontend build or type check fails

  • How to tell: the exact errors from npx tsc --noEmit and npx biome check.
  • Fix: on dependency drift, run npm ci first. Umi's temporary directory src/.umi/ is generated (and gitignored) — deleting it makes Umi rebuild it and cures some "I changed it but nothing happened" cases. npx biome check --write fixes formatting automatically. Run the four gates in order: npx biome check → npx tsc --noEmit → npx vitest run → npm run build.

The backend service or its tests look stuck

  • How to tell: the process burns CPU while the log stops growing.
  • Fix: first check whether it is genuinely working through a big query or waiting on a target-host timeout. For backend tests, disable random ordering explicitly (python -m pytest tests -q -p no:randomly); this project once had a single test hang indefinitely under random ordering, and force-killing that process then re-running came back all green. Never wipe the database just because the state looks unclear — there is exactly one data file, and deleting it is irreversible.

The AI assistant returns 400 AI_NOT_CONFIGURED

  • How to tell: the message field in the response and the on-page hint.
  • Fix: put DEEPSEEK_API_KEY in bastion-backend/.env and restart the service (environment variables are read at startup). Everything else keeps working without it.

相关页面 / Related pages: FAQ · Install-and-Deploy · Security-and-Maintenance · Home

Clone this wiki locally