Monitoring active SSH connections shows who is still attached to a server and whether those sessions match the maintenance, automation, or support work you expect. That makes it easier to spot forgotten shells, unexpected logins, and background access that stayed open longer than intended.

On a current Linux server, who reads the login records for interactive terminals, w adds session activity and idle time, and ss reads the live TCP sockets that sshd is using. Running all three commands together shows which connections have a normal terminal and which ones are only visible at the socket layer.

These checks are read-only, but process details from ss normally require sudo, and the reported source address may be a jump host, VPN gateway, or NAT address instead of the operator workstation itself. The examples assume the server listens on the default SSH service name :ssh, so replace that filter with the real port such as :2222 when the daemon listens elsewhere.

Steps to monitor active SSH connections:

  1. Open a terminal on the Linux server with an account that can use sudo.
    $ whoami
    user
  2. List the current login records to find interactive SSH terminals and their client addresses.
    $ who
    user     pts/0        Apr 14 12:53 (198.51.100.24)

    who shows terminal-backed logins such as pts/0, while local console or desktop sessions usually appear as entries such as tty2 or seat0.

  3. Check the active-user view to see where connected users came from and what each session is doing now.
    $ w
     12:53:50 up 4 min,  1 user,  load average: 2.22, 1.49, 0.68
    USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU  WHAT
    user              198.51.100.24    12:50    4:48   0.00s  0.01s sshd: user [priv]

    The FROM, IDLE, and WHAT columns help distinguish an active shell from an idle session or a connection that has not yet attached to a normal terminal workload.

  4. Show the live TCP connections currently established to the SSH service.
    $ sudo ss -tn state established '( sport = :ssh )'
    Recv-Q Send-Q Local Address:Port Peer Address:Port
    0      0       203.0.113.50:22    198.51.100.24:59719
    0      0       203.0.113.50:22    198.51.100.24:59530

    The filter can use the service name :ssh, but the -n flag keeps the displayed ports numeric in the output; use :2222 when the daemon listens on TCP port 2222.

  5. Include process information to map each live socket back to the sshd worker that owns it.
    $ sudo ss -tnp state established '( sport = :ssh )'
    Recv-Q Send-Q Local Address:Port Peer Address:Port Process
    0      0       203.0.113.50:22    198.51.100.24:59719 users:(("sshd",pid=7010,fd=4))
    0      0       203.0.113.50:22    198.51.100.24:59530 users:(("sshd",pid=5608,fd=4),("sshd",pid=5526,fd=4))

    Process details are usually hidden from unprivileged accounts, which is why this view is normally run with sudo.

  6. Compare the terminal views from who and w with the socket list from ss before deciding whether a connection is unexpected.

    A second socket in ss without a matching new pts* entry in who or w usually indicates a no-PTY connection such as a port forward or another background SSH client rather than a second interactive shell.