You know, like "lions and tigers and bears, oh my"… okay, not funny, moving on…
The problem#
There's a lot of different ways to transmit streams of bytes between applications on the same host or different hosts with various reasons you might want to use each one. And sometimes the two endpoints might disagree on which one they want to be using.
The solution#
As it turns out, there actually is a single answer to
bridging any two byte streams: socat
. The documentation
has plenty of examples. Here's a few I made up involving
named pipes and Unix sockets to go along with
my recent posts:
Bridge a pair of named pipes to a Unix socket#
socat UNIX-LISTEN:test.sock 'PIPE:pipe_in!!PIPE:pipe_out'
Builds a bridge such that a client sees a Unix socket test.sock
and the
server communicates through two named pipes, pipe-in
to send data over
the socket and pipe_out
to read the data received over the socket.
Connect to Unix socket HTTP server via TCP#
socat TCP-LISTEN:8042,fork,bind=localhost \
UNIX-CONNECT:http.sock
For an HTTP server accepting connections via the Unix socket
http.sock
, makes it also accept connections via the TCP socket
localhost:8042
.
Forward a Unix socket over an SSH connection#
socat EXEC:"ssh remote 'socat UNIX-CLIENT:service.sock -'" \
UNIX-LISTEN:proxy-to-remote.sock
Note ssh
can do the same without socat
(including supporting
either side being a TCP port):
ssh -N -L ./proxy-to-remote.sock:./service.sock remote
But that demonstrates combining socat
and ssh
for getting access
to streams only accessible from a remote computer.
The details#
socat
vs. nc
#
socat
describes itself as "netcat++". nc
is the name of netcat's binary, which already points you towards a
philosophical difference between the two tools: unlike socat
verbose options, nc
is terse:
$ nc -l -p 1234
# which can also be written with long options:
$ nc --listen --source-port 1234
is approximately equivalent to
$ socat - TCP-LISTEN:1234
Which one you prefer is a matter of taste: it's a lot more obvious at
a glance what the socat
command does, but the nc
command
takes up less space and is faster to type. Additionally, socat
has
a lot of options and is presumably more flexible than
nc
.
nc
has some complicated history resulting in
there being multiple forks, so the exact feature set available on a
given system may vary. If you're sticking to TCP/UDP, that's supported
in the original, but Unix sockets and more obscure protocols like
DCCP or SCTP are only available in some verions, so you
can't necessarily rely on them being available on an arbitrary machine.
(It also doesn't support named pipes explicitly, but shell redirection
can handle them.)
As the older tool, nc
is more likely to be available on a given
system, which may make it preferable for use in scripts which may run a
lot of different systems.
SSH forwarding#
While socat
does support SSL/TLS for encryption, often it's more
convenient to use SSH for encryption instead. As shown in the example
above, the two can be combined where appropriate.
ssh
offers the -L
and -R
options for forwarding
TCP (or in newer versions also Unix) sockets. The L
and R
stand
for Local or Remote, referring to which side SSH listens on,
forwarding those connections to the other side. That is, -L
listens to
a TCP or Unix socket on the local side and forwards all connections made
to that socket to the other one specified for the remote computer, which
is presumably already running a service listening for connections. You
can find plenty of example usages online, including
this StackExchange answer.
Also used in the example above is the other way to forward streams over
SSH: standard input/output. When ssh
is run with a command as an
argument, the standard input/output pipes are forwarded over the SSH
connection. In the example above, this is used to effectively tunnel
socat
through SSH, although it can be used in general to flexibly
run any part of any command pipeline on a different computer.
Comments
Have something to add? Post a comment by sending an email to comments@aweirdimagination.net. You may use Markdown for formatting.
There are no comments yet.