
ゼロトラストSSH踏み台プロキシ。Vaultをバックエンドとした鍵管理、RBACポリシー適用、完全なセッション録画、および本番インフラへの監査可能なアクセスを実現する管理用TUIを備えています。
堅牢化されたセルフホスト型SSH踏み台ホスト — Vault連携の鍵管理、RBACポリシー適用、完全なセッション録画、対話型管理TUIを備え、監査可能なゼロトラストアクセスを本番インフラへ提供するチーム向けに設計されています。
現代のエンジニアリングチームには、開発者に必要最小限のアクセス権を付与する方法が求められています — それ以上でもそれ以下でもありません。従来のSSH鍵の配布はエラーが発生しやすく、鍵は共有され、ラップトップに置き忘れられ、失効が数日遅れることがあります。
ZTTPは、インフラへの単一の入り口として機能することでこの問題を解決します:
| 問題 | ZTTPの解決策 |
|---|---|
| ラップトップで共有されるSSH鍵 | 鍵はHashiCorp Vault内にのみ存在 — ディスク上には決して置かれません |
| 誰が何をしたかの可視性がない | すべてのキーストロークが.ttyrec形式で記録されます |
| 本番環境への包括的なアクセス | ロールベースのポリシーエンジンが環境ごとのルールを強制します |
| アクティブなセッションを停止する手段がない | キルスイッチgRPCエンドポイントが任意のライブセッションを終了します |
| 監査担当者にとって不透明なアクセス | セッション再生、テキストログ、管理操作ログを備えた管理TUI |
開発者ラップトップ
│
│ zttp
│ (内部: ポート2224でのSSH)
▼
┌─────────────────────────────────────────────────────────┐
│ ZTTPプロキシ │
│ │
│ ① 認証ゲート — bcrypt/Argon2idログインTUI │
│ ② RBACエンジン — 環境認識型ポリシーチェック │
│ ③ Vault取得 — 一時的なSSH鍵の取得 │
│ ④ ブリッジ — 透過型TCPトンネル │
│ ⑤ 監査ライター — ttyrecフレームレコーダー │
└──────────┬──────────────────────────────────────────────┘
│ ssh (プライベートIP、一時鍵)
▼
ターゲットサーバー
インフラストラクチャサービス (Docker Compose):
.ttyrec形式に記録されますサーバー (プロキシホスト):
2224で公開またはLANアクセス可能な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
これにより、すべてのプラットフォーム向けにクライアントがクロスコンパイルされ、dist/install.shとdist/install.ps1が正しいサーバーURLで自動更新されます。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-logsDockerボリューム (コンテナ内の/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キルスイッチサービス
│ ├── proxy/ # SSHプロキシ、ゲートウェイTUI、管理TUI、ブリッジ
│ ├── rbac/ # ロールベースアクセス制御エンジン
│ ├── ratelimit/ # IPごとのレート制限
│ ├── session/ # セッショントラッキングとDBストア
│ └── 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 | コントロールプレーンDB (ユーザー、サーバー、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 | キルスイッチ用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ごとの1分あたりの最大ログイン試行回数 |
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 | 手動DBシード用のbcryptハッシュを生成 |
make clean | コンパイル済みバイナリとビルドキャッシュを削除 |
| レイヤー | メカニズム |
|---|
| トランスポート | すべてのクライアント接続はSSH (転送中は暗号化) |
| 認証 | bcrypt (コスト12) / Argon2id — 平文はスキーマ上構造的に禁止 |
| ブルートフォース対策 | アカウントロック (5回 / 15分) + IPごとのレートリミッター |
| 認可 | 単一JOINのRBACクエリ — 拒否は常に汎用的 ("Permission denied") |
| シークレット管理 | SSH秘密鍵はHashiCorp Vaultにのみ保存され、一時的に取得 |
| 監査証跡 | .ttyrec形式での完全なキーストローク録画、不変の追記専用管理ログ |
| プロセス分離 | プロキシはdistrolessコンテナ内で非root (UID 65532) として実行 |
| キルスイッチ | プロキシを再起動せずに、任意のライブセッションをgRPC経由で終了可能 |