Probe Your Linux Sockets With ss
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
UNIX sockets, also called inter-process communication (IPC) sockets, are internal sockets that processes use to communicate with each other on your Linux computer.
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 22.214.171.124:http tcp LAST-ACK 1 1 192.168.0.135:60078 126.96.36.199: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.
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 188.8.131.52:https users:(("chromium-browse",pid=2933,fd=77)) ESTAB 0 0 192.168.0.135:60274 184.108.40.206:https users:(("chromium-browse",pid=2933,fd=114)) FIN-WAIT-1 0 619 192.168.0.135:57666 220.127.116.11:https ESTAB 0 0 192.168.0.135:52086 18.104.22.168:https users:(("chromium-browse",pid=2933,fd=108)) SYN-SENT 0 1 192.168.0.135:46660 22.214.171.124:http users:(("firefox",pid=3663,fd=55)) SYN-SENT 0 1 192.168.0.135:46662 126.96.36.199: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))
-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.