内容
# Aegis-SSH-MCP






**为 AI 代理提供安全、受限的 SSH 访问权限,而无需授予 shell 访问权限。**
Aegis-SSH-MCP 是一个小型、MCP 原生的桥梁,允许 AI 代理在 Linux 主机上通过 SSH 运行**批准的命令**。
它的设计适用于那些希望拥有智能基础设施工作流,但不希望为 AI 提供无限制的终端访问权限的人员。
Aegis 位于您的 MCP 客户端和服务器之间。它检查每个请求的命令是否符合您的规则,仅当命令被允许时才打开短暂的 SSH 会话,返回结果,然后断开连接。
<img width="1536" height="1024" alt="image" src="https://github.com/user-attachments/assets/6e4b1046-e1ec-4d9e-88d5-434c4c71b07e" />
Aegis 不会取代 SSH、Linux 权限、sudo 或主机强化。它帮助您保持这些控制处于主导地位,同时为 MCP 客户端提供一种更安全的方式与真实系统交互。
快速链接:
- [快速入门](#快速入门)
- [工作原理](#工作原理)
- [核心概念](#核心概念)
- [安全模型](#安全模型)
- [客户端示例:LibreChat](#客户端示例:LibreChat)
- [文档](#文档)
## Aegis 解决了什么问题?
当 AI 代理可以检查日志、检查服务、查看容器或运行例行操作命令时,它们非常有用。
简单但危险的方法是:
> 给代理 SSH 访问权限,希望它表现良好。
Aegis 采取了一种更安全的方法:
> 给代理一个狭窄的 MCP 工具,使其只能运行您批准的命令。
这意味着代理可以执行诸如检查 Docker 状态、读取日志或运行诊断等操作,而无需获得持久的 shell、伪终端、SSH 代理转发或隐藏的会话状态。
## 适用场景
Aegis 在以下情况下非常有用:
- 将 MCP 客户端连接到 Linux 主机进行 SSH 操作
- 允许代理运行一组有限的操作命令
- 保持命令访问权限按主机范围和基于规则
- 审计代理尝试执行的操作
- 保留现有的 SSH、Linux、sudo 和主机安全模型
## Aegis 不是什么
Aegis 的设计故意保持狭窄。
它不是 SSH、Linux 权限、sudo、IAM、RBAC、主机强化或人工判断的替代品。
它不会:
- 为代理提供持久的 shell
- 创建隐藏的会话状态
- 提供完整的 OS 级别沙盒
- 通过人工工作流批准命令
- 将 MCP 变成完整的基础设施自动化平台
这就是设计。
Aegis 只做一件事:
**它为 MCP 客户端提供了一种受控、可审计的方式来运行批准的 SSH 命令,并保持其余安全模型完整。**
## 快速入门
运行 Aegis 的推荐方式是使用附带的 [`docker-compose.yml`](docker-compose.yml)。
先决条件:
- Docker Compose
- 支持 SSE 的 MCP 客户端
- 可达的 Linux 主机
- 具有最少权限的远程用户的 SSH 密钥或密码
默认情况下,Aegis 在以下地址暴露 MCP:
```text
http://localhost:8443
```
启动规则配置文件位于 [`rules/`](rules/)。部署时保留或复制这些配置文件;快速入门只需要您添加主机配置和 SSH 凭证。
### 1. 创建本地文件夹
在 `docker-compose.yml` 旁边创建以下文件夹(如果它们不存在):
```text
./configs
./keys
./certs # 仅在启用 HTTPS 时需要
```
存储库中已经包含 `./rules` 和启动规则配置文件。
### 2. 添加 SSH 密钥
将 Aegis 应使用的 SSH 私钥放入 `keys/` 中。
保持密钥权限严格,并在可能的情况下使用专用、最少权限的 SSH 用户。
### 3. 添加主机配置
创建 `configs/docker.json`:
```json
{
"alias": "docker",
"host_ip": "192.168.1.10",
"ssh_port": 22,
"ssh_user": "ops",
"auth_method": "key",
"key_path": "/keys/docker_ed25519",
"rule_profile": "docker-readonly",
"timeout_seconds": 30,
"host_key_fingerprint": "SHA256:replace-this-with-your-real-host-key",
"api_keys": [
"change-me-docker-key"
]
}
```
重要部分是:
- `alias`:此主机的友好名称
- `ssh_user`:Aegis 连接到的 Linux 用户
- `key_path`:容器内的私钥路径
- `rule_profile`:主机使用的命令规则
- `host_key_fingerprint`:固定 SSH 主机密钥
- `api_keys`:允许访问此主机端点的 bearer token
### 4. 启动 Aegis
```bash
docker compose pull
docker compose up -d
docker compose logs -f aegis-ssh-mcp
```
### 5. 连接您的 MCP 客户端
使用此 SSE 端点:
```text
http://localhost:8443/mcp/docker/sse
```
发送在 `configs/docker.json` 中配置的 bearer token:
```text
Authorization: Bearer change-me-docker-key
```
您可以使用 curl 测试可达性:
```bash
curl -i -N \
-H "Authorization: Bearer change-me-docker-key" \
http://localhost:8443/mcp/docker/sse
```
有效的 token 应返回 `200 OK` 并保持 SSE 流打开。
### 可选:从源代码构建
```bash
git clone https://github.com/sparksbenjamin/Aegis-SSH-MCP.git
cd Aegis-SSH-MCP
go build -o aegis-ssh-mcp .
```
## 工作原理
对于每个命令请求,Aegis 都会遵循相同的流程:
1. MCP 客户端请求 Aegis 运行命令。
2. Aegis 检查该主机端点的 bearer token。
3. Aegis 解析命令。
4. Aegis 拒绝不安全的 shell 行为,例如链接、重定向和命令替换。
5. Aegis 根据主机分配的规则配置文件检查命令。
6. 如果命令被允许,Aegis 打开一个新的非交互式 SSH 会话。
7. Aegis 运行命令、捕获结果、记录尝试并断开连接。
不会向代理提供持久的 shell。
<details>
<summary>架构视图</summary>
```text
+-------------------+
| MCP 客户端 / LLM |
| Claude / OpenAI |
| LibreChat / SSE |
+---------+---------+
|
| 通过 HTTP/SSE 或 stdio 的 MCP
|
+---------v---------+
| Aegis-SSH-MCP |
|-------------------|
| Bearer Auth |
| 规则验证 |
| 审计日志 |
| 主机隔离 |
| 短暂 SSH |
+---------+---------+
|
| 标准 SSH
|
+---------v---------+
| 远程 Linux 主机 |
|-------------------|
| SSH 权限 |
| sudo 策略 |
| auditd/journald |
| 主机安全 |
+-------------------+
```
</details>
## 核心概念
### 配置可以是固定主机或动态配置文件
[`configs/`](configs/) 中的每个 JSON 文件都描述了一个固定的远程主机或一个动态 SSH 配置文件。
固定主机配置创建:
- 一个 MCP 端点
- 一个主机范围的 SSH 工具
- 一个分配的规则配置文件
- 一个用于 SSE 的 bearer token 边界
例如,具有别名 `docker` 的主机变为:
```text
/mcp/docker/sse
```
如果一个代理需要访问两个主机,请在 MCP 客户端中添加 Aegis 两次:每个主机别名一个端点和一个 token。
动态配置文件使用相同的规则和 SSH 执行引擎,但 MCP 工具调用提供主机:
```json
{
"config_type": "dynamic",
"alias": "linux-dynamic",
"ssh_user": "ops",
"auth_method": "key",
"key_path": "/keys/linux-dynamic.pem",
"rule_profile": "readonly-safe",
"api_keys": [
"change-me-linux-dynamic-key"
]
}
```
该配置文件创建 `aegis_ssh_linux-dynamic`,并带有两个必需参数:
```json
{
"host": "192.168.1.42",
"command": "uptime"
}
```
### 规则决定允许运行的内容
每个主机都指向一个规则配置文件:
```json
"rule_profile": "docker-readonly"
```
规则配置文件位于 [`rules/`](rules/),并定义在尝试 SSH 之前允许或阻止哪些命令。
启动配置文件包括:
- `readonly-safe`
- `debian-readonly`
- `debian-ops`
- `ubuntu-readonly`
- `ubuntu-ops`
- `rhel-readonly`
- `rhel-ops`
- `proxmox-readonly`
- `proxmox-ops`
- `docker-readonly`
- `docker-ops`
- `systemd-ops`
- `kubernetes-readonly`
- `network-diagnostics`
- `logs-readonly`
- `package-readonly`
### 验证发生在 SSH 之前
Aegis 在连接到远程主机之前验证命令。
验证流程是:
1. 将命令解析为可执行文件和参数。
2. 拒绝 shell 控制功能,如重定向、链接和命令替换。
3. 只允许有限的一组安全管道过滤器。
4. 应用可执行文件、参数和完整命令的黑名单检查。
5. 应用可执行文件、参数和完整命令的白名单检查。
6. 只有当命令通过验证时,才尝试 SSH。
## 安全模型
Aegis 使用纵深防御。它不是一个神奇的安全层;而是几个较小的边界共同工作。
| 边界 | 保护它 | 谁拥有它 |
| :--- | :--- | :--- |
| 客户端到 Aegis | 每个主机别名的 bearer token,可选 TLS/HTTPS | Aegis / 操作员 |
| Aegis 运行时 | 无 shell 的 distroless 容器,以非 root 用户运行 | Aegis |
| 命令检查 | 解析、shell 功能拒绝、参数检查、受限管道过滤器 | Aegis |
| Aegis 到主机 | 短暂的 SSH 会话和主机指纹固定 | Aegis / 操作员 |
| 远程主机 | Linux 权限、sudoers、auditd、journald、主机强化 | 主机操作员 |
推荐的生产环境:
- 使用专用的最少权限 SSH 用户
- 使用 `host_key_fingerprint` 固定 SSH 主机密钥
- 首先使用狭窄的规则配置文件
- 启用 TLS 或在受信任的反向代理后面运行
- 定期轮换 bearer token
- 集中收集 Aegis 日志
- 保持 sudo 策略明确和最小化
有关更深入的威胁模型,请参见 [`docs/security.md`](docs/security.md)。
## 可选主机设置
主机配置还可以包括:
- `stealth_mode`:为阻止的命令返回一个外观正常的假响应
- `fake_response`:启用 `stealth_mode` 时使用的自定义响应
- `redaction_enabled`:在返回结果之前屏蔽匹配的输出
- `redaction_patterns`:用于输出屏蔽的正则表达式模式
- `host_key_fingerprint`:推荐的 SSH 主机密钥固定
## 客户端示例:LibreChat
```yaml
mcpSettings:
allowedDomains:
- "192.168.100.184"
mcpServers:
aegis-docker:
type: sse
url: "http://192.168.100.184:8443/mcp/docker/sse"
headers:
Authorization: "Bearer change-me-docker-key"
timeout: 120000
initTimeout: 30000
```
## 文档
README 旨在帮助您快速了解和使用 Aegis。更深入的文档在这里:
- [`docs/security.md`](docs/security.md):威胁模型、验证逻辑、管道处理、容器强化和 SSH 会话行为
- [`docs/config.md`](docs/config.md):主机配置字段、热重载行为、别名、API 密钥和密钥路径
- [`docs/rules.md`](docs/rules.md):规则配置文件设计、白名单、黑名单、参数约束和启动配置文件
- [`docs/FAQ.md`](docs/FAQ.md):常见问题和操作说明
- [`docs/tech-specs/aegis-ssh-mcp-tech-spec.md`](docs/tech-specs/aegis-ssh-mcp-tech-spec.md):更深入的实现细节
- [`docs/readme-authoring.md`](docs/readme-authoring.md):本存储库的 README 编写指南
## 屏幕截图
<details>
<summary>打开屏幕截图</summary>


</details>
## 项目状态
Aegis 具有早期阶段的 API 和操作运行时。
当前功能包括:
- 通过 HTTP/SSE 的 MCP
- 通过 stdio 的 MCP
- 多主机配置
- 基于规则的命令验证
- 审计日志
- SSH 密钥身份验证
- 密码身份验证
- 主机指纹固定
- 每个请求的临时 SSH 执行
- 强化无 shell 的 distroless 容器运行时
- 可选的输出屏蔽
- 配置和规则更改的热重载
## 支持和贡献
对于错误、设置问题或操作反馈,请在此存储库中打开问题。
主要维护者:[@sparksbenjamin](https://github.com/sparksbenjamin)
欢迎贡献,特别是在以下方面:
- MCP 客户端互操作性
- 规则验证改进
- 可观察性
- 部署强化
- 传输支持
- 测试和验证
在进行大型更改之前,打开问题是协调方向的最佳方式。
## 许可证
MIT 许可证