Модель безопасности
Что фреймворк делает для защиты сервера, какие решения приняты и что остаётся на вашей ответственности.
Защита от локаута (потери доступа к серверу)
Самый опасный класс ошибок инсталляторов. Принятые меры:
| Риск | Защита |
|---|---|
| Сломанный конфиг sshd | Drop-in валидируется sshd -t до перезапуска; при ошибке мгновенно восстанавливается прежний конфиг |
| Отключение паролей без ключа | mitdev предлагает сгенерировать Ed25519-ключи для deploy/root; глобальный PasswordAuthentication no применяется только при наличии deploy-ключа |
| Файрвол закрыл SSH | Правило SSH-порта добавляется до ufw enable |
| Смена порта SSH «не применилась» | При наличии ssh.socket он отключается (socket-активация приколачивает порт 22) и включается классический ssh.service |
| Fail2Ban банит администратора | ignoreip = 127.0.0.1/8 ::1; порт jail'а совпадает с фактическим портом SSH |
Усиление SSH (модуль security)
Drop-in /etc/ssh/sshd_config.d/99-mitdev.conf:
PermitRootLogin— по вашему выбору; рекомендуемое значение после создания deploy-пользователя с sudo —no;PasswordAuthentication— глобально для всех SSH-пользователей, по вашему выбору (см. выше);MaxAuthTries 3,LoginGraceTime 30,MaxSessions 10;KbdInteractiveAuthentication no,PermitEmptyPasswords no;X11Forwarding no,UseDNS no;- keep-alive:
ClientAliveInterval 300,ClientAliveCountMax 2.
Инсталлятор может создать две пары ключей:
/root/.mitdev-keys/<user>_ed25519 для deploy-пользователя и
/root/.mitdev-keys/root_ed25519 для root. Public keys добавляются в
соответствующие authorized_keys, private keys показываются root-командами
sudo mitdev ssh-key show deploy и sudo mitdev ssh-key show root.
Сетевой периметр
- UFW:
deny incoming / allow outgoing; открываются только SSH-порт иUFW_EXTRA_PORTS(по умолчанию 80, 443). - Kubernetes: API 6443/tcp + pod/service-сети (10.42/10.43) — только при активном UFW и только необходимые.
- Репликация PostgreSQL: 5432/tcp открывается точечно, по IP каждой
реплики (
ufw allow from <ip> to any port 5432), аpg_hba.confограничивает доступ той же парой «пользователь репликации + IP/32» с scram-sha-256. - Redis: слушает только localhost +
requirepass. - RabbitMQ: пользователь guest — localhost-only (дефолт RabbitMQ); создаётся отдельный admin со случайным паролем.
- MinIO: root-учётные данные генерируются; порты наружу не открываются (доступ — через reverse proxy по вашему решению).
Секреты
- Все пароли генерируются криптографически (
openssl rand -hex 16). - Хранятся в
/root/.mitdev-credentialsс правами 0600 — читает только root. - Сгенерированные SSH private keys deploy/root хранятся отдельно в
/root/.mitdev-keysс правами 0600 и показываются только root-командойmitdev ssh-key. - Пароли никогда не пишутся в журналы:
run_stepне используется для команд с паролем в аргументах, либо пароль передаётся через файл/stdin; в лог попадает только факт («PASSWORD set for X (value not logged)»). - Пароль репликации на реплике попадает в
postgresql.auto.conf(владелец postgres, 0600) — стандартная практикаpg_basebackup -R. - Резервные копии (
mitdev backup) содержат.env-файлы и дампы БД — архивам ставится 0600; за их дальнейшее хранение отвечаете вы. - Cloudflare (
mitdev cf): API-токен и connector-token хранятся в кредах (0600). Токен уходит curl только конфигом на stdin (--config -), никогда аргументом — argv виден вpsлюбому локальному пользователю. Connector-token в systemd-юнит cloudflared подаётся черезEnvironmentFile(0600), а не вExecStart(иначе systemd раскрыл бы его в argv). В логах модуль пишет только метод/путь/HTTP-код — секрет не кладётся в лог по построению;redact_log_textдополнительно вырезаетBearer …/CF_API_TOKEN=…. Токену давайте минимальные scope — меньше прав, меньше ущерб при утечке.
Права и изоляция
- Deploy-пользователь: домашняя директория 0750; sudo — полный (это осознанное решение для одного администратора; ограничивайте sudoers под свою модель угроз).
- Группа docker эквивалентна root — членство в ней получает только deploy-пользователь, и это следует понимать.
- MinIO работает от системного пользователя
minio-user(nologin); systemd-юнит с hardening:NoNewPrivileges,ProtectSystem=full,ProtectHome,PrivateTmp. - kubeconfig копируется deploy-пользователю с правами 0600 (это полный админ-доступ к кластеру — как и docker-группа).
- health-эндпоинт Cloudflare-модуля (
mitdev cf health) слушает только loopback или WG-адрес, никогда0.0.0.0(строгий whitelist bind-адреса): публично он выдал бы карту здоровья узлов (200/503 и причину отказа) — сигнал failover и точку разведки/DoS. Юнит бежит отnobodyсNoNewPrivileges.
Известные ограничения (ваша зона ответственности)
- MongoDB ставится без аутентификации (слушает localhost). До вывода
в продакшен включите
security.authorizationи создайте пользователей. Модуль предупреждает об этом при установке. - PostgreSQL primary слушает
listen_addresses='*'— доступ снаружи отсекают UFW и pg_hba, но при отключении файрвола порт станет доступен. - Автоматическое обновление пакетов не настраивается — решите сами:
unattended-upgradesили регулярныйmitdev update(mitdev doctorподсказывает, когда накопились обновления). - Split-brain при failover: watchdog v2 закрывает штатные сценарии —
двойная проверка pg_isready+TCP, порог
30 с, приоритетные задержки реплик, а главное fencing по timeline: смещённый старый primary, увидев пира со старшим timeline, сам понижается через pg_rewind. Окно риска остаётся при полном сетевом разделении, когда оба сегмента продолжают принимать записи и не видят эндпоинты ролей друг друга — кворума в схеме 1+2 нет. Для строгих гарантий на 5+ узлах уместен Patroni с etcd. Дополнительные механизмы самовосстановления: `postgres/.mitdev-repl-pass(0600, только postgres) и узкий sudoers — postgres может лишьsystemctl stop/start/restart postgresql`, ничего больше. - Цепочка поставки: k3s, Helm, gum и NodeSource ставятся официальными скриптами/репозиториями поставщиков по HTTPS с GPG-подписями пакетов, но это доверие к их инфраструктуре. Для air-gapped сред зеркалируйте артефакты самостоятельно.
Сообщение об уязвимостях
Не открывайте публичный issue. Напишите мейнтейнерам напрямую (контакты — в профиле репозитория); дайте разумный срок на исправление до раскрытия.