[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ss(1) :-) (or ss(8), depending upon one's distro)

So, 2018-02-11 Berkeley Linux User Group (BerkeleyLUG) meeting, some
discussion of ss(1) came up.

I realized a bit later I had handy example I'd recently used from work,
stripping out some bits and modestly reformatting ...:

From: Paoli, Michael
Sent: Thursday, February 08, 2018 2:43 PM
Subject: ss(8) outbound/egress

# ss -np -A inet 'dst 2000::/3 or ( dst and not ( dst or dst or dst or dst or dst or dst ) )'

(probably) need to run as root to get most/all the process (-p)
information - if not run as root most of that data will probably be
missing in the reported results (but IPs and ports and such would
still be reported)  The process data gives us the user (or user ID),
PID, and fd number.

It's pretty dang efficient (notably the filtering happens at kernel
layer), so it ought be fast/efficient enough.

Anyway, that ss(1) command with those options/arguments will get
information on any process driven traffic/connections (regardless of
state - e.g. including FIN_WAIT and the like),
where client is local, and where server IP used or attempted is on The
Internet (there might be a trace of false positives - I excluded
common IPs that aren't Internet addressable, but I didn't exclude some
more obscure and less probable ones).  It also covers any type of
Internet traffic - not only TCP, and also UDP, but also "anything"
(includes also "raw").  And it includes both IPv4 and IPv6.

So, that particular exercise, was to look at hosts and identify any
process activity where the remote end of the traffic was an Internet IP
address.  With ss(1) (or ss(8) on some distros), that's pretty darn
quick, efficient, and relatively easy.  With netstat, that wouldn't be
nearly as fast and efficient.  Looking a bit more at our ss(1) command:
ss -np -A inet '
  dst 2000::/3 or
    dst and not
      dst or
      dst or
      dst or
      dst or
      dst or
We couldn't quite literally write it like that (ss(1) wouldn't accept
the newlines in the filter expression), but for purposes of
illustration/readability ...
So we've got the -n option --numeric - don't resolve to service names.
The -p option - give us process information - that really only works for
process owner - or superuser (UID 0 - "root").
And -A inet - address family of Internet - essentially IP (e.g. we're
not looking at files of type socket).
Then we have the filter expression.  In this case we wanted to do a spot
check looking at stuff where remote was Internet addressable addresses
(at least to a very close approximation - we didn't excluded some more
obscure IPv4 addresses that wouldn't apply, but we excluded the more
common IPv4 addresses that wouldn't be Internet routable.  Also note
that that's *much* more clean and simple for IPv6.  So, our expression,
first of all, here dst isn't necessarily which way the data goes, but
dst is remote, src would be local to the host.  So we have:
  dst 2000::/3 or
That's any IPv6 Internet routable IP address or ...
    dst and not
Any IPv4 address and not ...
We then exclude from any IPv4 addresses, addresses which are RFC-1918
Intranet (private non-routable), localnet, APIPA, and the all 1's
broadcast address which is also not routable:
      dst or
      dst or
      dst or
      dst or
      dst or
Now, imagine trying to do that with netstat instead, in the "bad old
days" before ss(1).  You'd need to run a much more general netstat
command - it has no built-in filtering capabilities like ss(1).  The
ss(1) command also does the filtering quite efficiently, as the
filtering is done in-kernel.  With netstat, one would have to
post-filter the output, with tools such as sed, awk, grep, perl, python,
etc.  So, think of all the IP addresses, in the human readable form
output in netstat.  And if you think our filter expression for ss(1) is
a wee bit complex, imagine instead, writing regular expression(s) for
grep, or awk, or sed, or perl, or phython, to do the same set of
filtering based on the human readable form of the IP addresses, that
would be much more complex.  Keep in mind, too, the IPv4 may show as
native IPv4, or as mapped in IPv6 space, and also when so matched, the
IPv4 portion may show in hex, or in dotted quad.  Yeah, those would be
some rather ugly regular expressions to do all that.  They'd be much
less efficient, much less efficient on the human time, and also much
less probable to be precisely correct and get only and exactly the
desired traffic.

Anyway, that's just one example of how highly practical ss(1) is, and
how it's really quite highly superior to netstat.

Here's another example I did when setting up SMTP and such on BALUG.org
VM host, in this case, wanted to check if ports 25 and/or 587, TCP, were
being listened to, and if so, on what IP addresses:
$ ss -nlt '( sport = :25 or sport = :587 )'
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN     0      20                             *:*
LISTEN     0      20                      ::1:25                      :::*
The -l option is for listen, the t option for TCP, and sport for our
local ports.

You received this message because you are subscribed to the Google Groups "BerkeleyLUG" group.
To unsubscribe from this group and stop receiving emails from it, send an email to berkeleylug+unsubscribe@googlegroups.com.
To post to this group, send email to berkeleylug@googlegroups.com.
Visit this group at https://groups.google.com/group/berkeleylug.
For more options, visit https://groups.google.com/d/optout.