meta(tasks): migrate .tasks to v2 (global numbering 87 tasks)
This commit is contained in:
62
.tasks/2026-05-29-00265-harden-books-vds-exposed-ports.md
Normal file
62
.tasks/2026-05-29-00265-harden-books-vds-exposed-ports.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# harden-books-vds-exposed-ports
|
||||
|
||||
## Goal
|
||||
|
||||
Закрыть/ограничить публично торчащие host-порты на books VDS (89.253.255.133). Выявлены
|
||||
во время инцидента `restore-elasticsearch-indices-books-vds` (2026-05-29): ES был снесён
|
||||
ransom-ботом через открытый `0.0.0.0:9200` в обход traefik+firewalld. Тот же класс дыры
|
||||
(docker-publish обходит firewalld INPUT-зоны) зияет ещё на ряде stateful-сервисов. Цель —
|
||||
ни один stateful-сервис не должен быть доступен с публичного IP напрямую; доступ либо через
|
||||
traefik (под auth), либо по внутренней docker-сети, либо по SSH-туннелю для admin.
|
||||
|
||||
## Exposure audit (2026-05-29, `docker ps` + `ss -tlnp`)
|
||||
|
||||
| Сервис | Порт наружу | Auth на сервисе | Действие |
|
||||
|---|---|---|---|
|
||||
| `elasticsearch` | ~~`0.0.0.0:9200`~~ | ❌ free-ES без auth | ✅ ЗАКРЫТ (Fix #3, инцидент) |
|
||||
| `mongo` | `0.0.0.0:27017` | ✅ enabled | убрать публикацию (app ходит по docker-сети) |
|
||||
| `books-db` (mariadb) | `0.0.0.0:3306` | ✅ root+pass | убрать публикацию / SSH-туннель для admin |
|
||||
| `bookva-db` (mariadb) | `0.0.0.0:33306` | ✅ | убрать публикацию |
|
||||
| `minio` | `0.0.0.0:9000` | ✅ | оставить только через traefik (minio.kzntsv.site) |
|
||||
| `bookva-minio` | `0.0.0.0:9001` | ✅ | то же |
|
||||
| rsync | `:873` | ? проверить | проверить нужен ли наружу |
|
||||
| imgproxy / imgproxy-nginx / proxy-chain | `:8787/8788/8778` | ? | проверить, internal? |
|
||||
|
||||
## Key files / endpoints
|
||||
|
||||
- Portainer API `https://portainer.kzntsv.site` (key в `pass books-vds/full-env`), PUT `/api/stacks/<id>?endpointId=1` — паттерн как в Fix #3 (убрать `ports:` блок из compose).
|
||||
- Stack ids: см. `.wiki/entities/books-vds.md` § Стек (22–33). mongo=31, books-db=32, minio=30, ES=33. bookva-* стек(и) — id уточнить через Portainer API list.
|
||||
- firewalld активен но docker его обходит — закрытие через docker port-publish, НЕ через firewalld rules.
|
||||
|
||||
## Decisions log
|
||||
|
||||
- 2026-05-29: Не закрывать в emergency-режиме инцидента — БД credentialed (не дыра-нараспашку как free-ES), и публикация может использоваться для внешнего admin (DBeaver/Compass/mc). Нужно сперва проверить по каждому: ходит ли приложение через host-порт или по docker-сети, и нужен ли внешний admin-доступ (тогда SSH-туннель вместо публикации).
|
||||
|
||||
## Open questions
|
||||
|
||||
- [ ] Каждый сервис: приложение коннектится через `service-name:port` (docker DNS) или через host-порт? Если через docker-сеть → публикацию убрать безопасно.
|
||||
- [ ] Нужен ли кому-то внешний admin к mongo/mariadb? Если да → SSH local-forward, не публичный порт.
|
||||
- [ ] rsync:873 — это backup-pipeline или забытый демон? Проверить.
|
||||
- [ ] imgproxy/proxy-chain порты — реально нужны наружу или artefact?
|
||||
|
||||
## Completed steps
|
||||
|
||||
- [x] 2026-05-29: exposure audit (таблица выше)
|
||||
- [x] 2026-05-29: ES :9200 закрыт (в рамках инцидент-фикса)
|
||||
- [x] 2026-05-29: проверена auth — mongo/mariadb/minio требуют креды (не auth-less)
|
||||
|
||||
## Notes
|
||||
|
||||
Главный learning из инцидента: auth должна быть **на самом сервисе**, не только в
|
||||
traefik-мидлваре. firewalld не защищает от docker-publish. См.
|
||||
`.wiki/concepts/es-destructive-delete-incident-2026-05-26.md` § «Рецидив 2026-05-29».
|
||||
|
||||
## Branch
|
||||
|
||||
n/a (admin ops)
|
||||
|
||||
## Status
|
||||
|
||||
ready 2026-05-29
|
||||
|
||||
<!-- created-by: vitya@.admin-exec / 2026-05-29 / trigger: exposure-audit во время ES ransom-incident — 5 stateful-сервисов с публичными host-портами -->
|
||||
Reference in New Issue
Block a user