2026-04-28
Everyone knows netcat. It's the first thing you reach for when you need to shove bytes between two endpoints. But netcat is a pocket knife. socat is an entire machine shop. It connects any two bidirectional byte streams — sockets, files, pipes, PTYs, serial devices, SSL connections, UNIX domain sockets, SCTP — and it does it with a composable address syntax that, once you internalize it, makes you dangerous.
The basic grammar is socat [options] ADDRESS1 ADDRESS2. Each address is a type (like TCP-LISTEN, UNIX-CONNECT, EXEC, PTY) with options. Data flows bidirectionally between them. That's it. That's the whole model. The power is in what counts as an "address."
Expose a local Unix socket over TCP:
socat TCP-LISTEN:8080,reuseaddr,fork UNIX-CONNECT:/var/run/docker.sock
You now have the Docker API available on port 8080. The fork option means it handles multiple connections. You just built a proxy in one line.
Create an encrypted tunnel without setting up a VPN:
# On the server:
socat OPENSSL-LISTEN:4443,reuseaddr,fork,cert=server.pem,cafile=ca.crt EXEC:/bin/bash,pty,stderr
# On the client:
socat STDIO OPENSSL:server.example.com:4443,cert=client.pem,cafile=ca.crt
That's a TLS-encrypted remote shell with mutual certificate authentication. No SSH, no VPN, no configuration files. One line each side.
Turn a serial device into a TCP service:
socat TCP-LISTEN:2323,reuseaddr,fork /dev/ttyUSB0,b115200,raw,echo=0
Now anyone can telnet to port 2323 and talk to your embedded device. I've used this exact pattern to let three engineers debug the same UART simultaneously (add a tee with SYSTEM if you want logging).
Test a server that only listens on a Unix socket:
echo '{"method":"status"}' | socat - UNIX-CONNECT:/tmp/app.sock
The - means STDIO. Simpler than remembering curl --unix-socket syntax, and works with any protocol, not just HTTP.
Create a fake PTY for testing:
socat -d -d PTY,raw,echo=0,link=/tmp/vmodem0 PTY,raw,echo=0,link=/tmp/vmodem1
Two linked virtual serial ports. Write to one, read from the other. Perfect for testing serial protocol code without hardware. The -d -d flags give you debug output showing the allocated PTY names.
Port forwarding with timeout and logging:
socat -v -T 30 TCP-LISTEN:3307,fork TCP:db-server:3306
The -v flag dumps all traffic to stderr (hex + ASCII, like a mini Wireshark). -T 30 kills idle connections after 30 seconds. You've just built a transparent database proxy with traffic inspection.
The trick nobody knows — use SYSTEM addresses to inject shell commands into the data path:
socat TCP-LISTEN:8080,fork SYSTEM:'gzip -d | tee -a /var/log/raw.log | ./process_data'
Incoming gzipped data gets decompressed, logged, and piped to your processor. The entire ingest pipeline is one line.
Install it everywhere: apt install socat, brew install socat, apk add socat. It's been around since 2001 and it's in every distro's repos. The man page is a novel — man socat is 2000+ lines — but the address type list alone (socat -h) is worth memorizing.
