In this post, I’m going to go over two tools for inspecting the socket states (
ss), and why to choose one over the other (spoiler: you can really choose either). This is not going to be a 12 ways to inspect socket states article, there are lots of those.
What is a socket?
A socket is a Linux file descriptor for communicating with the network. In Linux, they say everything is a file. In this case, you can treat a socket like a file that writes to the network instead of writing to a disk. Sockets come in different flavors for TCP vs. UDP. For more on sockets, checkout these links:
- The Linux Programming Interface (this is really great)
- Beej’s Network Programming Guide (not quite TLPI, but available for free)
Why would I care about sockets?
Sockets can be in a bunch of different states (listed in this snippet of ss) which can be useful to answer questions like:
- Is my server process actually listening on the port I think it is?
- Is it listening on the loopback interface (
127.0.0.1), or could someone on my network connect to it (
0.0.0.0)? (This can be bad if you’re developing something and running a database that anyone in the coffee shop can make requests to)
- What processes are listening on what ports in general?
These questions pertain to sockets that are listening on a host, but there are also various connected states a socket can be in. High Performance Browser Networking’s TCP overview if great for some explanation of the other states (or again TLPI is excellent)
How do I inspect the state of sockets on my machine?
The two tools I’ll cover are the command line tools
ss. I’ll start with where they get their information.
The Procfs is a file system that Linux exposes that is like a peek into kernel memory. It lives in
/proc and it exposes information about TCP and UDP sockets at
/proc/net/udp. If I
cat either of those I’ll get some inscrutable output.
The other source of information is called the
netlink protocol. In this case you open a socket (a
AF_NETLINK as seen here). I can then send requests on that socket for information about other sockets (pretty meta). I have a lot to learn still about
netlink, but here are some things I found:
libnldocumentation which is a library for interacting with
- RFC 3594 – Linux Netlink as an IP Services Protocol
Netstat vs. ss
netstat gets its information from
/proc/net directly. It parses the file and prints out information based on it.
ss was written more recently to use the
netlink API (it will fall back to
proc/net if netlink is unavailable). The information in both systems is essentially the same (from what I’ve seen), but here are some arguments for why to use
- It’s faster (I just read that a lot, I don’t find
netstatto be noticeably slower)
- Netlink exposes more TCP states (again I mostly look for
LISTENso that’s not a huge selling point)
- It has better default argument
None of these are a huge homerun, which is why I expect a lot of people still use
netstat. It’s also likely that
netstat is installed more places. For instance my Macbook has
netstat but not
The default arguments is a little more compelling.
netstat by default will try to resolve IP addresses through DNS which really slows it down. It also opens a bunch of new UDP sockets, which might clutter the picture if you’re investigating something.
netstat -n stops this behavior, but
ss has that on by default (you can use
ss -r if you do want the resolution).
One other nice thing about
ss is that its source code is much nicer to read!
Here are some things I am still wondering
- What are the states that netlink supports that
netstatwon’t show? Are they states I actually care about?
- Where does
lsof -ifit in with all of this? Why would I choose that over
- What other users are there for netlink?
- Can I use netlink to poll for any new UDP connection? (I’ve been wanting to do this to figure out what process is sending UDP packets to a particular IP address, which is easy with TCP but hard with UDP)