Knowledge Base

Подтверждение открытых портов без ложных критических срабатываний

Зачем нужен этот метод

Категория: Server Hardening · Риск: high

Зачем нужен этот метод

Обычный TCP connect отвечает только на вопрос: "удалось ли установить соединение с портом". Он не доказывает, что за портом действительно работает MySQL, Redis, Docker API или другой чувствительный сервис.

У крупных провайдеров, CDN и DDoS-защит часто встречаются защитные режимы, которые принимают TCP handshake на множестве портов, но не отдают реальный протокол. Это может быть tarpit, фильтр, honeypot-подобная защита или сетевой middlebox. Если считать такой ответ критической уязвимостью, отчёт будет пугать владельца сайта ложным "F".

Правильная модель результата

Разделяйте два состояния:

| Состояние | Что означает | Влияет на score | |---|---|---| | TCP handshake | Соединение установилось, но сервис не подтверждён | Нет, только info | | Protocol confirmed | Получен ожидаемый баннер или безопасный read-only ответ | Да, если сервис опасен публично |

Безопасные подтверждения

Для web-сервисов достаточно `HEAD /` или `GET /` с коротким timeout.

Для SSH, FTP, SMTP, POP3 и IMAP обычно достаточно баннера. Для Redis допустим `PING`, потому что он не меняет состояние. Для Memcached допустим `version`.

Для Docker, Kubernetes, БД и административных панелей не нужно выполнять вход, запрос секретов или команды изменения состояния. Если мягкого подтверждения нет, результат лучше оставить как "неподтверждённый TCP handshake".

Как писать в отчёте

Плохо:

> База данных MySQL открыта в интернет.

Если был только TCP connect, лучше:

> Порт 3306 ответил на TCP-соединение, но MySQL-протокол не подтверждён. Риск исключён из итогового score; рекомендуется перепроверить из другой сети или сверить firewall.

Такой подход сохраняет ценность проверки и не создаёт ложную панику.