Note: Please read the updates as well, as the first part of this article has bugs.
So I had a moment a few weeks ago at work where we were trying to decide if a service was actually running on a machine. We had gotten to the point where we had actually ssh'd into the production machine, and were poking around trying to figure out what was up.
My coworker Fisher was driving, and I suggested he run
nmap on the box to see what ports were open. He ran it, but then as soon as the results came back, he started running another command. As he typed, he said, quite loudly, "Tuna Please!", and then ran the command
sudo netstat tunapl.
It outputs something like the following (truncated for brevity):
$ sudo netstat tunapl Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 192.168.1.18:ssh 126.96.36.199:30335 ESTABLISHED tcp 0 160 192.168.1.18:ssh cpe-72-231-30-23.:54860 ESTABLISHED Active UNIX domain sockets (w/o servers) Proto RefCnt Flags Type State I-Node Path unix 2 [ ] DGRAM 4002 /run/systemd/notify unix 2 [ ] DGRAM 9127 /run/user/109/systemd/notify unix 2 [ ] DGRAM 4020 /run/systemd/shutdownd unix 11 [ ] DGRAM 4022 /run/systemd/journal/dev-log unix 2 [ ] DGRAM 1890496 /run/user/1001/systemd/notify unix 7 [ ] DGRAM 4032 /run/systemd/journal/socket unix 2 [ ] DGRAM 4571 /run/systemd/journal/syslog ...
I had never seen this combo before, but it was an outage, so I completely forgot about it.
Then last week, I was like "oh yeah, Fisher used tuna please to figure this out". So I ran the command
sudo netstat tunaplz. It gave me the data I wanted, so I decided to go read the man page for the flags to see what it was doing. The following is what I gleaned from that page:
--tcp, -tTCP sockets
--udp, -uUDP sockets
Both make sense, I want both types of connections.
--numeric, -nShow numerical addresses instead of trying to determine symbolic host, port or user names.
I guess that's helpful.
-a, --allShow both listening and non-listening sockets.
Cool, I want all the things.
--program, -pShow the PID and name of the program to which each socket belongs.
Yeah, this is what I wanted to know in the first place!
--listening, -lOnly show listening sockets.
Wait, why this and
-a? Oh well.
The great part about this, and the amazing discovery, is that
-z, AFAICT, is not a valid flag, but
netstat just ignores it, instead of complaining!
So, if you're on a Linux box, and you wanna know about some sockets, just ask your computer for some Tuna Please!
sudo netstat tunaplz !!!
Update: As @saltyhorse pointed out, this is all dependent on versions and operating systems and what not. This has been tested in a few places, but specifically was written about a Debian install on a Raspberry Pi B+.
$ netstat --version net-tools 1.60 netstat 1.42 (2001-04-15) Fred Baumgarten, Alan Cox, Bernd Eckenfels, Phil Blundell, Tuan Hoang and others +NEW_ADDRT +RTF_IRTT +RTF_REJECT +FW_MASQUERADE +I18N AF: (inet) +UNIX +INET +INET6 +IPX +AX25 +NETROM +X25 +ATALK +ECONET +ROSE HW: +ETHER +ARC +SLIP +PPP +TUNNEL -TR +AX25 +NETROM +X25 +FR +ROSE +ASH +SIT +FDDI +HIPPI +HDLC/LAPB +EUI64 $ uname -a Linux newyork 4.1.13+ #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015 armv6l GNU/Linux
Update Number 2: So now I feel like a fool. Something seemed off when I was testing this late at night, and of course this article has been shared by an insane number of people, but @saltyhorse has shown me why
-z was being ignored!
@icco I have the same version string. Are you certain "netstat tunapl" doesn't ignore the flags? Does it print IP's instead of hostnames?— Ori Avtalion (@saltyhorse) May 9, 2016
The thing that I was confused about is why programs were only showing up for domain sockets (they weren't even programs, they were paths), but it was late at night, so #shrugs. Now that I'm more awake, and understanding what's going on, you need to put a
- in front of your args, and then
-z isn't ignored. Which makes much more sense. So much more sense.
So here is the correct output and call.
$ sudo netstat -tunapl Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 508/nginx -g daemon tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 414/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 765/exim4 tcp 0 72 192.168.1.18:22 188.8.131.52:64218 ESTABLISHED 14189/sshd: nat [pr tcp 0 0 192.168.1.18:22 184.108.40.206:25211 ESTABLISHED 15189/sshd: root [p tcp6 0 0 :::80 :::* LISTEN 508/nginx -g daemon tcp6 0 0 :::22 :::* LISTEN 414/sshd tcp6 0 0 ::1:25 :::* LISTEN 765/exim4 udp 0 0 0.0.0.0:42428 0.0.0.0:* 331/avahi-daemon: r udp 0 0 0.0.0.0:5353 0.0.0.0:* 331/avahi-daemon: r udp 0 0 0.0.0.0:68 0.0.0.0:* 339/dhcpcd udp 0 0 192.168.1.18:123 0.0.0.0:* 451/ntpd udp 0 0 127.0.0.1:123 0.0.0.0:* 451/ntpd udp 0 0 0.0.0.0:123 0.0.0.0:* 451/ntpd udp6 0 0 :::5353 :::* 331/avahi-daemon: r udp6 0 0 :::42257 :::* 331/avahi-daemon: r udp6 0 0 fe80::8b6:728b:e11::123 :::* 451/ntpd udp6 0 0 ::1:123 :::* 451/ntpd udp6 0 0 :::123 :::* 451/ntpd
Thanks to @saltyhorse for showing me the error of my ways. I'm saddened that the mnemonic is now less funny (no
-z), but overall still works.
Update Three: This is why journalists fact check their articles. Fisher has informed me that this mnemonic actually came from @timball. And he, "like Zoidberg, want the credit."