Probe Your Linux Sockets With ss

2477

We all know and love netstat (network statistics), because it is a wonderful tool for viewing detailed network connection information. An interesting alternative is ss, socket statistics. ss is part of the iproute2 suite of network tools.

ss displays statistics about your network sockets, which includes TCP, UDP, RAW, and UNIX domain sockets. Let us briefly review what these are.

Transmission Control Protocol (TCP) is a fundamental networking protocol. It is part of the Internet protocol suite and operates in the transport layer. All networking transmissions are broken up into packets. TCP guarantees that all packets arrive, in order, and without errors. This requires a lot of back-and-forth communication, as this joke illustrates:

“Hi, I’d like to hear a TCP joke.”
“Hello, would you like to hear a TCP joke?”
“Yes, I’d like to hear a TCP joke.”
“OK, I’ll tell you a TCP joke.”
“Ok, I will hear a TCP joke.”
“Are you ready to hear a TCP joke?”
“Yes, I am ready to hear a TCP joke.”
“Ok, I am about to send the TCP joke. It will last 10 seconds, it has two characters, it does not have a setting, it ends with a punchline.”
“Ok, I am ready to get your TCP joke that will last 10 seconds, has two characters, does not have an explicit setting, and ends with a punchline.”
“I’m sorry, your connection has timed out. Hello, would you like to hear a TCP joke?”

User Datagram Protocol (UDP is simpler and has less overhead. It is a connection-less protocol with no error checking or correction mechanisms, and does not guarantee delivery. There are UDP jokes, too:

I would tell you a UDP joke but you might not get it.

A UDP packet walks into a bar.
A UDP packet walks into a bar.

RAW sockets are naked. TCP and UDP encapsulate their payloads, and the kernel manages all the packets. RAW sockets transport packets without encapsulating them in any particular protocol, so we can write applications that manage network packets. Some applications that take advantage of RAW sockets are tcpdump and nmap.

UNIX sockets, also called inter-process communication (IPC) sockets, are internal sockets that processes use to communicate with each other on your Linux computer.

Dumping Sockets

Now we get to the fun part, dumping sockets! This is not quite as much fun as dumping a load from a backhoe, but it has its charms. These commands print the current state of TCP, UDP, RAW, and UNIX sockets respectively:

$ ss -ta
$ ss -ua
$ ss -wa
$ ss -xa

See how your UNIX sockets are verbose and numerous. If your Linux distribution uses systemd you’ll see it all over the place. This little incantation counts all the systemd lines:

$ ss -xa | grep systemd | wc -l
53

ss -a dumps everything. Let’s take a look at what the columns mean.

$ ss | less
Netid State    Recv-Q Send-Q Local Address:Port           Peer Address:Port                
u_seq ESTAB    0      0      @0002b 25461                 * 25462                
u_str ESTAB    0      0      @/tmp/dbus-C3OhS7lOOc 28053             * 22283   
udp   ESTAB    0      0      127.0.0.1:45509              127.0.1.1:domain               
tcp   ESTAB    0      0      192.168.0.135:40778          151.101.52.249:http 
tcp   LAST-ACK 1      1      192.168.0.135:60078          192.229.173.136:http
tcp   LISTEN   0      80     127.0.0.1:mysql                 *:*
tcp   LISTEN   0      128    :::ssh                         :::*

Netid displays the socket type and transport protocol.

State is the socket state, which are the standard TCP states. You’ll see ESTAB and LISTEN the most.

Recv-Q and Send-Q display the amount of data queued for receiving and sending, in bytes.

Local Address:Port is the open socket on your computer, and Peer is the address of the remote connection, if there is one.

Cool Examples

It’s always good to check for open ports. This shows all listening sockets:

$ ss -l

Seeing all the UNIX sockets isn’t necessary when you’re concerned about anything that might be open to the outside world, so this displays only listening TCP, UDP, and RAW sockets:

$ ss -tuwl
Netid  State      Recv-Q Send-Q  Local Address:Port    Peer Address:Port                
raw    UNCONN     0      0              :::ipv6-icmp   :::*                                                                                             
udp    UNCONN     0      0               *:bootpc      *:* 
tcp    LISTEN     0      80      127.0.0.1:mysql       *:*                                      
tcp    LISTEN     0      128             *:ssh         *:*                                       
tcp    LISTEN     0      128            :::http        :::*                    

UNCONN, unconnected, is the same as LISTEN. This example shows that pings are not blocked, bootpc is listening for DHCP assignments, MySQL is listening for local connections only, and SSH and HTTP are open to all requests, including external. *:* means all IPv4 addresses, and :::* means all IPv6 addresses.

You can see which processes are using sockets, which can be quite enlightening. This example shows the activity generated by a bit of Web surfing:

$ ss -tp
State      Recv-Q Send-Q         Local Address:Port       Peer Address:Port                
ESTAB      0      918            192.168.0.135:49882      31.13.76.68:https 
users:(("chromium-browse",pid=2933,fd=77))
ESTAB      0      0              192.168.0.135:60274      108.177.98.189:https 
users:(("chromium-browse",pid=2933,fd=114))
FIN-WAIT-1 0      619            192.168.0.135:57666      208.85.40.50:https                
ESTAB      0      0              192.168.0.135:52086      31.13.76.102:https                 
users:(("chromium-browse",pid=2933,fd=108))
SYN-SENT   0      1              192.168.0.135:46660      52.84.50.246:http                  
users:(("firefox",pid=3663,fd=55))
SYN-SENT   0      1              192.168.0.135:46662      52.84.50.246:http                  
users:(("firefox",pid=3663,fd=66))

Want to see the domain names? Add -r, for “resolve”:

$ ss -tpr
State      Recv-Q Send-Q    Local Address:Port     Peer Address:Port                
ESTAB      0      0         studio:48720           ec2-50-18-192-250.
us-west-1.compute.amazonaws.com:https   users:(("firefox",pid=3663,fd=71))
ESTAB      0      0         studio:57706            www.pandora.com:https                 
users:(("firefox",pid=3663,fd=69))
ESTAB      0      0          studio:49992           edge-star-mini-shv-01-
sea1.facebook.com:https      users:(("chromium-browse",pid=2933,fd=77))

Use the -D [filename] to dump your results into a text file, or use tee so you can see the output in your terminal and also store it in a file:

$ ss -tpr | tee ssoutput.txt

The more you know about TCP/IP, the more tools like ss will work effectively for you. The fine man ss contains a lot of useful examples, and if you install the iproute2-doc package you’ll find more help.

Learn more about Linux through the free “Introduction to Linux” course from The Linux Foundation and edX.