socat: швейцарский нож сетевых соединений
socat — утилита для соединения двух потоков данных: TCP-порта, файла, stdin, UNIX-сокета, TLS-соединения, псевдотерминала или процесса. Поэтому её называют «швейцарским ножом» для сети — она не заменяет прокси, балансировщики и VPN, но отлично закрывает разовые инженерные задачи.
Если netcat — это простой TCP-клиент и сервер из консоли, то socat идёт дальше: умеет TLS, UNIX domain sockets, форвардинг между разными типами адресов, fork для параллельных подключений, подробный вывод трафика и запуск процессов на одном из концов соединения.
Разработчикам и DevOps-инженерам socat пригождается при отладке API, проверке сетевой доступности, тестировании проксирования, временном пробросе портов и работе с контейнерами и локальными сервисами. Главное — разбираться в синтаксисе адресов и не превращать временный хак в постоянную и небезопасную схему.
Что такое socat и чем он отличается от netcat
Название socat обычно расшифровывают как SOcket CAT — по аналогии с cat, только вместо чтения файла в stdout он соединяет два произвольных канала ввода-вывода.
Базовая форма команды выглядит так:
socat [опции] АДРЕС1 АДРЕС2Например, соединить терминал с TCP-портом:
socat - TCP:example.com:80Здесь - означает стандартный ввод-вывод, а TCP:example.com:80 — TCP-соединение с example.com на порт 80.
Главное отличие от nc — ширина набора адресов. socat умеет не только TCP и UDP, но и OPENSSL, UNIX-CONNECT, UNIX-LISTEN, EXEC, SYSTEM, PTY, FILE, OPEN, TUN, UDP-LISTEN, TCP-LISTEN и другие типы. Это не просто «стучаться в порт», а строить трубу между двумя источниками данных.
1) Где удобнее netcat — быстрая проверка TCP-порта, ручная отправка HTTP-запроса, простейший listener. Если нужно «подключиться и посмотреть, отвечает ли сервис», nc обычно короче.
2) Где удобнее socat — когда нужно связать TCP с UNIX-сокетом, добавить TLS, прокинуть порт с fork, поднять временный мост между контейнером и хостом, создать псевдотерминал или логировать байты в обе стороны.
3) Где нужны другие инструменты — для анализа маршрута лучше traceroute или mtr, для просмотра открытых портов — ss и netstat, для HTTP-диагностики — curl, для TLS — openssl s_client. socat хорошо дополняет эти инструменты, но не делает их ненужными. Например, перед пробросом порта стоит проверить, кто слушает сокет, через утилиту ss, а HTTP-ответ удобнее разобрать через curl.
Установка и базовый синтаксис
В большинстве Linux-дистрибутивов socat есть в стандартных репозиториях.
Debian и Ubuntu:
sudo apt update
sudo apt install socatRHEL, CentOS Stream, Fedora:
sudo dnf install socatArch Linux:
sudo pacman -S socatmacOS через Homebrew:
brew install socatПроверить версию:
socat -VСинтаксис строится вокруг двух адресов, каждый из которых состоит из типа и параметров:
socat [опции] АДРЕС1 АДРЕС2Примеры адресов:
-—STDIO, то есть стандартный ввод и вывод;TCP:host:port— TCP-клиент;TCP-LISTEN:port,reuseaddr,fork— TCP-сервер;UDP:host:port— UDP-клиент;UDP-LISTEN:port,reuseaddr— UDP-listener;UNIX-CONNECT:/path/socket— подключение к UNIX-сокету;UNIX-LISTEN:/path/socket,fork— создание UNIX-сокета;OPENSSL:host:port,verify=1— TLS-клиент;OPEN:file— файл;EXEC:'command'— процесс.
Часто используемые опции:
-d -d— диагностические сообщения;-v— печатать передаваемые данные;-x— печатать данные в hex;-T 5— таймаут бездействия в секундах;-ly— отправлять сообщения в syslog;fork— создавать отдельный процесс на каждое входящее соединение;reuseaddr— переиспользовать адрес после перезапуска listener;bind=127.0.0.1— слушать только на конкретном IP.
Пример echo-сервера на порту 9000:
socat -v TCP-LISTEN:9000,reuseaddr,fork EXEC:'/bin/cat'Теперь в другом терминале:
socat - TCP:127.0.0.1:9000Всё, что вы введёте, вернётся обратно. Минимальный пример, но он хорошо показывает суть: socat связывает сокет и процесс.
Быстрая проверка TCP и UDP
socat можно использовать как интерактивный клиент. Подключимся к HTTP-серверу и отправим запрос вручную:
socat - TCP:example.com:80После подключения введите:
GET / HTTP/1.1
Host: example.com
Connection: close
Пустая строка в конце обязательна: она завершает HTTP-заголовки.
То же самое одной командой:
printf 'GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n' \
| socat - TCP:example.com:80Для быстрой проверки, что порт принимает TCP-соединение, удобно добавить таймаут:
socat -T 3 - TCP:example.com:443Если соединение установилось, проблема может быть выше сетевого уровня: TLS, HTTP, авторизация, reverse proxy, приложение. Если соединение не устанавливается, проверьте DNS, firewall, слушающий процесс и маршрут. Для базовой диагностики портов пригодится материал про netstat, а для маршрутов — разбор mtr и WinMTR.
С UDP всё менее однозначно: отсутствие ответа не всегда означает недоступность, потому что UDP не устанавливает соединение. Но отправить пакет и послушать ответ можно:
socat - UDP:127.0.0.1:9999Поднять UDP-listener:
socat -v UDP-LISTEN:9999,reuseaddr -В другом терминале отправить сообщение:
echo 'hello' | socat - UDP:127.0.0.1:9999Для UDP-диагностики socat полезен как генератор и приёмник тестовых пакетов. Но если нужно смотреть реальные пакеты, флаги, ретрансляции и направление трафика, лучше подключать tcpdump.
Проброс портов и временный TCP-прокси
Один из самых частых сценариев — временно пробросить локальный порт на другой адрес. Например, на сервере есть PostgreSQL на 127.0.0.1:5432, а вам нужно открыть локальный порт 15432 только для теста:
socat TCP-LISTEN:15432,bind=127.0.0.1,reuseaddr,fork TCP:127.0.0.1:5432Теперь клиент может подключаться к 127.0.0.1:15432, а socat передаст трафик в 127.0.0.1:5432.
Если нужно слушать на всех интерфейсах:
socat TCP-LISTEN:15432,reuseaddr,fork TCP:127.0.0.1:5432Но это уже риск: порт может стать доступен извне. Перед такой командой проверьте firewall, security group и список слушающих портов. В Linux для базовой защиты удобно использовать UFW; подробный разбор есть в статье как настроить фаервол с помощью UFW в Ubuntu.
Можно сделать цепочку между двумя хостами:
socat TCP-LISTEN:8080,reuseaddr,fork TCP:10.0.0.25:80Полезно для временной проверки, когда приложение ожидает сервис на одном адресе, а реальный endpoint находится на другом. Но не стоит превращать это в постоянную архитектуру: нет health check, балансировки, метрик и прозрачного логирования — для продакшена лучше reverse proxy, firewall rules, load balancer или service mesh.
socat также умеет работать через HTTP CONNECT-прокси:
socat - PROXY:proxy.example.com:target.example.com:443,proxyport=3128И через SOCKS4:
socat - SOCKS4:proxy.example.com:target.example.com:443,socksport=1080Такие команды удобны для проверки, проходит ли трафик через корпоративный прокси или промежуточный bastion. Для стабильного доступа к серверу за NAT чаще выбирают SSH-туннели; близкая тема разобрана в статье про reverse SSH tunnel.
UNIX-сокеты, Docker и локальные сервисы
Многие локальные сервисы слушают не TCP-порт, а UNIX domain socket. Примеры: Docker daemon, PostgreSQL, Redis, Nginx upstream, systemd-сервисы. socat удобен, когда нужно быстро связать UNIX-сокет с TCP или руками отправить запрос.
Подключение к UNIX-сокету:
socat - UNIX-CONNECT:/var/run/docker.sockDocker API говорит по HTTP поверх UNIX-сокета. Можно отправить запрос:
printf 'GET /_ping HTTP/1.1\r\nHost: docker\r\n\r\n' \
| socat - UNIX-CONNECT:/var/run/docker.sockЕсли всё в порядке, Docker вернёт OK.
Временный мост TCP → UNIX-сокет:
socat TCP-LISTEN:23750,bind=127.0.0.1,reuseaddr,fork UNIX-CONNECT:/var/run/docker.sockТеперь локальный TCP-порт 23750 проксирует запросы в Docker socket. Команда полезна для отладки клиентов, которые не умеют UNIX-сокеты, но умеют TCP.
С Docker socket нужно быть особенно аккуратным. Доступ к /var/run/docker.sock почти равен root-доступу к хосту: через Docker API можно запускать контейнеры, монтировать файловую систему и менять окружение. Никогда не публикуйте такой мост на внешнем интерфейсе.
Создать UNIX-сокет и связать его с TCP-сервисом:
rm -f /tmp/app.sock
socat UNIX-LISTEN:/tmp/app.sock,fork,reuseaddr TCP:127.0.0.1:8080Это полезно, когда один компонент ожидает UNIX-сокет, а реальное приложение слушает TCP: в контейнерных окружениях такой мост помогает быстро проверить гипотезу до изменения конфигурации. Если нужно глубже разобраться с сетями контейнеров, посмотрите материал как работает Docker networking.
TLS-соединения через socat
socat умеет работать с TLS через адреса OPENSSL и OPENSSL-LISTEN. Это не замена специализированным инструментам, но удобный способ быстро проверить защищённое соединение или поднять временный TLS-терминатор.
Подключиться к HTTPS-серверу:
socat - OPENSSL:example.com:443,verify=1,snihost=example.comПосле подключения можно отправить HTTP-запрос:
GET / HTTP/1.1
Host: example.com
Connection: close
Если сертификат не проходит проверку, socat завершит соединение. Для системного хранилища сертификатов можно явно указать cafile или capath, если это нужно в вашей ОС:
socat - OPENSSL:example.com:443,verify=1,snihost=example.com,cafile=/etc/ssl/certs/ca-certificates.crtОтключить проверку можно так:
socat - OPENSSL:example.com:443,verify=0Но это стоит делать только для локальной диагностики. В таком режиме вы проверяете не «безопасное TLS-соединение», а лишь факт, что сервер отвечает на TLS-порту.
Временный TLS-listener перед локальным HTTP-сервисом:
socat OPENSSL-LISTEN:8443,reuseaddr,fork,cert=server.crt,key=server.key,verify=0 \
TCP:127.0.0.1:8080Команда принимает TLS на 8443 и передаёт расшифрованный трафик в локальный сервис на 8080. Для нормального reverse proxy в продакшене лучше Nginx, Caddy или HAProxy, но для проверки клиента, который требует TLS, socat часто быстрее.
Если задача — подробно разобрать сертификат, цепочку, SNI и ошибки рукопожатия, удобнее использовать openssl s_client. А для понимания самого процесса пригодится статья как работает HTTPS.
Логирование трафика и отладка протоколов
socat хорош не только как мост, но и как простой инструмент наблюдения. Опция -v печатает данные, проходящие через соединение:
socat -v TCP-LISTEN:8080,reuseaddr,fork TCP:127.0.0.1:3000Теперь клиент подключается к 8080, реальное приложение остаётся на 3000, а вы видите поток запросов и ответов в терминале.
Для бинарных протоколов полезен hex-вывод:
socat -x TCP-LISTEN:9000,reuseaddr,fork TCP:127.0.0.1:9001Диагностические сообщения включаются через -d -d:
socat -d -d TCP-LISTEN:8080,reuseaddr,fork TCP:127.0.0.1:3000Команда покажет, когда listener поднялся, когда пришло соединение, какой адрес подключился, когда процесс завершился.
Типичный сценарий отладки:
1) Проверить, слушает ли сервис порт — ss -lntp или netstat -lntp.
2) Подключиться вручную — socat - TCP:host:port или curl, если это HTTP.
3) Вставить временный прокси с логированием — socat -v TCP-LISTEN:... TCP:....
4) При необходимости снять пакеты — tcpdump на нужном интерфейсе и порту.
5) Сравнить с внешней проверкой — если локально всё работает, а пользователи жалуются, проверьте DNS, CDN, firewall, географию и доступность извне.
Здесь уместен мониторинг доступности: внешний сервис видит проблему не так, как сервер изнутри. Например, Statuser может проверять сайт с заданным интервалом и присылать уведомление о сбое, а socat уже пригодится во время расследования: быстро проверить порт, TLS или промежуточный прокси. Базовый подход к таким проверкам описан в статье про uptime monitoring.
Полезные рецепты socat
Ниже — набор команд, которые часто используют в админской и разработческой практике. Их стоит адаптировать под свои адреса, интерфейсы и правила доступа.
1) Проверить HTTP через raw TCP
printf 'GET /health HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n' \
| socat - TCP:127.0.0.1:8080Полезно, когда нужно исключить влияние клиента, SDK или прокси-библиотеки.
2) Поднять простой TCP-listener
socat -v TCP-LISTEN:9000,reuseaddr,fork -Всё, что отправит клиент, появится в терминале. Удобно для проверки, доходит ли трафик.
3) Отправить файл по TCP
На принимающей стороне:
socat TCP-LISTEN:9000,reuseaddr OPEN:received.bin,creat,truncНа отправляющей стороне:
socat OPEN:file.bin TCP:server.example.com:9000Для регулярной передачи файлов лучше scp, rsync или объектное хранилище, но для одноразового теста команда рабочая.
4) Проксировать локальный порт на удалённый сервис
socat TCP-LISTEN:8081,bind=127.0.0.1,reuseaddr,fork TCP:remote.internal:8080Подходит для проверки приложения, которое умеет обращаться только к localhost.
5) Создать псевдотерминал
socat -d -d PTY,raw,echo=0 PTY,raw,echo=0socat выведет два пути вида /dev/pts/3 и /dev/pts/4. Данные, записанные в один, появятся в другом. Это полезно при отладке программ, которые ожидают serial-like устройство.
6) Связать команду с TCP-портом
socat TCP-LISTEN:9001,bind=127.0.0.1,reuseaddr,fork EXEC:'/usr/bin/env'Каждое подключение получит вывод команды env. Это безопаснее, чем отдавать shell, но всё равно требует контроля: любой EXEC на сетевом порту должен считаться потенциальной точкой атаки.
7) Ограничить время ожидания
socat -T 5 - TCP:10.0.0.10:8080Если соединение зависло без данных, socat завершит работу через 5 секунд бездействия.
Безопасность и ограничения
socat легко создаёт мосты там, где их не было. Это мощно, но именно поэтому опасно: команда на одну строку может случайно открыть внутренний сервис наружу или дать доступ к UNIX-сокету с повышенными правами.
1) Привязывайте listener к нужному адресу — если доступ нужен только локально, используйте bind=127.0.0.1 и не полагайтесь на «я запущу ненадолго»: временные процессы часто забывают остановить.
2) Проверяйте firewall — listener на 0.0.0.0 может стать доступен из интернета. Используйте ss -lntp, iptables, nftables, UFW или cloud security groups.
3) Не публикуйте Docker socket — TCP-мост к /var/run/docker.sock должен быть только локальным и временным. Внешний доступ к нему почти всегда критическая уязвимость.
4) Осторожно с EXEC и SYSTEM — не запускайте shell на сетевом порту. Даже если порт доступен только «внутри сети», это может стать точкой lateral movement.
5) Не используйте verify=0 как норму — для TLS-диагностики допустимо, для продакшена нет. Отключение проверки сертификата скрывает часть проблем: неправильную цепочку, подмену, неверный hostname.
6) Не заменяйте мониторинг временным процессом — socat помогает расследовать, но не отвечает на вопросы «когда началось», «кого затронуло», «как часто повторяется». Для этого нужны метрики, логи, алерты и внешние проверки. Statuser, например, проверяет сайт с заданным интервалом и уведомляет о сбое; это дополняет ручную диагностику, а не конкурирует с ней.
Ограничения тоже стоит учитывать. socat не даёт полноценной observability, не хранит историю, не делает балансировку, не управляет конфигурацией, не заменяет TLS-терминацию в Nginx или HAProxy. Его сила — быстро построить соединение и проверить гипотезу.
Когда socat действительно выручает
socat полезен в промежутке между «непонятно, что происходит» и «мы уже меняем конфигурацию сервиса». Он позволяет быстро сделать эксперимент без кода и без деплоя.
1) Приложение не может подключиться к локальному сервису — поднимите listener или прокси и посмотрите, приходит ли трафик.
2) Нужно проверить доступность внутреннего endpoint — соедините локальный порт с удалённым адресом и протестируйте клиентом.
3) Клиент требует TLS, а тестовый сервис слушает HTTP — временно оберните соединение через OPENSSL-LISTEN.
4) Сервис работает через UNIX-сокет, а инструмент умеет только TCP — постройте мост TCP-LISTEN → UNIX-CONNECT.
5) Нужно увидеть сырой протокол — включите -v или -x и смотрите байты до подключения тяжёлой трассировки.
6) Нужно воспроизвести проблему минимальным способом — уберите SDK, фреймворк, браузер и оставьте только сокет.
Главное правило: после эксперимента зафиксируйте выводы и уберите временный мост. Если команда стала нужна постоянно, её лучше заменить нормальной конфигурацией reverse proxy, firewall, systemd unit, Docker Compose или инфраструктурным кодом.
FAQ
Можно ли заменить curl на socat?
Для HTTP-запросов — только частично. socat показывает сырой обмен и полезен для низкоуровневой отладки, но curl удобнее для редиректов, заголовков, TLS-деталей, методов и статусов.
Чем socat лучше netcat?
Он поддерживает больше типов соединений: TLS, UNIX-сокеты, псевдотерминалы, файлы, процессы, TCP/UDP-listener с fork. Для простых TCP-проверок netcat часто короче.
Безопасно ли открывать порт через socat?
Безопасно только при понятных границах доступа: bind=127.0.0.1, firewall, минимум прав, отсутствие опасного EXEC. Listener на всех интерфейсах может случайно открыть внутренний сервис наружу.
Можно ли использовать socat в продакшене?
Можно для точечных задач, но осторожно. Для постоянного проксирования, TLS-терминации и балансировки лучше использовать специализированные инструменты: Nginx, HAProxy, Caddy, SSH-туннели или сетевые компоненты платформы.
Похожие статьи

Мониторинг TCP-соединений. Retransmits, resets, SYN backlog и что они говорят о проблемах
Подробно объясняем, что означают TCP retransmits, resets и SYN backlog, как интерпретировать эти показатели и почему они помогают быстрее находить причины сетевых задержек и ошибок.
7 июля 202611 мин

Ошибка TLS-рукопожатия: причины и способы исправить
Практический разбор TLS handshake error: от сертификатов и SNI до CDN, Nginx, шифров и сетевых проблем.
10 августа 20269 мин

Утилита ss. Современная альтернатива netstat для анализа сетевых соединений
Рассматриваем возможности и синтаксис утилиты ss — мощного инструмента для анализа и диагностики сетевых соединений в Linux. Полный список полезных опций и практические примеры.
10 августа 20256 мин
Настроить мониторинг за 30 секунд
Надёжные уведомления о даунтаймах. Без ложных срабатываний