Manpage of ss says:


Please take a look at the official documentation (Debian package iproute-doc) for details regarding filters.

What does that mean? I can't find anything under /usr/share/doc/iproute2-doc/.

$ ls /usr/share/doc/iproute2-doc/ss.html
ls: cannot access '/usr/share/doc/iproute2-doc/ss.html': No such file or directory

$ ls /usr/share/doc/iproute2-doc/
actions  changelog.Debian.gz  copyright  examples  README  README.decnet  README.devel  README.distribution.gz  README.iproute2+tc  README.lnstat

Is the document also online somewhere for browsing?


  • 2
    Do you have the corresponding package installed? – Jeff Schaller Feb 7 '19 at 0:31
  • 1
    if I haven't run sudo apt install iproute2-doc, would I have /usr/share/doc/iproute2-doc/? – Tim Feb 7 '19 at 0:46
  • I notice that whereas man ss on my Ubuntu 16.04 box refers to "Debian package iproute-doc", that on 18.04 refers only to "the official documentation" - so I suspect the relevant documentation has been moved elsewhere – steeldriver Feb 7 '19 at 1:06

The documentation is available in the Debian 9 package but was removed in later releases because it was outdated. The manpage is supposed to be the complete documentation now. (But it doesn’t have much to say about the details of filters.)

  • Thanks. Where can I learn about it? – Tim Feb 7 '19 at 11:30
  • 3
    I get the impression the only remaining “documentation” is the Bison parser code. – Stephen Kitt Feb 7 '19 at 15:02
  • Does that link use regex parser to parse command line arguments? – Tim Feb 7 '19 at 15:08
  • No, it’s a Yacc parser description, and the build uses Bison to build a real parser for it. – Stephen Kitt Feb 7 '19 at 15:11
  • I only know the getopts or getopt library to parse command line options. when to use Bison/Yacc and when to use getopts or getopt? – Tim Feb 7 '19 at 21:15
       FILTER := [ state STATE-FILTER ] [ EXPRESSION ]
              Please take a look at the official documentation for details regarding filters.

       STATE-FILTER allows to construct arbitrary set of states to match. Its syntax is sequence of keywords state and  exclude  fol‐
       lowed by identifier of state.

       Available identifiers are:

              All  standard TCP states: established, syn-sent, syn-recv, fin-wait-1, fin-wait-2, time-wait, closed, close-wait, last-
              ack, listening and closing.

              all - for all the states

              connected - all the states except for listening and closed

              synchronized - all the connected states except for syn-sent

              bucket - states, which are maintained as minisockets, i.e.  time-wait and syn-recv

              big - opposite to bucket

   ss -o state established '( dport = :ssh or sport = :ssh )'
          Display all established ssh connections.

   ss -o state fin-wait-1 '( sport = :http or sport = :https )' dst 193.233.7/24
          List all the tcp sockets in state FIN-WAIT-1 for our apache to network 193.233.7/24 and look at their timers.


ss [options] [ FILTER ]

can be expanded to

ss [options] [ state STATE-FILTER ] [ EXPRESSION ]

where options are

[-hVHnraloempiKsZNb460tudwxS] [-f FAMILY] [-A QUERY] [-D FILE] [-D FILE]

STATE-FILTER is one of

established, syn-sent, syn-recv, fin-wait-1, fin-wait-2, time-wait, closed, close-wait, last-ack, listening, closing, all, connected, synchronized, bucket, big

and we can deduce from the examples that EXPRESSION is a list of ip-rule SELECTORs.

SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK[/MASK] ] [ iif STRING ] [ oif STRING ] [ pref NUMBER ] [ l3mdev ] [ uidrange NUMBER-NUMBER ] [ ipproto PROTOCOL ] [ sport [ NUMBER | NUMBER-NUMBER ] ] [ dport [ NUMBER | NUMBER-NUMBER ] ] [ tun_id TUN_ID ]
  • 5
    This only covers the syntax for STATE-FILTER, which as noted in the first line is a subset of FILTER. This is an incomplete answer without also delving into EXPRESSION. – Andrew B Jul 30 '19 at 16:07
  • @AndrewB thanks, I have updated the answer. – user1133275 Jul 30 '19 at 19:29

I was wondering this same thing and the other answers and comments providing a link to the source was incredibly helpful.

The overall FILTER syntax is still a bit confusing, but based on an example from Linode showing how to check for ports above the secure (root required) range and the source I was able to put together a "complex" filter to check for opened ports in a specific range.

All three of these examples are functionally equivalent:

ss -a -t '( dport geq :5900 and dport leq :5999 or sport geq :5900 and sport leq :5999 )'

ss -a -t '( dport >= :5900 and dport <= :5999 or sport >= :5900 and sport <= :5999 )'

ss -a -t '( dport >= :5900 & dport <= :5999 | sport >= :5900 & sport <= :5999 )'

In this case the port(s) I'm hunting for are related to VNC, because the Vagrant and Packer tools from Hashicorp (and the virtualization tools they interact with like Virtualbox/VMware/libvirt) will automatically allocate ports in this range for virtual machines launched "headless" so that you can interact with the VM console without just sending in raw keystrokes.

The part that tripped me up for a second was that in the source code it has GEQ and LEQ but the actual filter syntax requires them to be lowercase or the symbolic representation >= or <=, while in the source code you can see the eq is defined as lowercase.

The other sneaky/confusing thing is that = and eq and == all work for equality.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.