nc — произвольные TCP и UDP соединения и прослушивание
СИНТАКСИС
nc [-46bCDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl] [-m minttl] [-O length]
[-P proxy_username] [-p source_port] [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable]
[-W recvlimit] [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]] [destination] [port]
ОПИСАНИЕ
Утилита nc (или netcat) используется практически для всего, что связано с TCP, UDP или
Unix-доменными сокетами. Она может открывать TCP-соединения, отправлять UDP-пакеты, прослушивать произвольные TCP- и
UDP-порты, выполнять сканирование портов и работать как с IPv4, так и с IPv6. В отличие от [telnet]({filename}../../telnet)(1), nc хорошо работает в скриптах
и отправляет сообщения об ошибках в стандартный поток ошибок, а не в стандартный поток вывода, как это делает [telnet]({filename}../../telnet)(1) в некоторых случаях.
Общие варианты использования:
простые TCP-прокси
HTTP-клиенты и серверы на основе скриптов
тестирование сетевых демонов
SOCKS или HTTP ProxyCommand для [ssh]({filename}../../ssh)(1)
и многое, многое другое
Параметры следующие:
-4 Использовать только IPv4-адреса.
-6 Использовать только IPv6-адреса.
-b Разрешить широковещательные сообщения.
-C Отправлять CRLF в качестве символа конца строки. Каждый символ новой строки (LF) из входных данных
преобразуется в CR+LF перед записью в сокет. Символы новой строки, которым уже предшествует символ возврата каретки (CR), не преобразуются.
Полученные данные не изменяются.
-D Включить отладку на сокете.
-d Не пытаться читать из стандартного ввода.
-F Передать первый установленный сокет, используя sendmsg(2), в стандартный вывод и завершить работу.
Это полезно в сочетании с -X, чтобы nc выполнял установку соединения через прокси, а затем
передавал остальную часть соединения другой программе (например, [ssh]({filename}../../ssh)(1) с использованием
параметра ssh_config(5) ProxyUseFdpass). Нельзя использовать с -U.
-h Вывести текст справки nc и выйти.
-I length
Указать размер буфера приема TCP.
-i interval
Приостанавливать выполнение на указанное количество секунд между отправляемыми и принимаемыми строками текста.
Также вызывает задержку между подключениями к нескольким портам.
-k После завершения соединения прослушивать следующее. Требуется -l. При использовании
вместе с опцией -u серверный сокет не подключается, и он может получать UDP-датаграммы
с нескольких хостов.
-l Прослушивать входящее соединение, а не устанавливать соединение с удаленным хостом.
Место назначения и порт для прослушивания можно указать либо как обязательные аргументы,
либо с помощью опций -s и -p соответственно. Нельзя использовать одновременно с -x или -z.
Кроме того, любые тайм-ауты, указанные с помощью опции -w, игнорируются.
-M ttl Установите TTL / максимальное количество переходов для исходящих пакетов.
-m minttl
Попросите ядро отбросить входящие пакеты, TTL / максимальное количество переходов которых меньше minttl.
-N [shutdown]({filename}../../shutdown)(2) сетевой сокет после завершения ввода. Некоторые серверы требуют этого для завершения своей работы.
-n Не выполнять разрешение доменных имен. Если имя не удается разрешить без DNS, будет выдана ошибка.
-O length
Укажите размер буфера отправки TCP.
-P proxy_username
Указывает имя пользователя для передачи серверу-прокси, требующему аутентификации. Если имя пользователя не указано, аутентификация выполняться не будет. Аутентификация прокси поддерживается только для HTTP CONNECT прокси.
-p source_port
Укажите исходный порт, который nc должен использовать, с учетом ограничений привилегий и доступности.
-q seconds
После завершения ввода в stdin подождите указанное количество секунд, а затем выйдите. Если seconds отрицательно, ждите бесконечно (по умолчанию). Указание неотрицательного значения seconds подразумевает -N.
-r Выберите исходные и/или конечные порты случайным образом, а не последовательно в диапазоне или в порядке, в котором их назначает система.
-S Включите опцию RFC 2385 TCP MD5 signature.
-s sourceaddr
Установите исходный адрес, с которого будут отправляться пакеты, что полезно на машинах с несколькими интерфейсами. Для Unix-domain datagram сокетов указывает локальный временный файл сокета, который необходимо создать и использовать, чтобы можно было получать датаграммы. Нельзя использовать вместе с -x.
-T keyword
Измените значение IPv4 TOS / IPv6 traffic class. keyword может быть одним из следующих: critical, inetcontrol, lowcost, lowdelay, netcontrol, throughput, reliability, или одним из DiffServ Code Points: ef, af11 ... af43, cs0 ... cs7; или числом в шестнадцатеричном или десятичном формате.
-t Отправляйте ответы RFC 854 DON'T и WON'T на запросы RFC 854 DO и WILL. Это позволяет использовать nc для создания скриптов сеансов telnet.
-U Используйте Unix-domain сокеты. Нельзя использовать вместе с -F или -x. В Linux, если имя начинается с символа `@`, оно интерпретируется как абстрактное пространство имен сокета: ведущий символ `@` заменяется байтом NULL перед связыванием или подключением. Подробности см. в unix(7).
-u Используйте UDP вместо TCP. Нельзя использовать вместе с -x. Для Unix-domain сокетов используйте датаграмный сокет вместо потокового сокета. Если используется Unix-domain сокет, создается временный сокет для приема в /tmp, если только не указан флаг -s.
-V rtable
Установите таблицу маршрутизации, которую следует использовать.
-v Выводите более подробную информацию.
-W recvlimit
Прекратите работу после получения recvlimit пакетов из сети.
-w timeout
Соединения, которые не могут быть установлены или бездействуют, завершаются после timeout секунд. Флаг -w не влияет на опцию -l, т.е. nc будет прослушивать соединение бесконечно, с флагом -w или без него. По умолчанию тайм-аут отсутствует.
-X proxy_protocol
Использовать proxy_protocol при взаимодействии с прокси-сервером. Поддерживаемые протоколы: 4 (SOCKS 4, 4A (SOCKS v.4A), 5 (SOCKS v.5) и connect (HTTPS proxy). Если протокол не указан, используется версия SOCKS 5. Обратите внимание, что протокол SOCKS v.4 очень ограничен и может использоваться только в том случае, если целевой хост может быть разрешен в IPv4-адрес. Остальные протоколы передают назначение в виде строки, которая интерпретируется удаленным прокси, и не имеют этого ограничения.
-x proxy_address[:port]
Подключиться к месту назначения, используя прокси-сервер по адресу proxy_address и порту. Если порт не указан, используется стандартный порт для протокола прокси (1080 для SOCKS, 3128 для HTTPS). IPv6-адрес можно указать однозначно, заключив proxy_address в квадратные скобки. Прокси нельзя использовать ни с одной из опций -lsuU.
-Z Режим DCCP.
-z Только сканирование на наличие прослушивающих демонов, без отправки каких-либо данных. Нельзя использовать вместе с -l.
destination может быть числовым IP-адресом или символьным именем хоста (если не указана опция -n). В общем случае, место назначения должно быть указано, если не указана опция -l (в этом случае используется локальный хост). Для Unix-domain сокетов требуется место назначения, и это путь к сокету для подключения (или для прослушивания, если указана опция -l).
port можно указать как числовой номер порта или как имя службы. Диапазон портов можно указать как числовые номера портов в формате nn-mm. В общем случае, порт назначения должен быть указан, если не указана опция -U. Для некоторых опций значение 0 указывает на то, что система должна выбрать номер порта.
МОДЕЛЬ КЛИЕНТ/СЕРВЕР
Довольно просто создать очень простую модель клиент/сервер с помощью nc. В одной консоли запустите nc, чтобы он прослушивал определенный порт для подключения. Например:
$ nc -l 1234
Теперь nc прослушивает порт 1234 в ожидании подключения. В другой консоли (или на другом компьютере) подключитесь к машине и порту, на котором выполняется прослушивание:
$ nc -N 127.0.0.1 1234
Теперь между портами должно быть установлено соединение. Все, что вы вводите во второй консоли, будет объединено с первой, и наоборот. После установления соединения nc не особо заботится о том, какая сторона используется как «сервер», а какая — как «клиент». Соединение можно завершить, отправив EOF («^D»), поскольку указан флаг -N.
В этой версии netcat нет опций -c или -e, но вы все равно можете выполнить команду после установления соединения, перенаправив дескрипторы файлов. Будьте осторожны, потому что открытие порта и разрешение любому подключиться и выполнять произвольные команды на вашем сайте — это ОПАСНО. Если вам действительно нужно это сделать, вот пример:
На стороне «сервера»:
$ rm -f /tmp/f; mkfifo /tmp/f
$ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
На стороне «клиента»:
$ nc host.example.com 1234
$ (подсказка оболочки с host.example.com)
Выполняя это, вы создаете FIFO в /tmp/f и заставляете nc прослушивать порт 1234 по адресу 127.0.0.1 на стороне «сервера». Когда «клиент» успешно устанавливает соединение с этим портом, на стороне «сервера» запускается /bin/sh и клиенту предоставляется подсказка оболочки.
Когда соединение прерывается, nc также завершает работу. Используйте -k, если вы хотите, чтобы он продолжал прослушивать, но если команда завершается, эта опция не перезапустит ее и не позволит nc продолжать работать. Также не забудьте удалить дескриптор файла, когда он больше не нужен:
$ rm -f /tmp/f
ПЕРЕДАЧА ДАННЫХ
Пример в предыдущем разделе можно расширить для создания базовой модели передачи данных. Любая информация, вводимая в одном конце соединения, будет выводиться на другом конце, и входные и выходные данные могут быть легко захвачены для эмуляции передачи файлов.
Начните с использования nc для прослушивания определенного порта, при этом вывод перенаправляется в файл:
$ nc -l 1234 > filename.out
Используя вторую машину, подключитесь к прослушивающему процессу nc, передавая ему файл, который необходимо передать:
$ nc -N host.example.com 1234 < filename.in
После передачи файла соединение автоматически закроется.
ОБЩЕНИЕ С СЕРВЕРАМИ
Иногда бывает полезно «руками» общаться с серверами, а не через пользовательский интерфейс. Это может помочь в устранении неполадок, когда может потребоваться проверить, какие данные отправляет сервер в ответ на команды, отправляемые клиентом. Например, для получения главной страницы веб-сайта:
$ printf "GET / HTTP/1.0\r\n\r\n" | nc host.example.com 80
Обратите внимание, что это также отображает заголовки, отправляемые веб-сервером. Их можно отфильтровать, используя такой инструмент, как sed(1), при необходимости.
Более сложные примеры могут быть созданы, когда пользователь знает формат запросов, необходимых серверу. В качестве другого примера электронное письмо можно отправить на SMTP-сервер, используя:
$ nc [-C] localhost 25 << EOF
HELO host.example.com
MAIL FROM:<_>
RCPT TO:<_>
DATA
Тело электронного письма.
.
QUIT
EOF
СКАНИРОВАНИЕ ПОРТОВ
Может быть полезно знать, какие порты открыты и какие службы выполняются на целевой машине. Флаг -z можно использовать, чтобы nc сообщал об открытых портах, а не устанавливал соединение. Обычно полезно включить подробный вывод в stderr, используя эту опцию в сочетании с опцией -v.
Например:
$ nc -zv host.example.com 20-30
Connection to host.example.com 22 port [tcp/ssh] succeeded!
Connection to host.example.com 25 port [tcp/smtp] succeeded!
Диапазон портов был указан, чтобы ограничить поиск портами 20-30, и он сканируется в порядке возрастания (если не установлен флаг -r).
Вы также можете указать список портов для сканирования, например:
$ nc -zv host.example.com http 20 22-23
nc: connect to host.example.com 80 (tcp) failed: Connection refused
nc: connect to host.example.com 20 (tcp) failed: Connection refused
Connection to host.example.com port [tcp/ssh] succeeded!
nc: connect to host.example.com 23 (tcp) failed: Connection refused
Порты сканируются в порядке, указанном вами (если не установлен флаг -r).
В качестве альтернативы может быть полезно узнать, какое серверное программное обеспечение запущено и какие версии используются. Эта информация часто содержится в приветственных баннерах. Чтобы получить их, необходимо сначала установить соединение, а затем разорвать соединение после получения баннера. Это можно сделать, указав небольшое время ожидания с помощью флага -w или, возможно, отправив команду "QUIT" на сервер:
$ echo "QUIT" | nc host.example.com 20-30
SSH-1.99-OpenSSH_3.6.1p2
Несовпадение протокола.
220host.example.com IMS SMTP Receiver Version 0.84 Ready
ПРИМЕРЫ
Установить TCP-соединение с портом 42 на host.example.com, используя порт 31337 в качестве исходного порта, с временем ожидания 5 секунд:
$ nc -p 31337 -w 5 host.example.com 42
Установить UDP-соединение с портом 53 на host.example.com:
$ nc -u host.example.com 53
Установить TCP-соединение с портом 42 на host.example.com, используя 10.1.2.3 в качестве IP-адреса для локального конца соединения:
$ nc -s 10.1.2.3 host.example.com 42
Создать и прослушивать Unix-доменный сокет:
$ nc -lU /var/tmp/dsocket
Подключиться к порту 42 на host.example.com через HTTP-прокси-сервер по адресу 10.2.3.4, порт 8080. Этот пример также можно использовать с ssh(1); см. директиву ProxyCommand в ssh_config(5) для получения дополнительной информации.
$ nc -x10.2.3.4:8080 -Xconnect host.example.com 42
Тот же пример, но с включенной аутентификацией прокси с именем пользователя "ruser", если это требуется прокси:
$ nc -x10.2.3.4:8080 -Xconnect -Pruser host.example.com 42
ССЫЛКИ
АВТОРЫ
Первоначальная реализация от *Hobbit* <_>. Переписано с поддержкой IPv6 Эриком Джексоном <_>. Изменено для порта Debian Ароном Сюй ⟨_⟩.
ОГРАНИЧЕНИЯ
UDP-сканирование портов с использованием комбинации флагов -uz всегда сообщает об успехе, независимо от состояния целевой машины. Однако в сочетании с анализатором трафика либо на целевой машине, либо на промежуточном устройстве, комбинация -uz может быть полезна для диагностики связи. Обратите внимание, что объем генерируемого UDP-трафика может быть ограничен либо аппаратными ресурсами, либо настройками конфигурации.