fawdyinc/shellguard
GitHub: fawdyinc/shellguard
ShellGuard 是一款 MCP 服务器,让 LLM 代理通过 SSH 安全地对远程服务器进行只读的 bash 访问,用于自动化运维诊断。
Stars: 16 | Forks: 4
# ShellGuard
别再把终端输出复制粘贴给你的 AI 了。让你的 LLM 通过 SSH 登录进去自己看吧。
ShellGuard 是一个 [MCP](https://modelcontextprotocol.io/) 服务器,允许 LLM 代理通过 SSH 对远程服务器进行受控的 bash 访问。将你的 AI 连接到生产、预发布或开发服务器,让它运行诊断、检查日志、查询数据库并进行故障排除——全程解放双手。
ShellGuard 是由 [Fawdy](https://fawdy.com) 团队构建的开源安全层。它为 Fawdy 基于 AI 的 Linux 服务器调查工具提供支持,该工具可提供通俗易懂的根本原因分析。
你可以将 ShellGuard 与任何兼容 MCP 的 AI 代理独立使用,也可以通过 [Fawdy](https://fawdy.com) 体验完整的调查功能。
## 为什么选择 ShellGuard?
AI 代理功能强大,但赋予它们对生产服务器无限制的 shell 访问权限是有风险的。ShellGuard 通过在命令级别强制执行只读访问来解决此问题。每条命令在执行前都会被解析、根据白名单进行验证并重构。如果代理尝试执行破坏性操作,ShellGuard 会阻止它,并告知代理应该怎么做。
命令仅限于精选的观察和诊断工具。破坏性操作将被拦截,并提供可操作的建议,以便 LLM 自行纠正并继续调查:
- `wget -r` -> `"不允许递归下载"`
- `tail -f` -> `"跟随模式会一直挂起直到超时。请使用 tail -n 100 查看最近的行。"`
- `sed` -> `"流编辑可能会修改文件——仅允许只读访问。请使用 grep 进行搜索。"`
- `$HOME/file` -> `"变量扩展不会展开。请使用绝对路径。"`
## 快速开始
### 安装
```
brew install fawdyinc/tap/shellguard
```
或下载最新的二进制文件:
```
curl -fsSL https://raw.githubusercontent.com/fawdyinc/shellguard/main/install.sh | sh
```
或使用 Go:
```
go install github.com/fawdyinc/shellguard/cmd/shellguard@latest
```
### 与 MCP 客户端配置
ShellGuard 作为 stdio MCP 服务器启动——无需任何参数。将其添加到你选择的 MCP 客户端中:
## 它的功能
ShellGuard 向 LLM 暴露了 6 个工具:
| 工具 | 描述 |
| --------------- | ------------------------------------------------------------- |
| `connect` | 建立到远程主机的 SSH 连接 |
| `execute` | 在远程主机上运行经过验证的 shell 命令 |
| `disconnect` | 关闭 SSH 连接 |
| `sleep` | 在诊断检查之间等待(最长 15 秒) |
| `provision` | 将诊断工具(`rg`、`jq`、`yq`)部署到远程主机 |
| `download_file` | 通过 SFTP 从远程主机下载文件(限制 50MB) |
可以通过 `disabled_tools` 配置选项或 `SHELLGUARD_DISABLED_TOOLS` 环境变量禁用 `provision`、`download_file` 和 `sleep`。
LLM 连接到服务器,运行命令并读取输出——这与手动操作的工作流程相同,但无需进行上下文切换。
## 工作原理
每条命令在到达远程主机之前都会经过一个 pipeline:
1. **解析** -- bash 被解析为 AST。Shell 技巧(分号、重定向、命令替换等)在语法级别会被拒绝。
2. **验证** -- 根据精选的命令白名单(带有显式的黑名单)检查命令、标志和参数。默认拒绝。
3. **重构** -- 对参数重新加引号以防止注入。
4. **执行** -- 命令通过 SSH 运行,具有单命令超时和输出截断功能。
有关完整详细信息,请参阅 [ARCHITECTURE.md](docs/ARCHITECTURE.md)。
## SSH 配置
### 身份验证
ShellGuard 按以下顺序尝试身份验证方法,并在第一次成功时停止:
| 优先级 | 方法 | 来源 | 失败时 |
| -------- | ------ | ------ | ---------- |
| 1 | 显式密钥 | `connect` 中的 `identity_file` 参数 | **致命错误** -- 连接立即失败 |
| 2 | ssh-agent | `SSH_AUTH_SOCK` unix 套接字 | 静默 -- 跳过 |
| 3 | 默认密钥 | `~/.ssh/id_ed25519`, `id_ecdsa`, `id_rsa` | 静默 -- 跳过 |
在默认密钥发现期间,受密码保护的密钥会被静默跳过。如果你通过 `identity_file` 指定了受密码保护的密钥,连接将会失败。请先将密钥添加到你的 agent 中:`ssh-add ~/.ssh/my_key`。
### SSH 模式
ShellGuard 支持两种 SSH 模式:
| 模式 | 描述 |
| ---- | ----------- |
| `native` | **(默认)** 使用 Go 的内置 SSH 库。读取 `~/.ssh/config` 中的 `HostName`、`User`、`Port` 和 `IdentityFile`。轻量级,无外部依赖。 |
| `system` | 使用本地 `ssh` 二进制文件。支持完整的 `~/.ssh/config`,包括 `ProxyJump`、`ProxyCommand`、`Match` 块和所有其他 OpenSSH 功能。需要安装 `ssh`。 |
如果你通过堡垒主机进行连接,使用 `ProxyJump`,或者依赖 SSH 配置中的 `Match` 块,请启用 system 模式:
```
ssh:
mode: system
```
```
export SHELLGUARD_SSH_MODE=system
```
如果 `mode` 设置为 `system` 但未找到 `ssh` 二进制文件,ShellGuard 将记录警告并回退到 native 模式。
**Native 模式限制:** 不支持 `Match` 指令、`ProxyJump`、`ProxyCommand` 和 `ForwardAgent`。如果你的基础架构需要这些功能,请使用 `system` 模式。
**System 模式注意事项:**
- 主机密钥验证完全由 OpenSSH 处理。`host_key_checking` 和 `known_hosts_file` 设置仅在 native 模式下适用。
- 连接使用 OpenSSH `ControlMaster` 进行多路复用,因此每个主机只有第一个连接需要支付 SSH 握手开销。
### 主机密钥验证
ShellGuard 使用 `~/.ssh/known_hosts` 验证 SSH 主机密钥。提供三种模式:
| 模式 | 行为 |
| ---- | -------- |
| `accept-new` | **(默认)** 首次使用时信任。未知主机将被接受并写入 `known_hosts`。密钥更改将被拒绝。 |
| `strict` | 要求主机密钥已存在于 `known_hosts` 中。未知主机将被拒绝。 |
| `off` | 完全禁用主机密钥验证。 |
如果主机密钥已更改,请从你的 `known_hosts` 文件中删除旧条目。
### 配置
可以在 YAML 配置文件中或通过环境变量指定设置。环境变量优先。
**配置文件位置:** `$XDG_CONFIG_HOME/shellguard/config.yaml`(默认:`~/.config/shellguard/config.yaml`)
```
ssh:
mode: "native" # native | system
connect_timeout: "10s" # default 10s
retries: 2 # default 2
retry_backoff: "250ms" # default 250ms
host_key_checking: "accept-new" # accept-new | strict | off (native mode only)
known_hosts_file: "~/.ssh/known_hosts" # native mode only
```
| YAML 字段 | 环境变量 | 默认值 | 描述 |
| ---------- | -------------------- | ------- | ----------- |
| `ssh.mode` | `SHELLGUARD_SSH_MODE` | `native` | SSH 模式:`native`(内置)或 `system`(使用本地 `ssh` 二进制文件) |
| `ssh.connect_timeout` | `SHELLGUARD_SSH_CONNECT_TIMEOUT` | `10s` | TCP + SSH 握手超时 |
| `ssh.retries` | `SHELLGUARD_SSH_RETRIES` | `2` | 连接/执行重试次数 |
| `ssh.retry_backoff` | `SHELLGUARD_SSH_RETRY_BACKOFF` | `250ms` | 基础退避(指数级:`backoff * 2^attempt`) |
| `ssh.host_key_checking` | `SHELLGUARD_SSH_HOST_KEY_CHECKING` | `accept-new` | 主机密钥验证模式(仅限 native 模式) |
| `ssh.known_hosts_file` | `SHELLGUARD_SSH_KNOWN_HOSTS_FILE` | `~/.ssh/known_hosts` | known_hosts 文件的路径(仅限 native 模式) |
## 工具包置备
远程服务器并不总是有你想要的工具。在 `connect` 时,ShellGuard 会探测 `rg`、`jq` 和 `yq`。如果缺少任何一个,LLM 可以调用 `provision` 来部署它们:
| 工具 | 版本 | 架构 |
| -------------- | ------- | --------------- |
| `rg` (ripgrep) | 14.1.1 | x86_64, aarch64 |
| `jq` | 1.7.1 | x86_64, aarch64 |
| `yq` | 4.52.2 | x86_64, aarch64 |
二进制文件从 GitHub Releases 下载并经过 SHA-256 验证,在本地缓存,并部署到远程主机的 `~/.shellguard/bin/` 目录下。
## 库使用
ShellGuard 可以作为 Go 库使用:
```
package main
import (
"context"
"log/slog"
"os"
"github.com/fawdyinc/shellguard"
)
func main() {
ctx := context.Background()
logger := slog.New(slog.NewTextHandler(os.Stderr, nil))
err := shellguard.RunStdio(ctx, shellguard.Config{Logger: logger})
if err != nil {
os.Exit(1)
}
}
```
有关高级用法,请参阅下方的[自定义配置](#custom-configuration)和[自定义执行器](#custom-executor-backend)部分。
### 自定义配置
```
import (
"github.com/fawdyinc/shellguard"
"github.com/fawdyinc/shellguard/manifest"
"github.com/fawdyinc/shellguard/server"
)
manifests, _ := manifest.LoadEmbedded()
// Add or remove commands as needed
core, err := shellguard.New(shellguard.Config{
Manifests: manifests, // Custom registry (nil = embedded defaults)
Executor: myCustomExecutor, // Custom backend (nil = SSH)
Name: "my-server", // MCP server name
Version: "1.0.0", // MCP server version
})
```
### 自定义执行器后端
实现 `server.Executor` 接口以使用非 SSH 后端:
```
type Executor interface {
Connect(ctx context.Context, params ssh.ConnectionParams) error
Execute(ctx context.Context, host, command string, timeout time.Duration) (ssh.ExecResult, error)
ExecuteRaw(ctx context.Context, host, command string, timeout time.Duration) (ssh.ExecResult, error)
SFTPSession(host string) (ssh.SFTPClient, error)
Disconnect(host string) error
}
```
## 测试
```
make test # Run all tests
make test-race # Run with race detector
make lint # Run go vet
```
## 项目结构
```
shellguard/
shellguard.go # Top-level constructor (New, RunStdio)
cmd/shellguard/ # CLI entrypoint
server/ # MCP server core, tool registration, Executor interface
parser/ # Shell AST parser (mvdan.cc/sh/v3)
validator/ # Command/flag/SQL validation engine
manifest/ # YAML command registry (embed.FS)
manifests/ # allowed command manifests
manifests/denied/ # denied command manifests
ssh/ # SSH manager, ShellQuote, ReconstructCommand
output/ # Output truncation (64KB cap)
toolkit/ # Diagnostic tool provisioning (rg, jq, yq)
```
## 体验完整功能
ShellGuard 本身已经非常出色,但如果你想获得带有通俗易懂的根本原因报告的自动化事件调查功能,请试试 [Fawdy](https://fawdy.com)。它通过 ShellGuard 连接到你的 Linux 服务器并自动调查事件。设置只需 10 分钟。
## 许可证
Apache License 2.0。有关详细信息,请参阅 [LICENSE](LICENSE)。
Cursor
转到:`Settings` -> `Cursor Settings` -> `MCP` -> `Add new global MCP server` 或者将其粘贴到你的 `~/.cursor/mcp.json` 文件中。你也可以通过在项目文件夹中创建 `.cursor/mcp.json` 来按项目安装。有关更多信息,请参阅 [Cursor MCP 文档](https://docs.cursor.com/context/model-context-protocol)。 ``` { "mcpServers": { "shellguard": { "command": "shellguard" } } } ```Claude Desktop
将以下内容添加到你的 Claude Desktop 配置文件中。有关更多信息,请参阅 [Claude Desktop MCP 文档](https://modelcontextprotocol.io/quickstart/user)。 - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json` - Windows: `%APPDATA%\Claude\claude_desktop_config.json` ``` { "mcpServers": { "shellguard": { "command": "shellguard" } } } ```Claude Code
运行此命令。有关更多信息,请参阅 [Claude Code MCP 文档](https://docs.anthropic.com/en/docs/claude-code/mcp)。 ``` claude mcp add shellguard -- shellguard ```OpenCode
将此内容添加到你的 OpenCode 配置文件中。有关更多信息,请参阅 [OpenCode MCP 文档](https://opencode.ai/docs/mcp-servers)。 ``` { "mcp": { "shellguard": { "type": "local", "command": ["shellguard"], "enabled": true } } } ```VS Code / GitHub Copilot
将以下内容添加到你的 VS Code `settings.json` 或 `.vscode/mcp.json` 中。有关更多信息,请参阅 [VS Code MCP 文档](https://code.visualstudio.com/docs/copilot/chat/mcp-servers)。 #### 用户设置 (`settings.json`) ``` { "mcp": { "servers": { "shellguard": { "type": "stdio", "command": "shellguard" } } } } ``` #### 工作区配置 (`.vscode/mcp.json`) ``` { "servers": { "shellguard": { "type": "stdio", "command": "shellguard" } } } ```Zed
将以下内容添加到你的 Zed 设置文件(`~/.config/zed/settings.json`)中。有关更多信息,请参阅 [Zed MCP 文档](https://zed.dev/docs/assistant/model-context-protocol)。 ``` { "context_servers": { "shellguard": { "command": { "path": "shellguard", "args": [] } } } } ```Roo Code
转到:`Roo Code Settings` -> `MCP Servers` -> `Edit MCP Settings` 或者将以下内容添加到你的 Roo Code MCP 设置文件中。有关更多信息,请参阅 [Roo Code MCP 文档](https://docs.roocode.com/features/mcp/using-mcp-in-roo)。 ``` { "mcpServers": { "shellguard": { "command": "shellguard" } } } ```标签:EVTX分析, LLM代理, MCP, SSH, Streamlit, 内存分配, 命令行控制, 日志审计, 系统诊断, 自动化payload嵌入, 访问控制, 远程运维