🔒 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 |
Порядок применения (для нового сервера)
- SSH ключ-онли (drop-in
/etc/ssh/sshd_config.d/00-hardening.conf):PasswordAuthentication no,PermitRootLogin prohibit-password,KbdInteractiveAuthentication no. Проверитьsshd -T. Ключевой доступ подтвердить свежим входом ДО reload. - Tailscale + закрыть публичный 22 в ufw (
ufw allow in on tailscale0, удалить22/tcp). Сначала проверить SSH через tailnet, потом убирать 22. Recovery - Hetzner Console. - ufw default deny inbound + Hetzner Cloud Firewall (defense-in-depth).
- fail2ban, unattended-upgrades, chrony, persistent journald.
- SSH-алерты (скопировать
ssh-login-notify.sh+ sshrc с cc-host, единый бот). - Docker: порты на
127.0.0.1,no-new-privileges, безprivileged, безdocker.sock, log-limits + live-restore. - File-integrity cron + baseline.
⬜ Осталось от CEO (нужны токены/ключи, мимо чата)
- Личный SSH-ключ CEO на capital-prod/ops (сейчас только деплой-ключ cc-host - нет раздельного kill-switch).
- Fine-grained GitHub PAT без
delete_repoвзамен текущего. - Cloudflare-токен для CF Access на
bo.(login-гейт на back-office). - Забрать копию age-ключа бэкапов себе (
scp cc-host:.config/age/capital-backup.key). - MFA на Hetzner-аккаунт + root-пароль recovery в Proton Pass (через Hetzner Console → Reset password).
Крупное отдельным треком
- sops+age для секретов (конфиги в git зашифрованы) + pre-commit hook против незашифрованных коммитов.
- Tailscale ACL сужение (member→all), device-approval, MFA/SSO на tailnet.
- Внешний pentest - 1 раз в год перед активными продажами.
- Central logging (off-host, immutable для комплаенса), auditd/FIM.