In most environments, you would only expect to find tcp, udp, raw and packet sockets. Happily,
ss knows about all of these.
ss knows all the protocols you need it to, I might use the following command. This will exclude the "unix" sockets. It also excludes "netlink" sockets, which are only used to communicate with the local kernel.
sudo ss -l -p | grep -vE '^(u_|nl )'
Often you do not have a lot of listening sockets. So you can look through them all, and manually ignore any that listen on loopback IP addresses. Alternatively, you can ask
ss to do all the filtering:
sudo ss -l -p -A 'all,!unix,!netlink' 'not src 127.0.0.1 not src [::1]'
In both cases, the output can also include "client" udp sockets. So it might also show DNS clients, HTTP/3 clients, ...
If you do not need to see information about the program which opened each socket, then you can remove the
-p option, and you do not need to run
netstat) with root privileges (
How comprehensive is the above command?
Despite being advertised as a replacement for netstat,
ss lacks the support for showing "udplite" sockets.
Also, the answer depends on your version of
ss (and I guess the kernel as well). When this answer was originally written, before 2017,
ss did not support "sctp".
netstat supported it since February 2014). sctp is expected specifically inside phone companies. Outside of phone companies, VOIP typically uses udp.
Unfortunately if you look for a comprehensive list in
man netstat, it gets quite confusing. Options for sctp and udplite are shown in the first line, along with tcp, udp and raw. Further down there's what looks like a comprehensive list of protocol families:
[-4|--inet] [-6|--inet6] [--unix|-x] [--inet|--ip|--tcpip] [--ax25] [--x25] [--rose] [--ash] [--bluetooth] [--ipx] [--netrom] [--ddp|--appletalk] [--econet|--ec].
netstat supports udplite and sctp, it does not support "dccp". Also netstat doesn't support packet sockets (like raw sockets but including link-level headers), as selected by
ss -l -0. In conclusion, I hate everything, and I could probably stand to be less pedantic.
ss does not support bluetooth sockets. Bluetooth sockets are not a traditional concern. This could be relevant if you were doing a full audit. Bluetooth security is quite a specific question though; I am not answering it here.
Omitting localhost in
netstat does not have a specific way to omit sockets bound to localhost. You could use
| grep -v on the end. Take care if you use the
-p option to netstat / ss. You might accidentally exclude some of your processes, if there is a match in the process name. I would include the colon in your pattern, like
grep -v localhost:. Except the default in
ss is to show numeric addresses, so in that case you would use
| grep -vE (127.0.0.1|\[::1\]):. I suppose you could try to check for processes which would be accidentally excluded, e.g.
ps ax | grep -E (127.0.0.1|\[::1\]):.
Is there a simpler command?
It's unfortunate about the packet sockets. Otherwise, I might suggest a plain
netstat -l command.
netstat helpfully anticipates your request and splits the output into "Internet connections", "UNIX domain sockets", and "Bluetooth connections". You would just look at the first section. There is no section for netlink sockets.
Suppose you're only concerned with tcp, udp, raw, and packet sockets. For the first three types of socket you could use
netstat -l -46.
Packet sockets are in common use. So you would also need to train yourself to run
ss -l -0 (or
ss -l --packet).
Unfortunately this leaves you with a big pitfall. The problem is it is now tempting to try and combine the two commands...
Traps to avoid with
ss -l -046 looks appealing as a single-command answer. However this is not true.
ss -46 only shows IPv6 sockets.
ss -64 only shows IPv4 sockets.
I suggest always sanity-checking your results. Learn what to expect; go through each protocol and see if there's anything missing that should be there. If you have no IPv4 addresses, or no IPv6 addresses, that's very suspicious. You can expect most servers to have an SSH service listening on both. Most non-servers should also show packet or raw sockets, due to using DHCP.
If you don't want to interpret the output of two different commands, one alternative might be to replace the
netstat command with
ss -l -A inet. This is slightly unfortunate because when you run netstat, the exact same options would exclude ipv6 sockets.
So for a single command, you could use
ss -l -A inet,packet ....
IMO you might as well use
ss -l | grep ... as I suggested in the first section. It is easy to remember this command, and it avoids any and all confusing behaviour in the selection options of
Although if you write scripts that use this output to automate something, then you should probably prefer to filter on a positive list of socket types instead. Otherwise the script could break when
ss starts supporting a new type of local-only socket.
Did I mention that
ss -a -A raw -f link shows a combination of sockets from
ss -a -A raw and
ss -a -f link ? Whereas
ss -a -A inet -f inet6 shows less sockets than
ss -a -A inet? I think
-f inet6 and
-f inet are special cases, which are not documented properly.
-6 are aliases for
-f inet, and
Did I mention that
ss -A packet will show headings, but will never show any sockets?
strace shows that it literally does not read anything. It seems to be because it treats packet sockets as always being "listening".
ss does not bother to provide a warning about this. And this is different from raw sockets, which
ss treats as being simultaneously "listening" and "non-listening".
man 7 raw says that if a raw socket is not bound to a specific protocol which are not bound to a specific IP protocol, then it is transmit-only. I have not checked if these are treated as listening sockets only)