🔒 Hardening сервера (чеклист)

Единый стандарт группы, применён на capital-prod и capital-ops (2026-09-15). Эталон-реализация в проекте sCardGlobal; здесь - чеклист под Capital. Инфра-топология - в Архитектура Capital v1.0.md §7.

Что применено на серверах Capital

Слой Состояние
SSH ключ-онли PasswordAuthentication no, ключ ~/.ssh/capital_ed25519 (cc-host)
SSH из интернета убран ✅ Tailscale, ufw пускает только tailscale0; порт 22 из интернета удалён
Провайдер-firewall ✅ Hetzner fw: только udp 41641 (Tailscale) + icmp; prod БЕЗ публичных 80/443 (CF tunnel)
ufw default deny inbound
fail2ban
unattended-upgrades
Docker no-new-privileges ✅ на app-сервисах (backoffice/cabinet/kyc)
Порты приложений ✅ только 127.0.0.1
SSH-алерты в Telegram ✅ pam_exec + sshrc, анти-спам (whitelist tailnet+Mac-IP, rate-limit 1/30мин), бот «Neo Infra Alerts»
chrony (time-sync)
persistent journald
Docker log-limits ✅ 10m×3 + live-restore
File-integrity алерты /usr/local/sbin/file-integrity.sh (sha256 authorized_keys/sshd_config/00-hardening/.env/compose → Telegram), cron */10
Branch protection (GitHub) ✅ на всех 8 repo: block force-push + block deletion
CI-сканеры ✅ gitleaks + Trivy fs (HIGH/CRITICAL) в .github/workflows/security.yml + dependabot

Порядок применения (для нового сервера)

  1. SSH ключ-онли (drop-in /etc/ssh/sshd_config.d/00-hardening.conf): PasswordAuthentication no, PermitRootLogin prohibit-password, KbdInteractiveAuthentication no. Проверить sshd -T. Ключевой доступ подтвердить свежим входом ДО reload.
  2. Tailscale + закрыть публичный 22 в ufw (ufw allow in on tailscale0, удалить 22/tcp). Сначала проверить SSH через tailnet, потом убирать 22. Recovery - Hetzner Console.
  3. ufw default deny inbound + Hetzner Cloud Firewall (defense-in-depth).
  4. fail2ban, unattended-upgrades, chrony, persistent journald.
  5. SSH-алерты (скопировать ssh-login-notify.sh + sshrc с cc-host, единый бот).
  6. Docker: порты на 127.0.0.1, no-new-privileges, без privileged, без docker.sock, log-limits + live-restore.
  7. File-integrity cron + baseline.

⬜ Осталось от CEO (нужны токены/ключи, мимо чата)

  1. Личный SSH-ключ CEO на capital-prod/ops (сейчас только деплой-ключ cc-host - нет раздельного kill-switch).
  2. Fine-grained GitHub PAT без delete_repo взамен текущего.
  3. Cloudflare-токен для CF Access на bo. (login-гейт на back-office).
  4. Забрать копию age-ключа бэкапов себе (scp cc-host:.config/age/capital-backup.key).
  5. MFA на Hetzner-аккаунт + root-пароль recovery в Proton Pass (через Hetzner Console → Reset password).

Крупное отдельным треком