Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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)

UPDATE:

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

# grep ^ListenAddress /etc/ssh/sshd_config 
ListenAddress 192.168.1.5:22
# 
# lsof -i -n -P
COMMAND     PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
sshd      23952 root    3u  IPv4 1718551      0t0  TCP 192.168.1.5:22 (LISTEN)
#
# ss -lp | grep -i ssh
0      128              192.168.1.5:ssh                           *:*        users:(("sshd",23952,3))
# 
# netstat -lp | grep -i ssh
tcp        0      0 a.lan:ssh                   *:*                         LISTEN      23952/sshd          
#
share|improve this question

4 Answers 4

up vote 9 down vote accepted
+50

(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 sotckets

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            127.0.0.1:6010                  *:*      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)
  3. 127.0.0.1:6010
    listen on IPv4 address 127.0.0.1 (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. 127.0.0.1 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 127.0.0.1/8 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 192.0.2.1 peer 192.0.2.3
    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:

address="127.0.0.1"
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}"
        fi
done

(replace "127.0.0.1")

share|improve this answer
    
you mean that there is no exact way to determine that a daemon is listening on what interface, because it could be only determined by IP address? –  gasko peter Jan 17 '13 at 8:43
    
yep, correct. you (or i) could extend the script i posted that it would do the steps before... –  Oluf Lorenzen Jan 17 '13 at 10:57

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 127.0.0.1, 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 192.0.2.1 for eth0 and 198.51.100.1 for eth1) and you tell an application to bind on 192.0.2.1, the application will still listen on both interfaces, but will only respond if the destination IP is 192.0.2.1. So someone on the eth1 interface, if its routing table is appropriately defined, can access your application by accessing it via the 192.0.2.1 address (but not via 198.51.100.1) 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.

share|improve this answer

Also with netstat but the specific arguments are:

netstat -lp -i wlan0
share|improve this answer
    
can you please explain the output of this command a little bit longer? :D –  gasko peter Jan 17 '13 at 8:40
    
Honestly, I don't know. I'd have to man netstat. The difference I'm suggesting is in changing the "query" that you're running to explicitly specify the interface you are interested in checking. –  frogstarr78 Jan 19 '13 at 17:31

Using lsof (as root):

# lsof -i -n -P
COMMAND    PID        USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
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  
share|improve this answer
2  
Specifically, *:ssh or 0.0.0.0:22 means it's listening on the wildcard interface (ie, all of them). Something like host-eth1:ssh or 10.0.0.4:22 mean it's listening on that specific interface –  Useless Nov 6 '12 at 11:42
    
wait a minute.. I thought this is the good answer :D but no, there is no interface in it.. How do I found out that a program is only listening on given interface? or there isn't any solution for this question? :O –  gasko peter Nov 19 '12 at 10:54
    
@gaskopeter You can see the interface from the ip address which is shown (192.168.1.5 or a.lan in your question). If there is a * in this place, then it listens on all interfaces (*:ssh in sr_'s answer). –  Philipp Wendler Jan 16 '13 at 14:18
    
@Useless: This is only true on BSD systems. –  BatchyX Jan 21 '13 at 8:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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