Бывает требуется опубликовать локальный TCP-сервис на другом порту или адресе, не изменяя конфигурацию приложения и не разворачивая отдельный reverse proxy. Для этого в линукс удобно использовать
socat — универсальный инструмент для двунаправленной передачи данных между сокетами.Установим
socat в Debian или Ubuntu:sudo apt update && sudo apt install socat -y
Предположим, приложение принимает соединения только на loopback-адресе:
127.0.0.1:8080
Проверим listener через
ss:ss -tlnp | grep ':8080'
Для сервиса, привязанного к IPv4 loopback, вывод может выглядеть так:
LISTEN 0 128 127.0.0.1:8080 0.0.0.0:*
Чтобы временно опубликовать сервис через порт
9000, запускаем дополнительный listener:socat TCP-LISTEN:9000,reuseaddr,fork \
TCP:127.0.0.1:8080
socat принимает соединения на 9000/tcp и для каждого из них устанавливает TCP-соединение с 127.0.0.1:8080. Без bind IPv4-listener обычно привязывается к 0.0.0.0, поэтому порт становится доступен на IPv4-адресах хоста с учётом firewall и других сетевых ограничений.Проверим новый listener:
ss -tlnp | grep ':9000'
Если входящие соединения на
9000/tcp разрешены, сервис можно проверить через адрес сервера:curl http://203.0.113.10:9000
Адреса из документационных диапазонов в примерах необходимо заменить реальными адресами своей инфраструктуры. Параметр
fork создаёт дочерний процесс для каждого принятого соединения, а reuseaddr включает SO_REUSEADDR и упрощает повторную привязку адреса после перезапуска.Если публиковать порт на всех локальных IPv4-адресах не требуется, listener можно привязать к конкретному адресу:
socat TCP-LISTEN:9000,bind=192.0.2.10,reuseaddr,fork \
TCP:127.0.0.1:8080
В этом случае соединения принимаются только на
192.0.2.10. Параметр bind выполняет привязку к IP-адресу, а не непосредственно к сетевому интерфейсу.socat также может проксировать TCP-соединения на другой сервер. Например, локальный 5433/tcp можно направить на PostgreSQL внутри другой сети:socat TCP-LISTEN:5433,bind=127.0.0.1,reuseaddr,fork \
TCP:10.0.0.20:5432
Для локального клиента это обычное соединение с
127.0.0.1:5433, тогда как socat передаёт байтовый поток на 10.0.0.20:5432:psql -h 127.0.0.1 -p 5433 database
Ещё один полезный сценарий — публикация Unix domain socket через локальный TCP-порт. Предположим, приложение использует следующий сокет:
/run/myapp/app.sock
Свяжем его с
127.0.0.1:8080:socat TCP-LISTEN:8080,bind=127.0.0.1,reuseaddr,fork \
UNIX-CONNECT:/run/myapp/app.sock
Если приложение обслуживает HTTP, проверить соединение можно через
curl:curl http://127.0.0.1:8080
Работает и обратное направление: Unix-сокет может передавать соединения в TCP:
socat UNIX-LISTEN:/tmp/backend.sock,fork \
TCP:127.0.0.1:8080
Для диагностики достаточно добавить
-d -d, чтобы socat выводил информацию о создаваемых соединениях:socat -d -d \
TCP-LISTEN:9000,reuseaddr,fork \
TCP:127.0.0.1:8080
Для постоянного проксирования предпочтительнее использовать штатную конфигурацию сервиса, reverse proxy, NAT или отдельный
systemd-unit. socat полезен для диагностики, временной публикации сервисов и связывания TCP с Unix domain sockets без изменения конфигурации приложений.🔥
socat позволяет одной командой организовать простой транспортный прокси между TCP-портами, удалёнными адресами и Unix-сокетами — хороший инструмент для диагностики и тестирования сетевого взаимодействия.🚪 Linux Ready | #практика