How to check that a daemon is listening on what interface?

Ex.: an sshd is configured to only listen on wlan0. So. Besides checking the sshd_config how can I check that a daemon is listening on what inerface? netstat can do it? how? (OS: openwrt or scientific linux or openbsd)


I thought sshd could be limited to an interface… but no… ( is on wlan0…)

# grep ^ListenAddress /etc/ssh/sshd_config 
# lsof -i -n -P
sshd      23952 root    3u  IPv4 1718551      0t0  TCP (LISTEN)
# ss -lp | grep -i ssh
0      128                               *:*        users:(("sshd",23952,3))
# netstat -lp | grep -i ssh
tcp        0      0 a.lan:ssh                   *:*                         LISTEN      23952/sshd          
Asked By: gasko peter


Using lsof (as root):

# lsof -i -n -P
sshd      3028        root    3u  IPv4   7072      0t0  TCP *:22 (LISTEN)
sshd      3028        root    4u  IPv6   7074      0t0  TCP *:22 (LISTEN)

iproute2‘s ss can do this, too (as root):

# ss -lp
State      Recv-Q Send-Q      Local Address:Port          Peer Address:Port   
LISTEN     0      128                    :::ssh                     :::*        users:(("sshd",3028,4))
LISTEN     0      128                     *:ssh                      *:*        users:(("sshd",3028,3))

…and finally, netstat (as root):

# netstat -lp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 *:ssh                   *:*                     LISTEN      3028/sshd  
Answered By: sr_

Also with netstat but the specific arguments are:

netstat -lp -i wlan0
Answered By: frogstarr78

(you might have to install the package ip on openwrt (v12 / attitude adjustment)

ifconfig/netstat etc. are considered deprecated, so you should use (as root)

ss -nlput | grep sshd

to show the TCP/UDP sockets on which a running program which contains the string sshd is listening to

  • -n
    no port to name resolution
  • -l
    only listening sockets
  • -p
    show processes listening
  • -u
    show udp sockets
  • -t
    show tcp sockets

Then you geht a list like this one:

tcp    LISTEN     0      128                    *:22                    *:*      users:(("sshd",3907,4))
tcp    LISTEN     0      128                   :::22                   :::*      users:(("sshd",3907,3))
tcp    LISTEN     0      128                    *:*      users:(("sshd",4818,9))
tcp    LISTEN     0      128                  ::1:6010                 :::*      users:(("sshd",4818,8))

the interesting thing is the 5th column which shows a combination of IP address and port:

  1. *:22
    listen on port 22 on every available IPv4 address
  2. :::22
    listen on port 22 on every available IP address (i do not write IPv6, as IP is IPv6 per RFC 6540)
    listen on IPv4 address (localhost/loopback) and port 6010
  4. ::1:6010
    listen on IP address ::1 (0:0:0:0:0:0:0:1 in full notation, also localhost/loopback) and port 6010

You then want to know which interfaces has an IPv4 address (to cover 1.)

ip -4 a
# or "ip -4 address"
# or "ip -4 address show"

or an IP address (to cover 2.)

ip -6 a
# or "ip -6 address
# or "ip -6 address show

(if you do not add the option for IP (-6) or IPv4 (-4) both are shown)

You can also have an look that output and search for e.g. or any other IP/IPv4-address

# here a demo where i show all addresses of the device "lo" (loopback)
ip a show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever

The lines beginning with inet and inet6 show that these IPs are bound to this interface, you may have many of these lines per interface:

he-ipv6: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN
    link/sit peer
    inet6 2001:db8:12::1/64 scope global
       valid_lft forever preferred_lft forever
    inet6 2001:db8::2/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::1111:1111/128 scope link
       valid_lft forever preferred_lft forever

and in a script:

for i in $(grep ':' /proc/net/dev | cut -d ':' -f 1 | tr -d ' ') ; do
        if $(ip address show dev $i | grep -q "${address}") ; then
                echo "${address} found on interface ${i}"

(replace "")

Answered By: Oluf Lorenzen

As far as i know, you can’t (except on BSD systems, where Finkregh’s solution works fine). It might be possible but you don’t care, because most application listen on every interface, even when bound to an IP address.

On linux (and openwrt), the only way for an application to listen only on a certain interface is the SO_BINDTODEVICE socket option. Few applications actually supports this, as it is OS specific. That, or they use packet socket, but that’s for low level protocols (like dhcp servers).

On linux, which uses a weak host model, every application listens on every interfaces by default, even when binding a socket to an IP address. The only exception is when binding to, which ensures that the application only listens on the lo interface.

You heard it right: If you have two interfaces (say eth0 and eth1) with two different IP addresses, (say for eth0 and for eth1) and you tell an application to bind on, the application will still listen on both interfaces, but will only respond if the destination IP is So someone on the eth1 interface, if its routing table is appropriately defined, can access your application by accessing it via the address (but not via on the eth1 interface.

Assuming that binding to an IP address is the same as binding to a network interface is utterly false on Linux. If that bothers you, use policy routing and/or iptables.

Answered By: BatchyX
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.