Главная > Операционные системы > UNIX
Описание. Кандидат BSDA должен уметь определить доступна ли удалённая система через TCP/IP и, если да, уметь при помощи telnet(1) убедиться отвечает ли сервис на клиентские запросы. Практика. ping(8), traceroute(8), telnet(1), nc(1) на FreeBSD и OpenBSD
Комментарий
Утилита ping предназначена для того, чтобы при помощи отправки
ICMP пакетов убедиться в работоспособности хоста. Утилита
настолько широкоизвестна, что наверное нет необходимости
подробно
о ней говорить. Заметим только, то, о чём многие порой забывают:
у утилиты ping(8) есть масса разных
аргументов, и её можно использовать для разнообразнейшей
диагностики. В скриптах полезно бывает применять опцию
Как видим, 36% пакетов было потеряно. В нормальной локальной сети, с хорошими проводами и не перенапряжёнными коммутаторами, такая «атака» не должна приводить к значительным потерям пакетов. Ещё один «необычный» способ использования программы ping(8) может состоять в том, чтобы пинговать широковещательный адрес сети. В этом случае на пинги могут начать отвечать разные машины в сети (а могут и не отвечать, это зависит от их настроек). Таким образом можно попытаться получить информацию о том, какие машины в локальной сети в настоящий момент включены. Не все хосты обязаны отвечать на запросы программы ping(8). Обычно программа ping(8) посылает пакеты, которые называются ECHO_REQUEST и ожидает получить пакет ECHO_RESPONSE. Однако варианты ответов могут быть разными. Ниже показан вариант с ответом «Destination Port Unreachable». Такой ответ, однако, означает, что на той стороне есть «живая» машина.
Немного напоминает знаменитый диалог Винни-Пуха и Пятачка:
Не путайте ответы «Destination Port Unreachable» и «Destination Host Unreachable». Последний генерируется маршрутизатором (или, в частном случае вашей собственной машиной), если он не знает куда послать пакет:
В первом («Винни-Пуховском») примере мы получили ответ от машины, которую мы и пинговали, следовательно она всё-таки включена. А во втором примере, пакет не был доставлен машине, так как она не была найдена (в приведённом примере не была найдена не только машина, но даже сеть, в которой она должна находиться). Команда traceroute(1) в некоторых случаях позволяет выяснить маршрут от одного компьютера до другого. Для этого она посылает пакеты на целевую машину последовательно увеличивая параметр TTL (time to live). В норме TTL должен уменьшаться на единицу на каждом маршрутизаторе, пока не станет равным нулю. Если он обнулится, пакет будет отброшен, а отославшей его стороне вернётся пакет ICMP TIME_EXCEEDED. В этом пакете будет присутствовать IP маршрутизатора, который его послал. По этой информации traceroute(1) сможет перечислить машины, через которые идут пакеты до целевой машины.
Для примера, попробуем выяснить маршрут к несуществующей сети:
Здесь мы выполняли команду traceroute(1) на машине 172.16.0.2. Она не знает маршрута к хосту 10.0.0.1 и пересылает пакет на машину 172.16.0.1 — свой маршрутизатор по умолчанию, а тот вернул ответ «Destination Host Unreachable», о чём свидетельствует флаг !H. Эта строка появилась потому, что брандмауэр на маршрутизаторе 172.16.0.1 не выпускает пакеты предназначенные для приватных сетей на свой дефолтный маршрутизатор возвращая ICMP пакет с сообщением об ошибке. Строка с номером 1 это результат работы первого пакета ICMP, в котором TTL был выставлен в 1. Этот пакет достиг машины 172.16.0.1, но дальнейшей маршрутизации не претерпел, так как у него истёк срок жизни, поэтому сообщение об ошибке сгенерировано не было. И только следующий пакет ICMP с TTL=2, породил сообщение об ошибке. Далее идут несколько умозрительные примеры, почёрпнутые из справки по команде traceroute(1).
Заметьте, что строки 2 и 3 совпадают — это происходит потому, что на втором маршрутизаторе имеются ошибки в ядре — система 4.3BSD маршрутизирует пакет с нулевым TTL.
Шлюзы 6, 8, 9, 10 и 11 либо не высылают нам ICMP с сообщением «time exceeded», либо у их сообщений слишком маленький TTL и оно нас не достигает. В точности нельзя сказать, что происходит на маршрутизаторе 12. Например, это может быть следствием ошибок в ядре 4.[23]BSD: BSD 4.x (x меньше либо равен 3) высылали сообщение об ошибке используя TTL оригинального пакета. Таким образом, ICMP «time exceeded» принципиально не мог до нас добраться.
У программы traceroute(1) есть ещё один
полезный аргумент: Ещё большую функциональность предлагает команда hping(8), описанная ниже. Данная программа не входит в курс BSDA, тем не менее я очень советую с ней поупражняться. Как и программа nmap(1), hping(8) мощное средство тестирования брандмауэров, с её помощью можно генерировать разнообразный «неправильный» трафик.
Часто машина не отвечает на пакеты ECHO_REQUEST, но при этом на ней успешно работает web-сервер и она отвечает на попытку установить соединение с 80-м портом. Программа hping(8) может «пинговать» хосты не только при помощи ICMP пакетов, которые часто отвергаются брандмауэрами, но так же и при помощи TCP и UDP пакетов. Так же программа hping(8) позволяет при помощи TCP пакетов с плавно изменяющимся TTL выяснить маршрут к хосту, даже если это не смогла сделать программа traceroute(1). Принцип работы тот, же, но TCP пакеты, мягко говоря, реже уничтожаются брандмауэрами. Проделаный ниже эксперимент проводился с хорошо известным в нашей стране интернет-магазином, который работает круглосуточно, но на пинги не откликается. Все имена в распечатке заменены, так как мне неизвестно из каких соображений администрация магазина выбрала такую политику безопасности.
Как видим, если послать «пинг» при помощи пакета TCP на порт 80 с выставленным флагом SYN, на него приходит ответ. (Иначе не мог бы функционировать магазин). Таким же образом, мы можем выяснить и маршрут до него. При этом ни команда ping(8), ни traceroute(8) с задачей не справляются. Подробное описание программы hping имеется в работе Николая Малых [url://Malyh-hping2-2005]. Основное назначение программы telnet(1) заключается в том, что она предоставляет удалённый терминал, позволяя управлять машиной на расстоянии. К сожалению, программа telnet(1) не шифрует трафик и даже пароли передаёт в открытом виде. Мы покажем чем это опасно, когда будем обсуждать программу tcpdump(1).
Однако программу telnet(1) можно использовать для того, чтобы провести диалог с удалённым сервером, проверить работу сервиса прослушивающего соответствующий порт. Например, при передаче почты, устанавливается связь с 25-м портом почтового сервера и далее идут команды SMTP протокола. Ниже приведён короткий пример такого диалога. Здесь символ | означает, что на этой строке приведено служебное сообщение программы telnet(1), > — строка которую мы вводим с клавиатуры, т.е. её клиент отсылает серверу, < — ответ сервера.
Обратите внимание на фразу Escape character is '^]'. Если по каким-то причинам вы не можете дождаться ответа сервера и вам надо разорвать соединение, нажмите клавиши <Ctrl>+] и перед вами появится командная строка telnet(1). В ней вы можете набрать команду quit и завершить сеанс:
Работа с telnet(1) может быть неудобна тем, что вы не всегда можете отредактировать свой текст в случае ошибки, к тому же некоторые сервисы, расчитанные на работу с роботом могут завершить соединение по таймауту, если вы набираете команды недостаточно быстро. Наконец, telnet(1) невозможно использовать в скриптах.
Чтобы преодолеть эти недостатки, вместо
telnet(1) можно использовать программу
nc(1) (netcat). В следующем примере, мы
делаем тоже, что и в предыдущем, но две команды SMTP (
Конечно программой nc(1) можно пользоваться и
интерактивно, если не назначить ей
В качестве примера скрипта использующего программу nc(1) приведём программу, которая пытается определить правильность некоторого адреса email. Приведённая программа первым делом разбирает адрес email, находя в нём часть отвечающую за имя сервера. Затем делает запрос к серверу DNS при помощи программы dig(1) определяя имя почтового сервера. И, наконец, при помощи nc(1) проводит диалог с этим сервером пытаясь при помощи команды SMTP RCPT определить существование почтового адреса на данной машине. Почтовый сервер на эту команду должен дать положительный ответ (код больше двухсот, но меньше трёхсот) и надпись <Recipient ok>. Но может и не дать никакого ответа по соображениям безопасности (смотря как настроен почтовый сервер). Тонкости работы команды dig(1) рассмотрены в Раздел 6.5, «Запрос к серверу DNS». Программирование в Bourne shell в Раздел 7.7, «Написание несложных Bourne-скриптов». #!/bin/sh if [ $# -lt 1 ] then echo "Usage mailtest.sh user@server" exit 1 fi # Вычленяем имя сервера из почтового адреса server=`echo $1 | sed s/.*@//` # Определяем почтовый сервер ответственный за передачу писем на # сервер $server mxserver=$( dig $server MX |\ egrep 'MX[[:space:]]+[0-9]+[[:space:]]+[^[:space:]]+\.' |\ sort -n -k5,5 |\ head -1 | awk '{print $6}' | sed 's/\.$//' ) echo Investigate: $1 echo Server: $server echo MX server: $mxserver # Пытаемся провести SMTP диалог с почтовым сервером nc $mxserver 25 << EOF HELO example.org MAIL From: postmaster@example.org RCPT To: $1 QUIT EOF Программа nc(1) штатно присутствует в FreeBSD и OpenBSD, а в DragonFly BSD и NetBSD её надо ставить отдельно, как сторонний продукт. В Раздел C.2.1.6.4.3, «TCP proxy» можно найти пример в котором nc(1) используется в качестве прокси-сервера.
Главная > Операционные системы > UNIX |