#!/bin/sh # 此脚本在特权容器内运行,目标是安装CMD Agent到宿主机 # 容器以 --privileged --pid=host -v /:/host 启动 set -e echo "=== 宿主机信息 ===" nsenter -t 1 -u hostname nsenter -t 1 -n ip addr show | grep "inet " | head -5 echo "=== 创建目录 ===" mkdir -p /host/opt/xiaoxia-cmd-agent echo "=== 写入server.py ===" cat > /host/opt/xiaoxia-cmd-agent/server.py << 'PYEND' import http.server import subprocess import json import os import secrets TOKEN_FILE = "/etc/xiaoxia-cmd-agent.token" LOG_FILE = "/var/log/xiaoxia-cmd-agent.log" def ensure_token(): if not os.path.exists(TOKEN_FILE): os.makedirs(os.path.dirname(TOKEN_FILE), exist_ok=True) token = secrets.token_hex(16) with open(TOKEN_FILE, "w") as f: f.write(token) os.chmod(TOKEN_FILE, 0o600) with open(TOKEN_FILE) as f: return f.read().strip() class CmdHandler(http.server.BaseHTTPRequestHandler): def log_message(self, fmt, *args): try: with open(LOG_FILE, "a") as f: f.write("%s - %s\n" % (self.address_string(), fmt % args)) except Exception: pass def do_POST(self): if self.path == "/exec": auth = self.headers.get("Authorization", "") token = ensure_token() if auth != "xsa-" + token: self.send_response(401) self.end_headers() self.wfile.write(b"Unauthorized") return length = int(self.headers.get("Content-Length", 0)) body = json.loads(self.rfile.read(length)) cmd = body.get("command", "") timeout = body.get("timeout", 30) try: result = subprocess.run( cmd, shell=True, capture_output=True, text=True, timeout=timeout ) resp = { "exit_code": result.returncode, "stdout": result.stdout, "stderr": result.stderr } except subprocess.TimeoutExpired: resp = {"exit_code": -1, "stdout": "", "stderr": "timeout"} self.send_response(200) self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(json.dumps(resp).encode()) elif self.path == "/status": self.send_response(200) self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(json.dumps({"status": "ok", "version": "1.0"}).encode()) else: self.send_response(404) self.end_headers() if __name__ == "__main__": ensure_token() server = http.server.HTTPServer(("0.0.0.0", 18888), CmdHandler) print("CMD Agent listening on 0.0.0.0:18888") server.serve_forever() PYEND echo "=== 写入service文件 ===" cat > /host/etc/systemd/system/xiaoxia-cmd-agent.service << 'SVCEND' [Unit] Description=Xiaoxia CMD Agent After=network.target [Service] Type=simple ExecStart=/usr/bin/python3 /opt/xiaoxia-cmd-agent/server.py Restart=always RestartSec=5 [Install] WantedBy=multi-user.target SVCEND echo "=== 启动服务 ===" nsenter -t 1 -m -u -n -i systemctl daemon-reload nsenter -t 1 -m -u -n -i systemctl enable xiaoxia-cmd-agent nsenter -t 1 -m -u -n -i systemctl restart xiaoxia-cmd-agent sleep 2 echo "=== 服务状态 ===" nsenter -t 1 -m -u -n -i systemctl is-active xiaoxia-cmd-agent echo "=== TOKEN ===" nsenter -t 1 -m -u -n -i cat /etc/xiaoxia-cmd-agent.token echo "=== 测试 ===" nsenter -t 1 -m -u -n -i curl -s http://127.0.0.1:18888/status echo "" echo "=== 完成 ==="