IPv6 + IPv4 = почти детективная история с граблями

Представьте ситуацию. Есть “свежий” выделенный сервер (Linux -> Debian), навожу на нем порядок - выключаю лишние сервисы, тюнингую различные настройки и так далее. Приходится и почитывать всякое новое, так как после работы с FreeBSD обнаруживается довольно много отличий. Наконец, вывод команды sockstat -l становится желаемым.

Но тут же вспоминаю, что был же еще включен ProFTPd. Хотя в списке открытых портов 21-го я не вижу. Странно. Запускаю FAR, создаю в нем новое подключение, нажимаю и …. Мои глаза расширяются - сервис откликается. Снова перепроверяю sockstat, но понять ничего не могу и глубоко задумываюсь…

Запускаю NetTools, ввожу IP, включаю сканирование портов и… снова удивляюсь. Результат совпадает с выводом команды sockstat на самом сервере - 21-й порт сканер не нашел.

Теперь для верности качаю NetCat под Windows, запускаю “nc SERVER_IP 21″ и… получаю приветствие FTP-сервера. Вот тут-то я вхожу в полный ступор. :) Ум за разум начинает заходить, я пытаюсь увидеть в этом всем хоть какую-то логику.

Цепляюсь за главное - раз sockstat не показывает открытый порт, но он ЕСТЬ (как в “ДМБ” про суслика) - точно что-то не так с sockstat. Гуглю на тему того почему эта утилита может выдавать не все, что есть на самом деле. Выясняется, что sockstat совсем не учитывает IPv6 (точнее, версия в Debian 6 - там нет поддержки ключа “-6″).

Ага, то есть, получается ProFTPd включен только для IPv6 протокола? Вдруг потому сканер в NetTools и не увидел 21- порт, в то время как NetCat и плагин ftp у FAR-а законнектились (и они его поддерживают)? Да ну нет, ерунда какая-то, даже если у меня в Win7 и включен IPv6, все равно наши провайдерские серваки не обрабатывают его. Да и вышестоящие провайдеры тоже. А вдруг я себе локально шлюз поставил и забыл?

Пингую IPv6 адрес сервера - нет ответа (а с веб-сервисов пингования ipv6 адресов - пингуется). Что и следовало ожидать. Снова пробую зайти на ftp - заходит… Ступор…

Наконец, МЫСЛЬ. У меня на сервере включен ip_forward, так как я использую виртуализацию на базе OpenVZ (на физическом сервере запущена виртуалка со своим адресом, на которой работает apache в связке с nginx). Вдруг при попытке зайти на закрытый порт пакет подхватывается стеком IPv6? Звучит бредово, но других пока идей нет совсем.

Для теста делаю на пару секунд echo 0 > /proc/sys/net/ipv4/ip_forward , тестирую FTP, возвращаю обратно 1. Мда….. Сервис продолжает откликаться! :) Тут уже вспоминаю, что проще было сделать tcpdump port 21. Заодно узнаю как смотреть траффик только для 6-й версии протокола - tcpdump ip6. Дамп показывает, что работа идет по обычному IPv4!

Но тогда почему я не вижу ничего в sockstat -l ????

Внимание, РАЗГАДКА!. :)

Естественно, после такого поворота я поискал как еще можно смотреть открытые порты. Один из альтернативных вариантов - lsof -i.

Команда lsof -i|grep proft выдает такой результат:

proftpd 11643 proftpd 1u IPv6 30371 0t0 TCP *:ftp (LISTEN)

Обратите внимание - IPv6, но *:ftp, т.е. биндится на все интерфейсы в системе! А устаревший sockstat просто этого не видит. Если в proftpd.conf опцию UseIPv6 выставить в off, то sockstat “прозревает”. Но главная мысль не в этом. Вывод:

Внимание! Если в Debian 6 поднят IPv6 протокол, то имейте в виду, что какой-то нежелательный сетевой сервис может запуститься так, что его абсолютно не будет видно с помощью sockstat! :) Используйте, например, lsof -i.

Плюс не помешает произвести полное внешнее сканирование с помощю Nessus, а изнутри - аудит при помощи Lynis. Лишние сервисы из автозапуска легко убирать с помощью rcconf. В apache желательно включить mod_security, а на закуску - настроить пересылку логов системы на какой-то отдельный сервер.