Two years ago, I described a simple way to display established TCP connections using ss
command. Today I will use lsof
and gawk
to pretty print network connections.
Notice, I am using gawk
to take advantage of the gensub
function.
Display listening TCP ports
Use the following command to display listening TCP ports.
$ sudo lsof -iTCP -sTCP:LISTEN -P -n | \ sed 1d | \ gawk '{ if (substr($9,1,1) != "[") { split($9,local,":"); } else { local[1]=gensub(/\[(.*)\]:.*/,"\\1","g",$9); local[2]=gensub(/\[.*\]:(.*)/,"\\1","g",$9); }; cmd="cat /proc/" $2 "/cmdline | tr '\''\\000'\'' '\'' '\''"; cmd | getline output; close(cmd); printf "Process %5s is listening on %s %s port %s -- %s \n",$2,$5,local[1],local[2],output }' | \ sort
Sample output.
Process 13278 is listening on IPv4 127.0.0.1 port 631 -- /usr/sbin/cupsd -l Process 13278 is listening on IPv6 ::1 port 631 -- /usr/sbin/cupsd -l Process 1138 is listening on IPv4 * port 22 -- /usr/sbin/sshd -D Process 1138 is listening on IPv6 * port 22 -- /usr/sbin/sshd -D Process 1810 is listening on IPv4 127.0.1.1 port 53 -- /usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/var/run/NetworkManager/dnsmasq.pid --listen-address=127.0.1.1 --cache-size=0 --conf-file=/dev/null --proxy-dnssec --enable-dbus=org.freedesktop.NetworkManager.dnsmasq --conf-dir=/etc/NetworkManager/dnsmasq.d Process 8418 is listening on IPv4 127.0.0.1 port 4000 -- /usr/bin/ruby /usr/bin/jekyll serve --future -w
Display UDP connections
Use the following command to display UDP connections. I have extended it a bit due to the stateless nature of the UDP protocol.
$ sudo lsof -iUDP -P -n | \ sed 1d | \ gawk '{ split($9,address,"->"); if (substr(address[1],1,1) != "[") { split(address[1],local,":"); } else { local[1]=gensub(/\[(.*)\]:.*/,"\\1","g",address[1]); local[2]=gensub(/\[.*\]:(.*)/,"\\1","g",address[1]); }; if (substr(address[2],1,1) != "[") { split(address[2],remote,":"); } else { remote[1]=gensub(/\[(.*)\]:.*/,"\\1","g",address[2]); remote[2]=gensub(/\[.*\]:(.*)/,"\\1","g",address[2]); }; local_address="local address " $5 " " local[1] " port " local[2]; if (length(remote[1])>0) { remote_address="remote address " remote[1] " port " remote[2]; } else { remote_address=""; } cmd="cat /proc/" $2 "/cmdline | tr '\''\\000'\'' '\'' '\''"; cmd | getline output; close(cmd); printf "Process %5s %s %s -- %s \n",$2,local_address,remote_address, output; }' | \ sort
Sample output.
Process 17135 local address IPv4 * port 631 -- /usr/sbin/cups-browsed Process 25997 local address IPv4 * port 68 -- /sbin/dhclient -d -q -sf /usr/lib/NetworkManager/nm-dhcp-helper -pf /var/run/dhclient-wlp2s0.pid -lf /var/lib/NetworkManager/dhclient-c6755d45-8401-405e-ac0f-029516cbd09f-wlp2s0.lease -cf /var/lib/NetworkManager/dhclient-wlp2s0.conf wlp2s0 Process 1810 local address IPv4 127.0.1.1 port 53 -- /usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/var/run/NetworkManager/dnsmasq.pid --listen-address=127.0.1.1 --cache-size=0 --conf-file=/dev/null --proxy-dnssec --enable-dbus=org.freedesktop.NetworkManager.dnsmasq --conf-dir=/etc/NetworkManager/dnsmasq.d Process 1810 local address IPv4 * port 55324 -- /usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/var/run/NetworkManager/dnsmasq.pid --listen-address=127.0.1.1 --cache-size=0 --conf-file=/dev/null --proxy-dnssec --enable-dbus=org.freedesktop.NetworkManager.dnsmasq --conf-dir=/etc/NetworkManager/dnsmasq.d Process 2161 local address IPv4 * port 5353 -- /opt/google/chrome/chrome Process 2161 local address IPv6 * port 5353 -- /opt/google/chrome/chrome Process 908 local address IPv4 * port 40303 -- avahi-daemon: running [notebook.local] Process 908 local address IPv4 * port 5353 -- avahi-daemon: running [notebook.local] Process 908 local address IPv6 * port 5353 -- avahi-daemon: running [notebook.local] Process 908 local address IPv6 * port 54270 -- avahi-daemon: running [notebook.local]
Display established TCP connections
Use the following command to display established TCP connections.
$ sudo lsof -iTCP -sTCP:ESTABLISHED -P -n | \ sed 1d | \ gawk '{ split($9,address,"->"); if (substr(address[1],1,1) != "[") { split(address[1],local,":"); } else { local[1]=gensub(/\[(.*)\]:.*/,"\\1","g",address[1]); local[2]=gensub(/\[.*\]:(.*)/,"\\1","g",address[1]); }; if (substr(address[2],1,1) != "[") { split(address[2],remote,":"); } else { remote[1]=gensub(/\[(.*)\]:.*/,"\\1","g",address[2]); remote[2]=gensub(/\[.*\]:(.*)/,"\\1","g",address[2]); }; local_address="local address " $5 " " local[1] " port " local[2]; if (length(remote[1])>0) { remote_address="remote address " remote[1] " port " remote[2]; } else { remote_address=""; } cmd="cat /proc/" $2 "/cmdline | tr '\''\\000'\'' '\'' '\''"; cmd | getline output; close(cmd); printf "Process %5s %s %s -- %s \n",$2,local_address,remote_address, output; }' | \ sort
Sample output.
Process 30572 local address IPv4 192.168.1.177 port 33286 remote address 93.184.216.34 port 443 -- nextcloud Process 2161 local address IPv4 192.168.1.177 port 33428 remote address 93.184.216.34 port 443 -- /opt/google/chrome/chrome Process 2161 local address IPv4 192.168.1.177 port 43736 remote address 93.184.216.34 port 5228 -- /opt/google/chrome/chrome
Display all network connections
Use the following command to display every connection with additional information.
$ sudo lsof -i -P -n | \ sed 1d | \ gawk '{ split($9,address,"->"); if (substr(address[1],1,1) != "[") { split(address[1],local,":");} else { local[1]=gensub(/\[(.*)\]:.*/,"\\1","g",address[1]); local[2]=gensub(/\[.*\]:(.*)/,"\\1","g",address[1]); }; if (substr(address[2],1,1) != "[") { split(address[2],remote,":");} else { remote[1]=gensub(/\[(.*)\]:.*/,"\\1","g",address[2]); remote[2]=gensub(/\[.*\]:(.*)/,"\\1","g",address[2]); }; local_address="local address " local[1] " port " local[2]; if(length(remote[1])>0) { remote_address="remote address " remote[1] " port " remote[2]; } else { remote_address=""; }; gsub(/[()]/,"",$10); cmd="cat /proc/" $2 "/cmdline | tr '\''\\000'\'' '\'' '\''"; cmd | getline output; close(cmd); printf "Process %5s %s %s %s %s %s -- %s \n",$2,$5,$8,local_address,remote_address,$10,output; }' | \ sort
Sample output.
Process 17135 IPv4 UDP local address * port 631 -- /usr/sbin/cups-browsed Process 25997 IPv4 UDP local address * port 68 -- /sbin/dhclient -d -q -sf /usr/lib/NetworkManager/nm-dhcp-helper -pf /var/run/dhclient-wlp2s0.pid -lf /var/lib/NetworkManager/dhclient-c6755d45-8401-405e-ac0f-029516cbd09f-wlp2s0.lease -cf /var/lib/NetworkManager/dhclient-wlp2s0.conf wlp2s0 Process 30572 IPv4 TCP local address 192.168.1.177 port 33286 remote address 93.184.216.34 port 443 ESTABLISHED -- nextcloud Process 1138 IPv4 TCP local address * port 22 LISTEN -- /usr/sbin/sshd -D Process 1138 IPv6 TCP local address * port 22 LISTEN -- /usr/sbin/sshd -D Process 1810 IPv4 TCP local address 127.0.1.1 port 53 LISTEN -- /usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/var/run/NetworkManager/dnsmasq.pid --listen-address=127.0.1.1 --cache-size=0 --conf-file=/dev/null --proxy-dnssec --enable-dbus=org.freedesktop.NetworkManager.dnsmasq --conf-dir=/etc/NetworkManager/dnsmasq.d Process 1810 IPv4 UDP local address 127.0.1.1 port 53 -- /usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/var/run/NetworkManager/dnsmasq.pid --listen-address=127.0.1.1 --cache-size=0 --conf-file=/dev/null --proxy-dnssec --enable-dbus=org.freedesktop.NetworkManager.dnsmasq --conf-dir=/etc/NetworkManager/dnsmasq.d Process 1810 IPv4 UDP local address * port 55324 -- /usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/var/run/NetworkManager/dnsmasq.pid --listen-address=127.0.1.1 --cache-size=0 --conf-file=/dev/null --proxy-dnssec --enable-dbus=org.freedesktop.NetworkManager.dnsmasq --conf-dir=/etc/NetworkManager/dnsmasq.d Process 2161 IPv4 TCP local address 127.0.0.1 port 34708 remote address 127.0.0.1 port 4000 CLOSE_WAIT -- /opt/google/chrome/chrome Process 2161 IPv4 TCP local address 192.168.1.177 port 33428 remote address 93.184.216.34 port 443 ESTABLISHED -- /opt/google/chrome/chrome Process 2161 IPv4 TCP local address 192.168.1.177 port 43736 remote address 93.184.216.34 port 5228 ESTABLISHED -- /opt/google/chrome/chrome Process 2161 IPv4 UDP local address * port 5353 -- /opt/google/chrome/chrome Process 2161 IPv6 UDP local address * port 5353 -- /opt/google/chrome/chrome Process 2962 IPv4 TCP local address 192.168.1.177 port 33600 remote address 93.184.216.34 port 443 ESTABLISHED -- /usr/bin/QOwnNotes Process 8418 IPv4 TCP local address 127.0.0.1 port 4000 LISTEN -- /usr/bin/ruby /usr/bin/jekyll serve --future -w Process 908 IPv4 UDP local address * port 40303 -- avahi-daemon: running [notebook.local] Process 908 IPv4 UDP local address * port 5353 -- avahi-daemon: running [notebook.local] Process 908 IPv6 UDP local address * port 5353 -- avahi-daemon: running [notebook.local] Process 908 IPv6 UDP local address * port 54270 -- avahi-daemon: running [notebook.local]