Как проверить, что демон слушает по какому интерфейсу?

28

Пример: sshd настроен на прослушивание только на wlan0. Так. Помимо проверки sshd_config, как я могу проверить, слушает ли демон какой интерфейс? netstat может это сделать? как? (ОС: openwrt или научный linux или openbsd)

ОБНОВИТЬ:

Я думал, что sshd может быть ограничен интерфейсом ... но нет ... (192.168.1.5 на 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          
#
Гаско Питер
источник

Ответы:

37

(возможно, вам придется установить пакет ipна openwrt (v12 / регулировка ориентации)

ifconfig / netstat и т.д. считаются устаревшими , поэтому вы должны использовать (как root)

ss -nlput | grep sshd

показать сокеты TCP / UDP, на которых sshdслушает работающая программа, содержащая строку

  • -n
    нет порта для разрешения имени
  • -l
    только прослушивающие розетки
  • -p
    показать процессы прослушивания
  • -u
    показать сокеты udp
  • -t
    показать сокеты tcp

Затем вы получаете список, как этот:

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))

интересным является 5-й столбец, который показывает комбинацию IP-адреса и порта:

  1. *:22
    прослушивать порт 22 на каждом доступном IPv4-адресе
  2. :::22
    прослушивать порт 22 на каждом доступном IP-адресе (я не пишу IPv6, так как IP - это IPv6 для RFC 6540 )
  3. 127.0.0.1:6010
    прослушивание IPv4-адреса 127.0.0.1 (localhost / loopback) и порта 6010
  4. ::1:6010
    прослушивать IP-адрес :: 1 (0: 0: 0: 0: 0: 0: 0: 1 в полной нотации, а также localhost / loopback) и порт 6010

Затем вы хотите узнать, какие интерфейсы имеют адрес IPv4 (для покрытия 1.)

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

или IP-адрес (для покрытия 2.)

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

(если вы не добавите опцию для IP ( -6) или IPv4 ( -4), оба будут показаны)

Вы также можете посмотреть, что вывод и поиск, например, 127.0.0.1или любой другой IP / IPv4-адрес

# 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

Строки, начинающиеся с inetи inet6показывающие, что эти IP-адреса привязаны к этому интерфейсу, могут иметь много таких строк на интерфейс:

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

и в скрипте:

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

(заменить "127.0.0.1")

Oluf Lorenzen
источник
Вы имеете в виду, что нет точного способа определить, что демон слушает на каком интерфейсе, потому что это может быть определено только по IP-адресу?
Гаско Питер
да, правильно. Вы (или я) могли бы расширить сценарий, который я опубликовал, что он сделает шаги раньше ...
Олуф Лоренцен
1
Что насчет SO_BINDTODEVICE?
Павел Шимерда
20

Используя lsof(как 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может сделать это, тоже (как корень):

# 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))

... и, наконец, netstat(как 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  
Sr-
источник
3
В частности, *:sshили 0.0.0.0:22означает, что он прослушивает подстановочный интерфейс (т. Е. Все они). Что-то вроде host-eth1:sshили 10.0.0.4:22означает, что он слушает на этом конкретном интерфейсе
Бесполезно
подожди минутку .. Я подумал, что это хороший ответ: D, но нет, в нем нет интерфейса .. Как я узнал, что программа прослушивает только данный интерфейс? или нет никакого решения для этого вопроса? : O
Гаско Петр
@gaskopeter Вы можете увидеть интерфейс с IP-адреса, который отображается ( 192.168.1.5или a.lanв вашем вопросе). Если *в этом месте есть, то он прослушивает все интерфейсы ( *:sshв ответе sr_).
Филипп Вендлер
@Useless: это верно только для систем BSD.
BatchyX
@BatchyX Как так? Я вижу, что говорит Бесполезный, по крайней мере, в Arch Linux и Debian.
x-yuri
9

Насколько я знаю, вы не можете (за исключением систем BSD, где решение Finkregh работает отлично). Это может быть возможно, но вам все равно, потому что большинство приложений прослушивают каждый интерфейс, даже если он привязан к IP-адресу.

В linux (и openwrt) единственный способ для приложения прослушивать только определенный интерфейс - это SO_BINDTODEVICEопция сокета. Мало кто из приложений на самом деле поддерживает это, так как это зависит от конкретной ОС. Это, или они используют сокет пакета, но это для протоколов низкого уровня (таких как серверы DHCP).

В linux, который использует модель слабого хоста, каждое приложение по умолчанию прослушивает все интерфейсы, даже когда привязывает сокет к IP-адресу. Единственное исключение - привязка к 127.0.0.1, которая гарантирует, что приложение прослушивает только loинтерфейс.

Вы правильно поняли : если у вас есть два интерфейса (скажем, eth0и eth1) с двумя разными IP-адресами (например, 192.0.2.1 для eth0и 198.51.100.1 для eth1), и вы указываете приложению связываться с 192.0.2.1, приложение все равно будет прослушивать оба интерфейса, но будут отвечать, только если IP-адрес назначения равен 192.0.2.1. Таким образом, кто-то в eth1интерфейсе, если его таблица маршрутизации определена надлежащим образом, может получить доступ к вашему приложению, обратившись к нему через адрес 192.0.2.1 (но не через 198.51.100.1) в eth1интерфейсе.

Предполагать, что привязка к IP-адресу такая же, как привязка к сетевому интерфейсу, совершенно неверна в Linux. Если это вас беспокоит, используйте политику маршрутизации и / или iptables.

BatchyX
источник
-1

Также с netstat, но конкретные аргументы:

netstat -lp -i wlan0
frogstarr78
источник
1
Можете ли вы объяснить немного дольше вывод этой команды? : D
Гаско Петр
Честно говоря, я не знаю. Я должен был бы man netstat. Разница, которую я предлагаю, заключается в изменении «запроса», который вы выполняете, чтобы явно указать интерфейс, который вы хотите проверить.
frogstarr78
"netstat -lp -i wlan0" и "netstat -i" дают одинаковый ответ на мою систему Ubuntu
Брюс Барнетт
1
netstat -iперечислит интерфейсы, а не прослушивающие порты, -1 для ответа, который не отражает реальность
Mikko Rantalainen