一个加固的、自托管的 SSH 堡垒主机,具备基于 Vault 的密钥管理、RBAC 策略执行、完整会话录制和交互式管理 TUI——专为需要对生产基础设施进行可审计、零信任访问的团队而设计。
现代工程团队需要一种方式,为开发者提供完成工作所需的最低访问权限——不多也不少。传统的 SSH 密钥分发容易出错:密钥被共享、遗忘在笔记本电脑上,且撤销往往为时已晚。
ZTTP 通过充当进入基础设施的唯一门户来解决这一问题:
| 问题 | ZTTP 解决方案 |
|---|---|
| SSH 密钥共享在笔记本电脑上 | 密钥仅存在于 HashiCorp Vault 中——绝不落盘 |
| 无法了解谁做了什么 | 每次按键都以 .ttyrec 格式记录 |
| 对生产环境的一揽子访问 | 基于角色的策略引擎强制执行按环境划分的规则 |
| 无法终止活动会话 | 通过 gRPC 端点提供 Kill-switch,可随时终止任何实时会话 |
| 对审计人员不透明 | 管理 TUI 支持会话回放、文本日志和管理操作日志 |
开发者笔记本电脑
│
│ zttp
│ (底层:SSH 通过端口 2224)
▼
┌─────────────────────────────────────────────────────────┐
│ ZTTP 代理 │
│ │
│ ① 认证网关 — bcrypt/Argon2id 登录 TUI │
│ ② RBAC 引擎 — 环境感知策略检查 │
│ ③ Vault 获取 — 临时 SSH 密钥检索 │
│ ④ 桥接 — 透明 TCP 隧道 │
│ ⑤ 审计写入器 — ttyrec 帧记录器 │
└──────────┬──────────────────────────────────────────────┘
│ ssh(私有 IP,临时密钥)
▼
目标服务器
基础设施服务(Docker Compose):
.ttyrec 格式记录,带时间戳帧服务器(代理主机):
2224 上的公网或局域网可访问 IPmake(可选,但推荐)开发者(客户端):
ssh 命令)git clone https://gitlab.com/Nihal799/zttp.git
cd zttp
cp .env.example .env
编辑 .env 并至少设置以下内容:
PROXY_NODE_IP=<your-server-public-ip>
POSTGRES_PASSWORD=<a-strong-password>
VAULT_TOKEN=<a-strong-vault-token>
⚠️ 切勿提交你的
.env文件。 它已列入.gitignore。
make docker-up
# 或直接:
docker compose -f deploy/docker-compose.yml up -d --build
make docker-ps
curl http://localhost:8080/healthz
make release PROXY_ADDR=<your-server-ip>:2224
这将为所有平台交叉编译客户端,并自动使用正确的服务器 URL 更新 dist/install.sh 和 dist/install.ps1。Nginx 容器将在 http://<your-server-ip>:8555/ 提供这些文件。
curl -fsSL http://<proxy-ip>:8555/install.sh | bash
irm http://<proxy-ip>:8555/install.ps1 | iex
安装完成后,连接到 ZTTP 网关:
zttp
# 或直接:
ssh -p 2224 <your-username>@<proxy-ip>
你将看到一个终端登录界面。认证通过后,你会看到你有权访问的服务器列表。
所有配置均通过环境变量(或 .env 文件)完成。完整参考请参见 .env.example。
ZTTP 采用基于角色的模型。每个用户被分配一个角色;每个角色都有一个策略,定义它可以访问哪些服务器环境。
角色和服务器分配通过管理控制台管理(见下文)。RBAC 引擎在单个 PostgreSQL 查询中执行所有检查——它绝不会向客户端暴露访问被拒绝的原因(防枚举保护)。
从网关菜单中选择 zttp-admin 服务器连接,或使用具有 security-admin 角色的账户登录。
管理控制台提供:
所有管理操作都会记录到审计卷中的
admin-actions.log文件。
所有会话都存储在 zttp-audit-logs Docker 卷中(容器内为 /var/log/zttp/audit/)。
security-admin 身份登录Ctrl+C 返回# 列出录制文件
sudo ls /var/lib/docker/volumes/zttp-audit-logs/_data/
# 使用 ttyplay 播放录制
sudo ttyplay /var/lib/docker/volumes/zttp-audit-logs/_data/<session-id>.ttyrec
# 阅读管理操作日志
sudo cat /var/lib/docker/volumes/zttp-audit-logs/_data/admin-actions.log
要求: Go 1.25+、Docker(用于交叉编译)
# 为当前平台构建代理 + CLI
make build
# 为所有平台交叉编译 CLI(Linux、macOS、Windows)
make release PROXY_ADDR=<proxy-ip>:2224
# 运行测试
make test
# 本地运行代理(需要 Postgres 和 Vault 已在运行)
make run-proxy
zttp/
├── cmd/
│ ├── proxy/ # 代理服务器入口点
│ └── zttp/ # CLI 客户端入口点
├── db/
│ └── migrations/ # PostgreSQL 模式迁移
├── deploy/
│ ├── docker-compose.yml
│ ├── Dockerfile.proxy
│ └── vault-seed.sh # 将测试 SSH 密钥填充到 Vault
├── dist/
│ ├── install.sh # Linux/macOS 安装脚本
│ └── install.ps1 # Windows 安装脚本
├── internal/
│ ├── audit/ # 管理操作日志
│ ├── auth/ # 用户认证(bcrypt、锁定)
│ ├── cli/ # CLI 客户端 TUI 和连接逻辑
│ ├── config/ # 基于环境的配置
│ ├── killswitch/ # gRPC kill-switch 服务
│ ├── proxy/ # SSH 代理、网关 TUI、管理 TUI、桥接
│ ├── rbac/ # 基于角色的访问控制引擎
│ ├── ratelimit/ # 按 IP 速率限制
│ ├── session/ # 会话跟踪和数据库存储
│ └── vault/ # HashiCorp Vault SSH 密钥客户端
├── proto/ # gRPC 协议定义
├── tools/
│ └── hashpw/ # CLI 工具:生成 bcrypt 密码哈希
├── .env.example # 配置模板
├── go.mod
└── Makefile
git checkout -b feat/your-featuremake test请勿提交:
.env 或任何包含密钥的文件zttp 二进制文件已被 .gitignore 忽略)本项目为专有软件。保留所有权利。
使用 Go、PostgreSQL、HashiCorp Vault 和 Docker 构建。
| 服务 | 用途 |
|---|
zttp-proxy | SSH 堡垒主机(Go 二进制文件) |
zttp-postgres | 控制平面数据库(用户、服务器、RBAC 策略) |
zttp-vault | HashiCorp Vault — 存储 SSH 私钥 |
zttp-nginx | 在 /release/ 提供 CLI 安装程序 |
zttp-init-audit | 一次性容器,用于修复卷权限 |
| 变量 | 默认值 | 描述 |
|---|
PROXY_LISTEN_ADDR | 0.0.0.0:2222 | SSH 代理绑定地址 |
HTTP_LISTEN_ADDR | 0.0.0.0:8080 | 健康检查 HTTP 地址 |
GRPC_LISTEN_ADDR | 0.0.0.0:9090 | Kill-switch gRPC 地址 |
PROXY_NODE_IP | 127.0.0.1 | 烧录到 CLI 二进制文件中的外部 IP |
DATABASE_URL | postgres://zttp:... | PostgreSQL 连接字符串 |
VAULT_ADDR | http://localhost:8201 | Vault 服务器 URL |
VAULT_TOKEN | dev-root-token-zttp | Vault 根令牌(仅限开发环境——生产环境请使用 AppRole) |
MAX_FAILED_ATTEMPTS | 5 | 锁定阈值 |
LOCKOUT_DURATION | 15m | 账户锁定持续时间 |
RATE_LIMIT_PER_MIN | 10 | 每个 IP 每分钟最大登录尝试次数 |
AUDIT_LOG_DIR | /var/log/zttp/audit | 会话录制目录路径 |
SOC_WEBHOOK_URL | (空) | 用于 SOC 告警的可选 webhook |
| 角色 | 访问权限 |
|---|
security-admin | 对所有环境的完全访问权限 + 管理控制台 |
sre-tier1 | 包括生产环境在内的所有环境 |
sre-tier2 | 仅限预发布和开发环境 |
dev | 仅限开发环境 |
readonly | 开发环境,受限命令集 |
| 菜单选项 | 描述 |
|---|
| 添加用户 | 创建新用户并分配角色 |
| 添加服务器 | 注册目标服务器(主机名、IP、环境、SSH 用户) |
| 管理服务器访问 | 授予或撤销用户对特定服务器的访问权限 |
| 查看用户 | 列出所有用户及其角色 |
| 查看服务器 | 列出所有已注册的服务器 |
| 查看审计日志 | 浏览会话、回放录制、阅读文本日志 |
| [ 返回 ] | 返回服务器网关 |
| 命令 | 描述 |
|---|
make build | 为当前平台构建代理和 CLI |
make release | 为所有平台交叉编译 CLI 二进制文件 |
make release-docker | 在 Docker 容器内交叉编译(避免 snap/WSL 问题) |
make docker-up | 启动所有 Docker Compose 服务 |
make docker-down | 停止所有服务并删除卷 |
make docker-logs | 跟踪代理日志 |
make docker-ps | 显示容器状态 |
make test | 运行所有 Go 测试 |
make migrate | 应用数据库迁移 |
make seed | 填充开发数据 |
make hashpw PW=mypassword | 生成 bcrypt 哈希,用于手动数据库填充 |
make clean | 删除编译后的二进制文件和构建缓存 |
| 层级 | 机制 |
|---|
| 传输 | 所有客户端连接均为 SSH(传输中加密) |
| 认证 | bcrypt(成本 12)/ Argon2id — 模式中结构性地禁止明文 |
| 暴力破解防护 | 账户锁定(5 次尝试 / 15 分钟)+ 按 IP 速率限制器 |
| 授权 | 单 JOIN RBAC 查询 — 拒绝始终是通用的("Permission denied") |
| 密钥管理 | SSH 私钥仅存储在 HashiCorp Vault 中,临时获取 |
| 审计追踪 | 以 .ttyrec 格式完整记录按键,不可变的追加式管理日志 |
| 进程隔离 | 代理以非 root(UID 65532)身份在 distroless 容器中运行 |
| Kill switch | 任何实时会话均可通过 gRPC 终止,无需重启代理 |