How to check active network connections in Linux

When a Linux host exposes an unexpected service, slows during a network burst, or enters incident review, active sockets show which processes are listening and which endpoints already have open sessions. Checking the kernel socket table keeps the investigation tied to current runtime state instead of only service names, firewall rules, or stale notes.

The ss utility from iproute2 reads socket state for TCP, UDP, and other protocol families. It can show listeners, established sessions, queue depth, process IDs, and filters such as local source port without sending traffic or probing the service from outside the host.

Process details usually require root privileges, and the output can reveal IP addresses, usernames, command paths, and service names. Numeric output avoids slow name lookups, network namespaces limit what each shell can see, and short-lived connections may disappear between repeated runs.

Steps to check active network connections with ss in Linux:

  1. List listening TCP and UDP sockets with owning processes.
    $ sudo ss --tcp --udp --listening --processes --numeric
    Netid State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
    tcp   LISTEN 0      5          127.0.0.1:9000      0.0.0.0:*    users:(("python3",pid=3066,fd=3))

    Sockets in LISTEN state accept inbound connections. A local address of 127.0.0.1 is loopback-only, while 0.0.0.0 or [::] means the service listens on all IPv4 or IPv6 interfaces in that network namespace.

  2. Summarize socket counts by protocol and state.
    $ ss --summary
    Total: 7
    TCP:   52 (estab 2, closed 49, orphaned 0, timewait 3)
    
    Transport Total     IP        IPv6
    RAW	  0         0         0
    UDP	  0         0         0
    TCP	  3         3         0
    INET	  3         3         0
    FRAG	  0         0         0

    The estab count shows established TCP sessions. Large or rising timewait and syn-recv counts can point to connection churn or incomplete handshakes.

  3. List established TCP connections with owning processes.
    $ sudo ss --tcp --processes --numeric state established
    Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
    0      0          127.0.0.1:36932    127.0.0.1:9000  users:(("python3",pid=3066,fd=5))
    0      0          127.0.0.1:9000     127.0.0.1:36932 users:(("python3",pid=3066,fd=4))

    Local Address:Port identifies the local endpoint, and Peer Address:Port identifies the other end of the session. Remote sessions show the remote IP address and port in the peer column.

  4. Filter the socket table to one local port.
    $ sudo ss --tcp --listening --processes --numeric 'sport = :9000'
    State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
    LISTEN 0      5          127.0.0.1:9000      0.0.0.0:*    users:(("python3",pid=3066,fd=3))

    Use sport = :PORT for the local port and dport = :PORT for the peer destination port. The expression is handled by ss, so a separate text filter is not needed.

  5. Inspect the process that owns an unexpected socket.
    $ ps -fp 3066
    UID          PID    PPID  C STIME TTY          TIME CMD
    app         3066       1  0 20:20 ?        00:00:00 python3 -m http.server 9000 --bind 127.0.0.1 --directory /srv/app/public

    Confirm the command line and service owner before stopping or killing a process. Terminating the wrong PID can drop active sessions or stop a critical service.

  6. Resolve the executable path for the reported PID.
    $ sudo readlink -f /proc/3066/exe
    /usr/bin/python3.14

    If the target ends in (deleted), the executable was removed or replaced after the process started. Reading /proc/PID/exe can also be restricted by kernel permission checks.