socat Socket Relay

socat cheatsheet — multipurpose relay for bidirectional data streams. socat TCP-LISTEN, socat SSL, socat pipe to exec. Port forwarding, SSL tunnels, and TCP proxying explained.

7 min read

What it is

socat is a command-line utility that establishes bidirectional data streams between two endpoints. It’s like a universal socket redirector, useful for connecting diverse network protocols, files, pipes, and devices.

Installation

Linux

sudo apt update && sudo apt install socat
# or
sudo yum install socat
# or
sudo dnf install socat

macOS

brew install socat

Windows

socat is not directly available as a native Windows executable. The common approach is to use it within the Windows Subsystem for Linux (WSL).

  1. Install WSL: Follow Microsoft’s official guide to install WSL.
  2. Install socat within WSL: Once WSL is set up, open your Linux distribution (e.g., Ubuntu) and run:
    sudo apt update && sudo apt install socat
    

Core Concepts

socat operates by connecting two addresses. An address defines an endpoint for data transfer. socat then relays data bidirectionally between these two connected addresses.

Common address types include:

  • TCP: tcp-listen:<port>, tcp:<host>:<port>
  • UDP: udp-listen:<port>, udp:<host>:<port>
  • File: file:<path>
  • STDIO: stdios
  • Pipes: pipe:<path>
  • PTY (Pseudo-terminal): pty
  • EXEC (Execute a program): exec:<command>

Commands / Usage

socat’s primary syntax is socat [options] <address1> <address2>.

Listening for Connections

TCP Server

socat TCP-LISTEN:12345,reuseaddr,fork EXEC:'/bin/bash -i'

Listens on TCP port 12345, accepts multiple connections (due to fork), and spawns an interactive bash shell for each connection. reuseaddr allows immediate reuse of the port.

socat TCP-LISTEN:54321 STDOUT

Listens on TCP port 54321 and prints any incoming data to standard output.

UDP Server

socat UDP-LISTEN:9999,fork STDOUT

Listens on UDP port 9999, accepts multiple datagrams (due to fork), and prints incoming data to standard output.

Unix Domain Socket Server

socat UNIX-LISTEN:/tmp/mysocket,fork EXEC:'/usr/bin/cat -'

Listens for connections on the Unix domain socket /tmp/mysocket. For each connection, it executes cat - which reads from its standard input (the connection) and writes to its standard output (the connection).

Making Connections

TCP Client

socat TCP:example.com:80 STDIN

Connects to example.com on port 80 and reads data from standard input to send.

socat TCP:192.168.1.100:8080 EXEC:'/bin/bash -i'

Connects to a remote host on port 8080 and spawns an interactive bash shell, relaying data between the shell and the remote connection.

UDP Client

socat UDP:192.168.1.200:53 STDIN

Sends data from standard input as UDP datagrams to 192.168.1.200 on port 53.

Unix Domain Socket Client

socat UNIX:/var/run/docker.sock STDOUT

Connects to the Docker daemon’s Unix domain socket and prints any data received to standard output.

File and Pipe Operations

Reading from a File

socat FILE:logfile.txt STDOUT

Reads the content of logfile.txt and prints it to standard output.

Writing to a File

socat STDIN FILE:output.txt

Reads data from standard input and writes it to output.txt.

Appending to a File

socat STDIN FILE:output.txt,append

Reads data from standard input and appends it to output.txt.

Reading from a Named Pipe

socat PIPE:/tmp/mypipe STDOUT

Reads data from the named pipe /tmp/mypipe and prints it to standard output.

Writing to a Named Pipe

socat STDIN PIPE:/tmp/mypipe

Reads data from standard input and writes it to the named pipe /tmp/mypipe.

Pseudo-terminals (PTY)

Creating a PTY Pair

socat PTY,link=/tmp/pty_master,raw,echo=0 EXEC:'/bin/bash -i'

Creates a pseudo-terminal pair. The master side is accessible via /tmp/pty_master. The slave side is attached to an interactive bash shell. raw disables terminal processing, and echo=0 prevents echoing input.

Executing Commands

Running a Command and Piping its Output

socat EXEC:'ls -l' STDOUT

Executes ls -l and sends its standard output to socat’s standard output.

Piping Input to a Command

SOCAT_CMD="echo hello world"
socat STDIN EXEC:"$SOCAT_CMD"

Reads from standard input and pipes it as standard input to the command specified by $SOCAT_CMD.

Connecting a Command’s Stdin/Stdout to a Socket

socat TCP:localhost:9000 EXEC:'/usr/bin/curl -X POST -d @-' localhost:8000

Connects to localhost:9000. Any data received on this TCP connection is sent as standard input to the curl command. The curl command then sends this data via HTTP POST to localhost:8000.

Combining Addresses and Options

Port Forwarding (TCP)

socat TCP-LISTEN:8080,fork TCP:localhost:3000

Listens on port 8080, and for each connection, forwards the traffic to localhost:3000.

TCP to UDP Relay

socat TCP-LISTEN:12345 UDP:localhost:54321

Listens for TCP connections on port 12345 and forwards received data to UDP port 54321 on localhost.

File to Network

socat FILE:data.txt TCP:remotehost:9999

Sends the content of data.txt over TCP to remotehost:9999.

Network to File

socat TCP:localhost:8888 FILE:received_data.bin

Listens for TCP connections on localhost:8888 and writes all received data to received_data.bin.

Common Options

  • -d, -dd, -ddd: Increase verbosity level for debugging (shows packets, connection attempts, etc.).
  • -s: Print statistics about data transfer.
  • fork: For listening sockets, creates a new process for each incoming connection, allowing multiple simultaneous clients.
  • reuseaddr: Allows the socket to be bound to an address that is already in use (useful for rapid restarts).
  • raw: Disables canonical mode and all special line processing on the pseudo-terminal.
  • echo=0: Disables echo on the pseudo-terminal.
  • bind=<ip>: Bind the listening socket to a specific IP address.
  • sourceport=<port>: Force the source port for outgoing connections.
  • wait-conn: Waits until the second address is actually connected before relaying data.

Common Patterns

Simple Shell Access over Network

# On the server:
socat TCP-LISTEN:4444,reuseaddr,fork EXEC:'/bin/bash -i'

# On the client:
socat TCP:server_ip:4444 STDIN

Provides a remote shell. Be cautious with this, as it’s insecure without encryption.

Port Forwarding with socat (a more robust alternative to ssh -L)

# Forward local port 8080 to remote port 3000 on a server that socat is running on
# On your local machine:
socat TCP-LISTEN:8080 TCP:your_server_ip:9000

# On your_server_ip:
socat TCP-LISTEN:9000 TCP:localhost:3000

This setup forwards local port 8080 to your_server_ip:9000, which then forwards to localhost:3000 on your_server_ip.

Secure Shell Access (using socat with OpenSSL)

# Server-side setup (generate certs first if you don't have them)
socat OPENSSL-LISTEN:8443,cert=server.pem,key=server.key,reuseaddr,fork EXEC:'/bin/bash -i'

# Client-side setup
socat OPENSSL:server_ip:8443,verify=0 STDIN

This provides an encrypted shell. verify=0 disables certificate verification for simplicity in this example; in production, you’d want proper verification.

Debugging Network Services

# Connect to a running service and see raw traffic
socat TCP:target_host:port STDOUT

# Send commands to a service and see responses
socat STDIN TCP:target_host:port

Creating a Network-based Pipe

# In one terminal:
socat TCP-LISTEN:12345 STDOUT

# In another terminal:
socat STDIN TCP:localhost:12345

Anything typed in the second terminal appears in the first, and vice-versa (if the first terminal is also set up to send back).

Interacting with Serial Ports

# Connect a serial port to a TCP port
socat PTY,link=/tmp/vserial0,raw,echo=0,waitslave FILE:/dev/ttyUSB0,raw,echo=0

# Then, connect to the PTY's master side
socat TCP-LISTEN:5000 PTY:/tmp/vserial0,raw,echo=0

This allows remote access to a serial device over TCP.

Gotchas

  • fork vs. wait-conn: fork is crucial for handling multiple clients on listening sockets. wait-conn is useful when you need to ensure the second address is connected before any data is relayed. Without wait-conn, data might be sent to an address that isn’t yet ready.
  • Buffering: Terminal applications often buffer output. socat itself can also buffer. Use the raw option on PTYs and file descriptors to disable terminal processing and buffering where appropriate for raw data streams.
  • Security: socat itself does not provide encryption. For secure communication, use socat with OPENSSL addresses or tunnel socat traffic through ssh or stunnel. Be extremely cautious when exposing shell access (EXEC:'/bin/bash -i') over unencrypted networks.
  • Error Handling: socat can be verbose with -d. Understanding the output is key to debugging connection issues. Look for messages about "connection refused," "timeout," or "address already in use."
  • File Permissions: When using UNIX-LISTEN, ensure the directory for the socket file has appropriate permissions.
  • Resource Limits: Be mindful of system limits on open file descriptors, especially when using fork extensively.