Skip to content

Security: raphael2025/antmonitor

Security

docs/SECURITY.md

运维安全手册:别让人通过监控系统或局域网控制矿机

这套系统能重启全场、改全场矿池。改矿池等于把算力送给别人,是最值钱也最隐蔽的攻击。 下面按"做了收益最大"排序;前三节是上线前必做。


一、上线前必做(10 分钟)

1. 设置强密码

  • 最省事:用浏览器打开监控面板,在顶部「改密码」修改自己的密码。本机可用 http://127.0.0.1:8800,其它电脑用监控机的局域网地址;启用 HTTPS 时按实际地址访问。 密码太弱(admin888 这类默认密码、少于 8 位、少于 4 种不同字符、或和用户名相同) 会弹出改密提示,但可以关闭,账号仍保留原有角色权限。新密码的哈希写进 config.yaml,立即生效。
  • 账号还没密码(config.yaml 里是占位符或留空,这种账号任何地方都登不上): 在监控电脑上运行 python auth.py passwd admin,输两遍新密码,然后重启服务才生效。
  • 本机和其它电脑均可在登录后修改自己的密码。弱口令提示不是只读限制;不要以为保留默认密码的 ops/admin 账号只能查看面板。首次部署应给实际启用的账号设置强密码。
  • 每个人用自己的账号,别共用。审计记录里会带「账号@来源 IP」,出事能追到人。

2. 配置矿池白名单(防偷算力)

在 config.yaml 里填上你们实际用的矿池主机名(子域名自动放行):

control:
  pool_allowlist: ["f2pool.com", "antpool.com"]   # 例:btc.f2pool.com 也放行

配好后:

  • 网页「换矿池」只能换到白名单里的矿池。换到别的会被拒,同时推 Telegram 告警。
  • 每轮扫描读取每台矿机配置的全部矿池(含备用池)。只要出现白名单外的,就会报严重告警 「矿池不在白名单(疑似被篡改)」,并语音播报。有人绕过面板、直接用矿机默认口令改池,也能被发现。
  • 白名单只能改 config.yaml,网页(包括 admin)改不了。
  • 没配白名单时,网页换矿池直接禁用。

3. 开 Telegram 推送

每次重启、换矿池,以及被拒绝的换池尝试,都会推到值班群。谁在什么时候动了哪些机器,群里都看得到。


二、网络隔离(软件管不到,但最关键)

面板的登录只保护面板本身。矿机自己还是默认口令 root/root。局域网里任何一台电脑(包括被控制的矿机) 都能绕过面板,直接请求矿机的 set_miner_conf.cgi 改矿池。

做法 效果 对运维的影响
交换机 ACL:矿机网段的 80 / 4028 / 6060 端口只允许监控电脑的 IP 访问 局域网里别的机器碰不到矿机管理口 无,日常操作都走面板
办公网和矿机网分开 VLAN 员工电脑中毒不会波及矿机 无
改掉矿机口令 就算网络被打穿,也拿不到矿机权限 一次性工作量

改矿机口令时怎么不影响监控:scan.passwords 支持多组口令轮流尝试,可以分批改:

scan:
  passwords:
    - ["root", "新口令"]
    - ["root", "root"]    # 全部改完后删掉这一行

三、监控电脑本身

Windows 防火墙:8800 端口只放行运维电脑

第一次运行 Python 时,Windows 常会弹窗「允许 python 访问网络」。点了允许就会生成一条对所有人开放的规则。 不要删掉它(删了下次还会弹窗;弹窗时点"取消"会生成阻止规则,阻止优先于放行,运维电脑反而连不上), 而是把它收窄到只放行指定电脑。用管理员 PowerShell 执行:

# 允许访问面板的电脑:运维电脑 + 通过 /api/public 取数的 agent 主机(IP 换成你们自己的)
$allow = "192.168.1.20","192.168.1.21"
# 自动生成的 python 放行规则:只放行上面这些电脑
Get-NetFirewallRule -DisplayName "*python*" | Where-Object { $_.Direction -eq "Inbound" -and $_.Action -eq "Allow" } |
  Set-NetFirewallRule -RemoteAddress $allow
# 当初弹窗点了"取消"留下的 python 阻止规则会挡住所有人,删掉
Get-NetFirewallRule -DisplayName "*python*" | Where-Object { $_.Direction -eq "Inbound" -and $_.Action -eq "Block" } |
  Remove-NetFirewallRule
# 再加一条端口规则兜底(同样只放行这些电脑)
New-NetFirewallRule -DisplayName "矿机监控面板" -Direction Inbound -Protocol TCP `
  -LocalPort 8800 -RemoteAddress $allow -Action Allow

目录权限:别让普通账号能改程序

程序目录默认所有登录用户都能改。任何本地账号改了 server.py,等服务重启就能以服务账号的身份执行代码。 config.yaml 里还存着矿机口令和各种 token。

先确认服务是用哪个 Windows 账号运行的(双击 run.bat 就是当前登录的账号;NSSM 看服务属性里的"登录身份"), 然后用这个账号右键「以管理员身份运行」命令提示符,执行(路径换成实际位置):

cd /d C:\miner-monitor
icacls . /inheritance:r /grant:r "*S-1-5-32-544:(OI)(CI)F" "*S-1-5-18:(OI)(CI)F" "%USERNAME%:(OI)(CI)M" /T

效果:管理员组、SYSTEM 和运行服务的这个账号能读写,其它本地账号都改不了、也读不到 config.yaml。 千万别漏掉 %USERNAME% 那一项:开了 UAC 时,双击 run.bat 启动的进程不带管理员权限, 只给管理员组授权会让服务连自己的程序目录都读不了,下次重启监控就停了。

如果 NSSM 用 SYSTEM 账号跑服务、而仓库是别的账号 clone 的,git 会报 "dubious ownership",网页更新失效。 用管理员命令提示符执行一次:git config --system --add safe.directory C:/miner-monitor

远程桌面

  • 如果监控电脑开了远程桌面(RDP),务必用强密码。
  • 3389 端口同样只放行运维电脑。

别把面板直接暴露到公网

  • 要远程看,优先走 VPN。
  • 如果非要用 nginx 或 frp 从外网访问:
    • 把代理的地址加到 server.trusted_proxies。
    • 用 http 方式转发,让代理带上 X-Forwarded-For 头。
  • 纯 TCP 转发通常无法保留真实客户端 IP,审计和按来源限流只能看到转发端;不要用它把面板公开暴露到公网。 仅供已授权运维使用的 SSH 本地隧道仍可用于无桌面服务器访问,但审计可能只记录为本机来源。 同机跑 nginx 的话,把 127.0.0.1 加进 server.trusted_proxies,并让它正确传递客户端地址。 本机来源只豁免按用户名的临时锁定,按来源 IP 的登录失败限流仍生效。

四、HTTPS(可选:防局域网里有人抓包偷密码)

走 HTTP 时,登录密码和会话令牌在局域网里都是明文。开 HTTPS 用 Git 自带的 openssl 生成一张自签证书。 在程序目录下打开命令提示符执行(Git 默认没把 openssl 加进 PATH,所以写全路径;把 IP 换成监控电脑的 IP):

cd /d C:\miner-monitor
mkdir certs
"C:\Program Files\Git\usr\bin\openssl.exe" req -x509 -newkey rsa:2048 -nodes -days 3650 ^
  -keyout certs\key.pem -out certs\cert.pem ^
  -subj "/CN=miner-monitor" -addext "subjectAltName=IP:192.168.1.10,IP:127.0.0.1"
server:
  tls_cert: "certs/cert.pem"
  tls_key: "certs/key.pem"

证书路径按服务的工作目录解析:run.bat 会先切到程序目录,所以没问题;用 NSSM 的话,服务属性里的 "启动目录"(AppDirectory)要设成程序目录。

重启后所有地址都改成 https:局域网用 https://IP:8800,监控电脑本机改弱密码用 https://127.0.0.1:8800。 每台浏览器第一次会提示证书不受信任,确认一次就行。开启后登录 Cookie 自动加 Secure。 certs/ 已加进 .gitignore,不会被提交。


五、版本更新的安全

  • 网页「⬆ 版本」和自动更新,会从 GitHub 拉取代码并执行。能往跟踪分支推代码的人,就能在所有现场电脑上执行代码。
  • 生产现场建议保持 update.auto: false,由人确认后再点更新。
  • 让现场跟踪一个专门的发布分支(update.branch),在 GitHub 上给它开分支保护,只允许信得过的人合并。
  • GitHub 账号开两步验证。

六、出事了怎么查

情况 去哪看
谁重启/换池了 admin 登录后调用 /api/commands(审计),user 字段是「账号@来源 IP」。换池记录里有完整的矿池地址和矿工名,重要操作保留 400 天,不会被大量定位灯/维修记录冲掉
「矿池不在白名单」告警 立刻去看告警里列出的矿池地址。确认不是自己人配的,就用面板把该机矿池改回来,并按第二节查网络和矿机口令
登录失败很多 logs/miner.log 里搜「登录失败」,能看到账号和来源 IP。同一来源连错 8 次锁 5 分钟(监控电脑本机也一样);同一账号连错 20 次锁 15 分钟,但监控电脑本机、以及这个账号以前成功登录过的电脑不受这条限制(别人没法故意把值班员锁在外面)
页面提示「不允许用 xxx 访问」 用了域名访问面板。改用 IP,或把域名加到 server.allowed_hosts

附:系统已自带的防护

  • 账号权限分三级:viewer 只能看;ops 能下发命令;admin 能改设置、更新版本、看审计。
  • 弱密码:登录后提示修改,保留原有角色权限;空口令和示例占位符不能登录。
  • 改密码防爆破:同一会话改密码时旧密码连错 5 次,会被强制登出。
  • 登录限流:按来源 IP 和按账号各计一道,并发请求绕不过去。
  • 会话过期:12 小时不活动自动登出。
  • 重启和换矿池要二次确认,而且后端强制校验,不能靠绕过前端跳过。
  • 命令只能发往已配置网段内的矿机。网段本身只能是内网地址。
  • 防 DNS 重绑定:只接受用 IP、本机名或白名单域名访问。
  • 防跨站伪造:写请求带了别的网站的来源会被拒,请求体必须是 JSON;WebSocket 同样校验来源 (经 trusted_proxies 里的代理进来的除外)。
  • 矿池地址严格校验:只接受 stratum+tcp://主机名:端口 这种标准写法,带 @、?、#、% 等字符的地址一律当成可疑。
  • 云端上报只往外推数据,从不执行云端返回的任何内容。公网云端地址必须用 https。 云端没有域名(https://IP:端口、自签证书)时按证书 SHA-256 指纹认云端:指纹对不上直接断开, 中间人拿不到云端私钥就冒充不了。指纹从云端面板「🔌 场地接入」复制(接入码里已带)。
  • 上报 token 不回传浏览器:保存后面板只显示末 4 位,留空保存=沿用原值;settings.json(含 token)以 600 权限写入。
  • 一键安装:config.yaml 设为 600;admin 密码在安装时设置(或随机生成后只显示一次),不会留在示例占位口令上。
  • 日志打码:日志里的 token 和密码参数都会被打码。

There aren't any published security advisories