
Zero-trust SSH бастион-прокси с управлением ключами на базе Vault, применением политик RBAC, полной записью сессий и административным TUI для аудируемого доступа к производственной инфраструктуре.
Укреплённый, самостоятельно размещаемый SSH-бастион с управлением ключами на базе Vault, применением политик RBAC, полной записью сессий и интерактивной TUI для администрирования — создан для команд, которым нужен аудируемый доступ с нулевым доверием к производственной инфраструктуре.
Современным инженерным командам нужен способ дать разработчикам минимально необходимый доступ для выполнения их задач — не больше и не меньше. Традиционное распространение SSH-ключей чревато ошибками: ключи передаются между коллегами, забываются на ноутбуках и отзываются слишком поздно.
ZTTP решает эту проблему, выступая в роли единственной двери в вашу инфраструктуру:
Ноутбук разработчика
│
│ zttp
│ (Под капотом: SSH через порт 2224)
▼
┌─────────────────────────────────────────────────────────┐
│ Прокси ZTTP │
│ │
│ ① Шлюз аутентификации — TUI входа bcrypt/Argon2id │
│ ② Механизм RBAC — проверка политики с учётом окружения │
│ ③ Получение из Vault — эфемерное получение SSH-ключа │
│ ④ Мост — прозрачный TCP-туннель │
│ ⑤ Запись аудита — регистратор кадров ttyrec │
└──────────┬──────────────────────────────────────────────┘
│ ssh (частный IP, эфемерный ключ)
▼
Целевой сервер
Инфраструктурные сервисы (Docker Compose):
.ttyrec с кадрами, содержащими временные меткиСервер (хост прокси):
2224make (необязательно, но рекомендуется)Разработчик (клиент):
ssh)git clone https://gitlab.com/Nihal799/zttp.git
cd zttp
cp .env.example .env
Отредактируйте .env и задайте как минимум:
PROXY_NODE_IP=<публичный-ip-вашего-сервера>
POSTGRES_PASSWORD=<надёжный-пароль>
VAULT_TOKEN=<надёжный-токен-vault>
⚠️ Никогда не коммитьте файл
.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=<ip-вашего-сервера>:2224
Эта команда выполняет кросс-компиляцию клиентов для всех платформ и автоматически обновляет dist/install.sh и dist/install.ps1 с правильным URL сервера. Контейнер Nginx раздаёт их по адресу http://<ip-вашего-сервера>:8555/.
curl -fsSL http://<ip-прокси>:8555/install.sh | bash
irm http://<ip-прокси>:8555/install.ps1 | iex
После установки подключитесь к шлюзу ZTTP:
zttp
# или напрямую:
ssh -p 2224 <ваше-имя-пользователя>@<ip-прокси>
Вам будет показан экран входа в терминале. После аутентификации вы увидите список серверов, к которым у вас есть доступ.
Вся конфигурация задаётся через переменные окружения (или файл .env). Полный справочник см. в .env.example.
ZTTP использует ролевую модель. Каждому пользователю назначается роль; у каждой роли есть политика, определяющая, к каким окружениям серверов она имеет доступ.
Роли и назначения серверов управляются через административную консоль (см. ниже). Механизм RBAC выполняет все проверки одним запросом к PostgreSQL — он никогда не раскрывает клиенту причину отказа в доступе (защита от перечисления).
Подключитесь к серверу zttp-admin из меню шлюза или войдите с учётной записью, имеющей роль security-admin.
Административная консоль предоставляет:
Все административные действия записываются в
admin-actions.logвнутри тома аудита.
Все сессии хранятся в Docker-томе zttp-audit-logs (/var/log/zttp/audit/ внутри контейнера).
security-adminCtrl+C для возврата# Список записей
sudo ls /var/lib/docker/volumes/zttp-audit-logs/_data/
# Воспроизведение записи с помощью ttyplay
sudo ttyplay /var/lib/docker/volumes/zttp-audit-logs/_data/<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=<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/ # TUI клиента CLI и логика подключения
│ ├── config/ # Конфигурация на основе переменных окружения
│ ├── killswitch/ # gRPC-сервис kill-switch
│ ├── proxy/ # SSH-прокси, TUI шлюза, TUI администратора, мост
│ ├── rbac/ # Механизм контроля доступа на основе ролей
│ ├── ratelimit/ # Ограничение частоты запросов по IP
│ ├── session/ # Отслеживание сессий и хранилище БД
│ └── vault/ # Клиент SSH-ключей HashiCorp Vault
├── proto/ # Определения gRPC-протокола
├── tools/
│ └── hashpw/ # Инструмент CLI: генерация bcrypt-хеша пароля
├── .env.example # Шаблон конфигурации
├── go.mod
└── Makefile
git checkout -b feat/ваша-функцияmake testПожалуйста, не коммитьте:
.env или любые файлы, содержащие секретыzttp в корне указан в .gitignore)Этот проект является проприетарным. Все права защищены.
Создано с использованием Go, PostgreSQL, HashiCorp Vault и Docker.
| Проблема | Решение ZTTP |
|---|
| SSH-ключи хранятся на ноутбуках | Ключи живут только в HashiCorp Vault — никогда не попадают на диск |
| Нет видимости того, кто что делал | Каждое нажатие клавиши записывается в формате .ttyrec |
| Неограниченный доступ к продакшену | Механизм политик на основе ролей обеспечивает соблюдение правил для каждого окружения |
| Нет способа остановить активную сессию | gRPC-эндпоинт kill-switch завершает любую активную сессию |
| Непрозрачный доступ для аудиторов | Административная TUI с воспроизведением сессий, текстовыми журналами и журналом действий администратора |
| Сервис | Назначение |
|---|
zttp-proxy | SSH-бастион (бинарный файл Go) |
zttp-postgres | База данных плоскости управления (пользователи, серверы, политики RBAC) |
zttp-vault | HashiCorp Vault — хранит закрытые SSH-ключи |
zttp-nginx | Раздаёт установщики CLI по адресу /release/ |
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-адрес kill-switch |
PROXY_NODE_IP | 127.0.0.1 | Внешний IP, встраиваемый в бинарные файлы CLI |
DATABASE_URL | postgres://zttp:... | Строка подключения к PostgreSQL |
VAULT_ADDR | http://localhost:8201 | URL сервера Vault |
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 |
| Роль | Доступ |
|---|
security-admin | Полный доступ ко всем окружениям + административная консоль |
sre-tier1 | Все окружения, включая продакшен |
sre-tier2 | Только staging и разработка |
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=мойпароль | Генерация bcrypt-хеша для ручного заполнения БД |
make clean | Удаление скомпилированных бинарных файлов и кэша сборки |
| Уровень | Механизм |
|---|
| Транспорт | Все клиентские подключения — SSH (шифрование при передаче) |
| Аутентификация | bcrypt (стоимость 12) / Argon2id — открытый текст структурно запрещён в схеме |
| Защита от перебора | Блокировка учётной записи (5 попыток / 15 мин) + ограничитель частоты по IP |
| Авторизация | Запрос RBAC с одним JOIN — отказы всегда общие («Отказано в доступе») |
| Управление секретами | Закрытые SSH-ключи хранятся исключительно в HashiCorp Vault, получаются эфемерно |
| Журнал аудита | Полная запись нажатий клавиш в формате .ttyrec, неизменяемый журнал администратора с добавлением только в конец |
| Изоляция процессов | Прокси работает от непривилегированного пользователя (UID 65532) внутри контейнера distroless |
| Kill switch | Любая активная сессия может быть завершена через gRPC без перезапуска прокси |