socat и netcat решают общую задачу: соединить два потока данных. netcat — минимальный TCP/UDP-клиент и сервер, socat — конструктор из адресов, который умеет файлы, сокеты, TLS, последовательные порты и запуск программ. Вместе они закрывают проверку портов, отладку протоколов, передачу файлов в доверенной сети и быстрые туннели. Ниже — практические рецепты и ограничения.
Какая реализация netcat у вас стоит
У netcat нет единого стандарта. Debian и Ubuntu по умолчанию ставят netcat-openbsd, Fedora — nmap-ncat, в Arch обычно используют openbsd-netcat. Отличаются ключи: у OpenBSD nc есть -z и -N, у traditional nc — -e, у ncat — —ssl и —exec. Проверьте справку до того, как копировать команду из статьи.
nc -h 2>&1 | head -n 5
update-alternatives --display nc
ncat --version
socat -V
Если в выводе есть «OpenBSD netcat», ориентируйтесь на синтаксис с -z. Если стоит ncat, доступны TLS и прокси, но часть привычных флагов не работает.
Проверка доступности портов
Самый частый сценарий — понять, слушает ли служба порт и проходит ли трафик через фильтр. OpenBSD nc проверяет соединение ключом -z, подробный вывод включает -v. Несколько портов можно перечислить в одной команде.
nc -zv 192.0.2.10 22 80 443
nc -zvu 192.0.2.10 53
nc -zv -w 3 example.org 443
ss -tlnp | grep -E ':(22|80|443)\b'
UDP проверяется иначе: ответа может не быть даже при открытом порту, поэтому -zvu показывает лишь отсутствие явного отказа. Для локальной картины используйте ss -tlnp — он покажет, какой процесс держит порт и на каком адресе. Если служба слушает только 127.0.0.1, снаружи порт будет закрыт при работающем сервисе.
Однострочный сервер и отладка протокола
netcat умеет принимать соединение и выводить данные в терминал. Это удобно, чтобы увидеть, что именно присылает клиент, или вручную отправить HTTP-запрос. socat добавляет fork и reuseaddr: без fork сервер обслужит одно соединение и завершится, а без reuseaddr повторный запуск может упереться в «Address already in use».
nc -l 9000
socat -d -d TCP-LISTEN:9001,reuseaddr,fork -
printf 'GET / HTTP/1.1\r\nHost: example.org\r\nConnection: close\r\n\r\n' | nc example.org 80
ss -tlnp | grep -E '9000|9001'
Первые две команды — альтернативные способы поднять слушатель, запускайте одну из них. Ключ -d -d у socat включает подробный лог: видно, какие адреса открыты и сколько байт прошло. Для HTTPS такой приём не сработает — нужен TLS-слой, о нём ниже. Не оставляйте nc -l на внешнем интерфейсе: соединение не аутентифицируется.
Передача файлов в доверенной сети
На приёмнике запускают слушатель, на отправителе — клиент. socat умеет открывать файл напрямую, что избавляет от перенаправлений и лишних оболочек. Проверяйте целостность контрольной суммой: TCP гарантирует доставку, но не защищает от ошибки в команде или обрыва на стороне приложения.
# приёмник
socat -u TCP-LISTEN:9000,reuseaddr OPEN:backup.tar.zst,creat,trunc
# отправитель
socat -u FILE:backup.tar.zst TCP:192.0.2.10:9000
sha256sum backup.tar.zst
Флаг -u задаёт однонаправленный поток, OPEN создаёт файл. Если файл большой, сравните размер и хеш на обеих сторонах: частичная передача иногда выглядит успешной, но даёт обрезанный архив. Для каталогов сначала соберите архив. Для регулярных задач используйте rsync поверх SSH: он шифрует, докачивает и проверяет результат, а команды стоит оформить в небольшой скрипт с проверкой статуса.
Unix-сокеты и локальные перенаправления
Многие службы общаются через Unix-сокет, а не TCP. socat позволяет подключиться к нему из программы, которая умеет только TCP, или наоборот — выставить сокет через локальный порт. Это удобно для отладки API контейнеров и демонов.
socat - UNIX-CONNECT:/run/app/app.sock
socat TCP-LISTEN:8081,bind=127.0.0.1,fork UNIX-CONNECT:/run/app/app.sock
socat UNIX-LISTEN:/tmp/proxy.sock,fork TCP:127.0.0.1:8080
curl --unix-socket /tmp/proxy.sock http://localhost/
Обратите внимание на bind=127.0.0.1: без него порт откроется на всех интерфейсах. Права на сокет задаются umask или chmod, иначе любой пользователь системы сможет подключиться к вашему демону.
TLS-туннель на своих сертификатах
socat умеет оборачивать поток в OpenSSL без сторонних демонов. Это полезно для тестового стенда и передачи данных между двумя своими машинами. Сертификат можно выпустить самому через openssl, но обе стороны должны доверять центру.
openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365 -subj "/CN=192.0.2.10" -addext "subjectAltName=IP:192.0.2.10"
socat OPENSSL-LISTEN:4433,reuseaddr,fork,cert=cert.pem,key=key.pem,verify=0 -
socat OPENSSL-CONNECT:192.0.2.10:4433,cafile=cert.pem,verify=1 -
openssl s_client -connect 192.0.2.10:4433 -CAfile cert.pem
verify=0 на сервере отключает проверку клиентского сертификата — так делать можно только в изолированной сети. Для постоянного канала лучше SSH: он даёт аутентификацию, пересылку портов и проверенные алгоритмы без ручной сборки.
Последовательный порт
Отладка Arduino, роутера или промышленного контроллера часто требует доступа к /dev/ttyUSB0. socat соединяет порт с терминалом или TCP, что позволяет работать удалённо. Скорость и режим задаются в адресе.
socat - /dev/ttyUSB0,b115200,raw,echo=0
socat TCP-LISTEN:2323,reuseaddr,fork /dev/ttyUSB0,b115200,raw,echo=0
picocom -b 115200 /dev/ttyUSB0
Права на устройство обычно дают через группу dialout. Не запускайте два клиента на одном порту: данные будут перемешаны.
Безопасность и ограничения
- netcat и socat не шифруют трафик и не проверяют пользователя.
- Слушайте только на localhost, если доступ нужен одной машине.
- Ограничивайте время жизни соединения ключами -t, -w и опцией connect-timeout.
- Не передавайте через них пароли и ключи в открытом виде.
- Проверяйте, что порт не открыт в интернет, через ss и правила файрвола.
Диагностика
Если соединение не устанавливается, идите по цепочке: DNS, маршрут, файрвол, слушающий процесс. socat с тремя -d показывает детали, strace — системные вызовы, tcpdump — пакеты. Частая ошибка — забытый fork: сервер принимает одно соединение и молча закрывается.
socat -d -d -d TCP-LISTEN:9000,reuseaddr,fork -
strace -f -e trace=network socat - TCP:192.0.2.10:9000
ss -tlnp
tcpdump -ni any port 9000
Проверяйте коды возврата в скриптах: socat возвращает ненулевой статус при ошибке, и без проверки цикл будет молча крутиться. Для постоянных сервисов используйте systemd-юнит с Restart=on-failure, а не nohup.
Итог
netcat хорош для быстрой проверки порта и ручного диалога с протоколом, socat — для файлов, Unix-сокетов, TLS и последовательных портов. Оба инструмента просты ровно настолько, насколько просты ваши задачи, и опасны там, где начинается недоверенная сеть. Держите их в наборе диагностики, но постоянные каналы стройте на SSH и настоящем TLS.