112 lines
3.9 KiB
Python
112 lines
3.9 KiB
Python
#!/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()
|