kali-mcp
by lzy1111xoy
README.md
# Kali-MCP
基于 MCP (Model Context Protocol) 的远程 Kali Linux 终端控制服务器。允许 AI 客户端(Claude Desktop、Cursor、Cline 等)通过 HTTP/SSE 远程操控真实的 Kali Shell 会话,适用于安全研究、渗透测试自动化、远程运维等场景。
## 架构概览
```
┌─────────────────┐ HTTP + SSE ┌──────────────────────┐ stdin/stdout ┌─────────────────┐ node-pty ┌─────────────────┐
│ AI 客户端 │ ───────────────► │ Python 主控服务器 │ ────────────────► │ Node.js PTY │ ─────────────► │ Kali Linux │
│ Claude/Cursor │ X-Kali-Token │ FastMCP + Uvicorn │ JSON-RPC 2.0 │ 引擎 │ spawn/write │ Shell (root) │
│ │ ◄─────────────── │ TokenAuthMiddleware │ ◄──────────────── │ (node-pty) │ ◄───────────── │ │
└─────────────────┘ SSE 流 └──────────────────────┘ pty.output └─────────────────┘ 输出回传 └─────────────────┘
```
- **Python 主控** (`mcp_kali_server.py`):基于 FastMCP 框架,对外暴露 MCP 工具,负责会话管理、安全审查、密码认证
- **Node.js PTY 引擎** (`pty_engine/index.js`):通过 `node-pty` 创建真实伪终端,执行命令并回传输出
- **通信协议**:Python 与 Node.js 之间使用 JSON-RPC 2.0 over stdin/stdout
## 环境要求
### 服务端(Kali Linux 主机)
| 依赖 | 最低版本 | 说明 |
|------|---------|------|
| Python | 3.10+ | 需支持 `tuple[str, int]` 等新语法 |
| Node.js | 18+ | PTY 引擎运行环境 |
| npm | 随 Node.js | 安装 `node-pty` 依赖 |
| Kali Linux | 任意版本 | 建议以 root 运行(PS1 与 HOME 默认指向 `/root`) |
### 客户端(AI 助手)
任意支持 MCP SSE 传输的客户端:Claude Desktop、Cursor、Cline、Continue 等。
## 部署步骤
### 1. 获取项目代码
将项目目录复制到 Kali Linux 任意位置(路径已动态化,无需固定目录):
```bash
cp -r kali-mcp /opt/kali-mcp
cd /opt/kali-mcp
```
### 2. 创建虚拟环境并安装 Python 依赖
```bash
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
依赖清单(见 [requirements.txt](kali-mcp/requirements.txt)):
- `mcp>=1.28,<2` — MCP 协议核心库(Anthropic 官方 SDK v1.x;**务必带上 `<2` 上界**,`pip install mcp` 现在默认装 2.x,2.x 已移除 `mcp.server.fastmcp`,代码会 import 失败)
- `pydantic>=2.0.0` — 数据模型校验
- `anyio>=4.0.0` — 异步兼容层
- `uvicorn`、`starlette` — ASGI 服务器与中间件
### 3. 安装 Node.js PTY 引擎依赖
```bash
cd pty_engine
npm install
cd ..
```
依赖:`node-pty@^1.0.0`(见 [package.json](kali-mcp/pty_engine/package.json))。
> **注意**:`node-pty` 是原生模块,安装时需要 `make` 与 `g++`。Kali 默认已包含,若缺失请执行 `apt install -y build-essential python3-dev`。
### 4. 验证安装
```bash
python3 -c "from mcp.server.fastmcp import FastMCP; print('Python 依赖 OK')"
cd pty_engine && node -e "import('node-pty').then(()=>console.log('Node PTY OK'))" && cd ..
```
## 运行方式
### 命令行参数
```
python3 mcp_kali_server.py [--host addr:port] [-t PASSWORD]
```
| 参数 | 默认值 | 说明 |
|------|--------|------|
| `--host <addr:port>` | `0.0.0.0:8000` | 服务监听地址与端口 |
| `-t, --token <password>` | 无 | 连接密码;**不传则禁用认证**(仅建议本地调试) |
### 启动示例
```bash
# 先激活虚拟环境
source venv/bin/activate
# 1. 本地调试(无认证,仅监听本机)
python3 mcp_kali_server.py --host 127.0.0.1:8000
# 2. 局域网开放 + 密码认证(推荐)
python3 mcp_kali_server.py --host 0.0.0.0:8000 -t MySecretPass123
# 3. 自定义端口
python3 mcp_kali_server.py --host 0.0.0.0:9000 -t MySecretPass123
# 4. 查看帮助
python3 mcp_kali_server.py --help
```
启动成功后会输出:
```
INFO - === Kali-MCP Server Starting (Root Mode) ===
INFO - Node.js version: v18.x.x
INFO - PTY Engine started successfully
INFO - 密码认证已启用
INFO - Kali-MCP Server ready
INFO - Uvicorn running on http://0.0.0.0:8000
```
未启用密码时会出现警告:
```
WARNING - 认证已禁用,仅建议本地调试使用
```
### 环境变量
| 变量名 | 默认值 | 说明 |
|--------|--------|------|
| `KALI_QUEUE_SIZE` | `2000` | 每个会话输出队列容量,超出时丢弃最旧数据。高频输出场景可调大 |
```bash
# 示例:放大输出队列到 10000
KALI_QUEUE_SIZE=10000 python3 mcp_kali_server.py -t MyPass
```
### 后台运行(生产环境)
推荐用 `systemd` 或 `screen`/`tmux` 托管:
```bash
# 使用 nohup 简单后台运行
nohup python3 mcp_kali_server.py --host 0.0.0.0:8000 -t MySecretPass123 > /dev/null 2>&1 &
# 或使用 systemd(推荐)
cat > /etc/systemd/system/kali-mcp.service <<'EOF'
[Unit]
Description=Kali-MCP Server
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/kali-mcp
ExecStart=/usr/bin/python3 /opt/kali-mcp/mcp_kali_server.py --host 0.0.0.0:8000 -t MySecretPass123
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now kali-mcp
```
### 日志位置
日志写入 `<项目目录>/logs/mcp.log`,同时输出到 stdout。日志文件通过后台线程异步写入,不阻塞事件循环。
## AI 客户端配置
服务端启动后,SSE 端点为 `http://<host>:<port>/sse`。各客户端配置方式如下:
### Claude Desktop
编辑配置文件:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"kali-terminal": {
"url": "http://192.168.1.100:8000/sse",
"headers": {
"X-Kali-Token": "MySecretPass123"
}
}
}
}
```
> 将 `192.168.1.100` 替换为 Kali 主机实际 IP。若服务端未启用密码认证(未传 `-t`),可省略 `headers` 字段。
### Cursor
进入 `Settings → MCP → Add new MCP Server`,或编辑 `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"kali-terminal": {
"url": "http://192.168.1.100:8000/sse",
"headers": {
"X-Kali-Token": "MySecretPass123"
}
}
}
}
```
### Cline (VS Code)
编辑 `~/.cline/mcp_settings.json`:
```json
{
"mcpServers": {
"kali-terminal": {
"url": "http://192.168.1.100:8000/sse?token=MySecretPass123"
}
}
}
```
> 不支持自定义 Header 的客户端可改用查询参数 `?token=` 传递密码,两种方式等价。
### 通用验证(curl)
配置客户端前,可用 curl 验证服务是否正常:
```bash
# 无密码模式
curl -N http://127.0.0.1:8000/sse
# Header 方式认证
curl -N -H "X-Kali-Token: MySecretPass123" http://192.168.1.100:8000/sse
# 查询参数方式认证
curl -N "http://192.168.1.100:8000/sse?token=MySecretPass123"
# 错误密码测试(应返回 401)
curl -i -H "X-Kali-Token: wrong" http://192.168.1.100:8000/sse
```
成功时会收到 SSE 事件流(`event: endpoint` 等),失败返回 `HTTP/1.1 401 Unauthorized`。
## MCP 工具说明
服务端暴露以下 9 个 MCP 工具,AI 客户端可按需调用:
### 会话管理
| 工具 | 参数 | 说明 |
|------|------|------|
| `create_session` | `session_id` (必填), `shell` (默认 `/bin/bash`), `cwd` (默认 `/root`), `rows`, `cols`, `tag` | 创建新的终端会话 |
| `list_sessions` | 无 | 列出所有活跃会话及其状态、PID、空闲时长 |
| `close_session` | `session_id` | 关闭并销毁指定会话 |
| `resize_session` | `session_id`, `rows`, `cols` | 调整终端尺寸 |
### 命令执行
| 工具 | 参数 | 说明 |
|------|------|------|
| `send_line` | `session_id`, `line` | 发送一行命令(自动加回车),**经过安全审查** |
| `send_input` | `session_id`, `text` | 发送原始文本(不加回车,用于交互式输入) |
| `send_control` | `session_id`, `key` | 发送控制键:`c`/`d`/`z`/`up`/`down`/`left`/`right`/`tab`/`esc`/`enter`/`backspace` |
### 输出读取
| 工具 | 参数 | 说明 |
|------|------|------|
| `read_output` | `session_id`, `timeout` (默认 1.0s), `lines` (默认 0=全部), `raw` (默认 false) | 读取会话输出,默认剥离 ANSI 转义 |
| `wait_for` | `session_id`, `pattern` (正则), `timeout` (默认 60s), `case_sensitive` | 阻塞等待输出中出现匹配模式 |
| `get_screen` | `session_id` | 获取当前终端屏幕快照与光标位置 |
### MCP 资源
- `sessions://current` — 以纯文本形式返回当前所有活跃会话概览
### 典型调用流程
AI 客户端的典型工作流:
```
1. create_session(session_id="shell-1") # 创建会话
2. send_line(session_id="shell-1", line="ls -la") # 执行命令
3. read_output(session_id="shell-1") # 读取结果
4. send_line(session_id="shell-1", line="nmap -sV 192.168.1.0/24")
5. wait_for(session_id="shell-1", pattern="Nmap done", timeout=300)
6. read_output(session_id="shell-1", lines=100)
7. close_session(session_id="shell-1") # 清理
```
## 安全说明
### 命令安全审查
`send_line` 会经过 [SecurityPolicy](kali-mcp/mcp_kali_server.py#L144-L159) 审查,以下命令会被拦截并抛出 `PermissionError`:
- 危险正则:`rm -rf /`、`dd if=/dev/zero`、`mkfs.*`、`chmod 777 /`、fork bomb `:(){ :|:& };:` 等
- 禁止命令:`shutdown`、`reboot`、`halt`、`kill -9`、`pkill`、`killall`、`fdisk` 等
- 管道命令会递归检查每个子命令
> `send_input` 不经过安全审查(用于交互式输入如 sudo 密码),请谨慎使用。
### 密码认证机制
- 密码使用 **PBKDF2-HMAC-SHA256** 加盐哈希,10 万次迭代
- 内存中仅保留 `salt` + `hash_hex`,**不明文存储密码**
- 校验使用 `hmac.compare_digest` 常量时间比较,防时序攻击
- 认证失败返回 HTTP 401,日志仅记录客户端 IP,**不记录密码值**
### 网络安全建议
1. **生产环境务必启用密码**:`-t <强密码>`
2. **配合防火墙**:仅允许可信 IP 访问 8000 端口
3. **使用反向代理 + HTTPS**:通过 Nginx 加密 SSE 流,避免密码明文传输
4. **不要暴露到公网**:如必须公网访问,务必启用 HTTPS
### Nginx 反向代理示例(HTTPS 加密)
```nginx
server {
listen 443 ssl;
server_name kali.example.com;
ssl_certificate /etc/ssl/certs/kali.pem;
ssl_certificate_key /etc/ssl/private/kali.key;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off; # SSE 必须关闭缓冲
proxy_read_timeout 86400s; # 长连接超时
proxy_set_header Host $host;
}
}
```
客户端配置改为 `https://kali.example.com/sse`。
## 故障排查
### 启动失败
| 报错 | 原因与解决 |
|------|-----------|
| `Node.js not installed` | 未安装 Node.js,执行 `apt install -y nodejs` |
| `PTY engine script not found` | `pty_engine/index.js` 不存在,确认在项目目录下启动 |
| `PTY Engine startup timeout` | Node.js 启动超时,检查 `node-pty` 是否安装成功(重新 `npm install`) |
| `无效的 --host 格式` | `--host` 参数缺少冒号或端口非数字,格式应为 `addr:port` |
| `端口 xxx 越界` | 端口需在 1-65535 范围内 |
| `ModuleNotFoundError: No module named 'mcp'` | Python 依赖未装,执行 `pip install -r requirements.txt` |
| `ModuleNotFoundError: No module named 'mcp.server.fastmcp'` | 装到了 MCP SDK v2.x(默认)。v2 已移除 `fastmcp`。需降级到 v1.x:`pip install "mcp>=1.28,<2"` |
### 客户端连接失败
| 现象 | 原因与解决 |
|------|-----------|
| 401 Unauthorized | 密码错误或未传 `X-Kali-Token`;确认服务端启用了 `-t` 且密码一致 |
| 连接超时 | 防火墙未放行端口;检查 Kali 主机 `iptables` / `ufw` |
| SSE 流立即断开 | 中间代理缓冲了流,Nginx 需设置 `proxy_buffering off` |
| 工具调用无响应 | 会话已终止或 PID 不存在,调用 `list_sessions` 确认状态 |
### 查看日志
```bash
# 实时查看服务日志
tail -f logs/mcp.log
# 查看认证失败记录
grep "认证失败" logs/mcp.log
# 查看 PTY 引擎输出
grep "\[PTY-Engine\]" logs/mcp.log
```
### 重新安装 PTY 引擎
若 `node-pty` 原生模块损坏(升级 Node.js 后常见):
```bash
cd pty_engine
rm -rf node_modules package-lock.json
npm install
```
## 性能特性
- **异步日志**:文件日志通过后台线程异步写入,不阻塞事件循环
- **输出队列限流**:每会话默认 2000 条缓冲,超出丢弃最旧并警告(可通过 `KALI_QUEUE_SIZE` 调整)
- **尾部缓冲匹配**:`wait_for` 维护 10000 字节尾部缓冲,避免每次全量拼接历史
- **PTY 引擎自动重启**:Node.js 子进程崩溃时自动重启并清理悬挂请求
- **空闲会话清理**:超过 1 小时未活动的会话自动关闭
## 项目结构
```
kali-mcp/
├── mcp_kali_server.py # Python 主控服务器(入口)
├── requirements.txt # Python 依赖
├── pty_engine/
│ ├── index.js # Node.js PTY 引擎
│ ├── package.json # Node.js 依赖
│ └── package-lock.json
├── venv/ # 部署时手动创建
└── logs/ # 运行时自动创建
└── mcp.log
```
## 许可证
本项目仅供合法的安全研究、教学与授权测试使用。使用者需自行遵守所在地区的法律法规,作者不对任何滥用行为承担责任。
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues