#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 挖矿病毒守护 - Cunkebao 服务器安装脚本 使用 devlop.py 中的服务器配置,上传 miner_guard.sh 并配置每 30 分钟执行。 运行: cd Cunkebao && python miner_guard_install.py --yes """ import os import sys import io try: import paramiko except ImportError: print("错误: pip install paramiko") sys.exit(1) # Cunkebao 服务器配置(与 devlop.py 一致) script_dir = os.path.dirname(os.path.abspath(__file__)) cfg = { "host": "42.194.245.239", "port": 6523, "user": "yongpxu", "password": "Aa123456789.", } def main(): import argparse p = argparse.ArgumentParser(description="Cunkebao 挖矿守护安装") p.add_argument("--yes", "-y", action="store_true", help="跳过确认") args = p.parse_args() # miner_guard.sh 来自 soul-api local_sh = os.path.join(os.path.dirname(script_dir), "soul-api", "miner_guard.sh") if not os.path.isfile(local_sh): local_sh = os.path.join(script_dir, "miner_guard.sh") if not os.path.isfile(local_sh): print("[错误] 未找到 miner_guard.sh,请确保 soul-api/miner_guard.sh 存在") sys.exit(1) print("=" * 60) print(" 挖矿病毒守护 - Cunkebao 安装") print("=" * 60) print(" 服务器: %s:%s" % (cfg["host"], cfg["port"])) print(" 用户: %s" % cfg["user"]) print(" 脚本: ~/miner_guard.sh") print(" 日志: ~/miner_guard.log") print(" Cron: 每 30 分钟执行") print("=" * 60) if not args.yes: print("\n确认安装? 输入 yes 继续: ", end="") if input().strip().lower() != "yes": print("已取消") return client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: client.connect(cfg["host"], port=cfg["port"], username=cfg["user"], password=cfg["password"], timeout=15) except Exception as e: print("[连接失败]", str(e)) sys.exit(1) # 获取用户 home 并确定实际路径 sin, sout, serr = client.exec_command("echo $HOME", timeout=5) home = sout.read().decode("utf-8", errors="replace").strip() or "/home/%s" % cfg["user"] remote_path = "%s/miner_guard.sh" % home log_path = "%s/miner_guard.log" % home cron_line = "*/30 * * * * /bin/bash %s >> %s 2>&1" % (remote_path, log_path) # 非 root 时用 $HOME 做日志,避免 /var/log 无权限 with open(local_sh, "r", encoding="utf-8", errors="replace") as f: content = f.read() if cfg["user"] != "root": head = '[ "$(id -u)" != "0" ] && LOG="$HOME/miner_guard.log" && LOCK="/tmp/miner_guard_$(whoami).lock"\n' if "LOG=" in content and "id -u" not in content[:200]: content = head + content sftp = client.open_sftp() with sftp.file(remote_path, "w") as f: f.write(content) sftp.chmod(remote_path, 0o755) sftp.close() # 用户 crontab crontab_line = cron_line + "\n" tmp_cron = "/tmp/miner_guard_cron_%s" % os.getpid() sftp = client.open_sftp() with sftp.file(tmp_cron, "w") as f: f.write(crontab_line) sftp.close() sin, sout, serr = client.exec_command( "(crontab -l 2>/dev/null | grep -v miner_guard || true; cat %s) | crontab - 2>&1; rm -f %s; crontab -l 2>/dev/null" % (tmp_cron, tmp_cron), timeout=10 ) out = sout.read().decode("utf-8", errors="replace") err = serr.read().decode("utf-8", errors="replace") if "miner_guard" in out: print("\n[成功] 已安装,每 30 分钟执行") else: print("\n[警告] crontab 可能未添加,错误: %s" % (err or out)) print(" 请 SSH 登录后执行: (crontab -l 2>/dev/null; echo '%s') | crontab -" % cron_line.strip()) client.close() print("\n日志: %s" % log_path) print("=" * 60) if __name__ == "__main__": main()