Sniff UNIX domain socket

I know that some process is writing to a certain unix domain socket (/var/run/asterisk/asterisk.ctl), but I do not known the pid of the sender. How can I find out who is writing to the socket? I have tried with:

sudo lsof /var/run/asterisk/asterisk.ctl

but it just list the owner of the socket. I would like to know who is writing / reading to this socket, and I would also like to sniff the data. Is this possible?


The short answers are no and not easily.

On Linux lsof relies on /proc/net/unix to retrieve the information regarding UNIX domain sockets. This interface lists all of the bound sockets, but it does not keep track of endpoints. So you can see what sockets exist, but you can't see what's connected to them. Somewhere this information is tracked, it must be tracked or else the sockets connections wouldn't work. I have yet to find any mechanism to retrieve the connection information.

The sniffing question is slightly more interesting, but no less disappointing. What I meant by "not easily" is that there does not exist any hook to sneak in and grap that data. The closest analog is using tcpdump or Wireshark, both of which use libpcap to actually do the heavy lifting. While network (AF_INET) and UNIX domain (AF_UNIX) are both created using the socket() function call, both use connect() to connect to, both use read() and write() to process data, they are handled by different kernel subsystems. This has the unfortunate side effect that libpcap is not designed to work with UNIX domain sockets.

There is a slightly less dim side to the problem. Take a look at the man page for recv(2). This is a lower level system call that read() makes use of. There exists a flag for recv() called MSG_PEEK. This would allow you to sniff the traffic passing through a UNIX domain socket. So that's the bright side, the dark side is that to the best of my knowledge there does not exist any current application designed to do this. So you're looking at some development effort.

I really wish there was a nice simple answer of F'YEAH to both parts of your question.


Yes, you can do this. All you need is systemtap.

Consider one of the example systemtap scripts which will print the PID and process name of any program that reads or writes a specified inode (and your Unix domain socket is just such a thing).

You can trivially modify this script to print the actual data being read/written; I'll leave doing so as an exercise to the reader.


I know this is not answering the main question, but I've ended up here, searching for just sniffing communication on a socket. I've decided to post for others like me. Here's how I did it:

$> sudo socat -t100 -x -v UNIX-LISTEN:/var/run/php5-fpm.sock.socat,mode=777,reuseaddr,fork UNIX-CONNECT:/var/run/php5-fpm.sock

You can remove -x and just leave -v for ascii communication. Hope that helps someone.