Làm thế nào để kiểm tra xem một daemon đang nghe trên giao diện nào?


28

Ví dụ: một sshd được cấu hình để chỉ nghe trên wlan0. Vì thế. Bên cạnh việc kiểm tra sshd_config, làm thế nào tôi có thể kiểm tra xem một daemon đang lắng nghe những gì inerface? netstat có làm được không? làm sao? (HĐH: openwrt hoặc khoa học linux hoặc openbsd)

CẬP NHẬT:

Tôi nghĩ rằng sshd có thể bị giới hạn trong một giao diện ... nhưng không ... (192.168.1.5 có trên 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          
#

Câu trả lời:


37

(bạn có thể phải cài đặt gói iptrên openwrt (v12 / điều chỉnh thái độ)

ifconfig / netstat, vv được coi là không dùng nữa , vì vậy bạn nên sử dụng (với quyền root)

ss -nlput | grep sshd

để hiển thị các ổ cắm TCP / UDP mà chương trình đang chạy chứa chuỗi sshdđang nghe

  • -n
    không có cổng để giải quyết tên
  • -l
    chỉ nghe ổ cắm
  • -p
    hiển thị quá trình lắng nghe
  • -u
    hiển thị ổ cắm udp
  • -t
    hiển thị ổ cắm tcp

Sau đó, bạn đưa ra một danh sách như thế này:

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

Điều thú vị là cột thứ 5 hiển thị kết hợp địa chỉ IP và cổng:

  1. *:22
    nghe trên cổng 22 trên mỗi địa chỉ IPv4 có sẵn
  2. :::22
    lắng nghe cổng 22 trên mọi địa chỉ IP khả dụng (tôi không viết IPv6, vì IP là IPv6 trên RFC 6540 )
  3. 127.0.0.1:6010
    nghe trên địa chỉ IPv4 127.0.0.1 (localhost / loopback) và cổng 6010
  4. ::1:6010
    lắng nghe địa chỉ IP :: 1 (0: 0: 0: 0: 0: 0: 0: 1 trong ký hiệu đầy đủ, cũng như localhost / loopback) và cổng 6010

Sau đó, bạn muốn biết giao diện nào có địa chỉ IPv4 (để bao gồm 1.)

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

hoặc một địa chỉ IP (để bao gồm 2.)

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

(nếu bạn không thêm tùy chọn cho cả IP ( -6) hoặc IPv4 ( -4) đều được hiển thị)

Bạn cũng có thể có một cái nhìn đầu ra và tìm kiếm ví dụ 127.0.0.1hoặc bất kỳ địa chỉ IP / IPv4 nào khác

# 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

Các dòng bắt đầu bằng inetinet6hiển thị rằng các IP này được liên kết với giao diện này, bạn có thể có nhiều dòng trên mỗi giao diện:

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

và trong một kịch bản:

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

(thay thế "127.0.0.1")


bạn có nghĩa là không có cách chính xác để xác định rằng một daemon đang lắng nghe trên giao diện nào, bởi vì nó chỉ có thể được xác định bởi địa chỉ IP?
pasko peter

vâng, đúng. bạn (hoặc tôi) có thể mở rộng kịch bản mà tôi đã đăng rằng nó sẽ thực hiện các bước trước khi ...
Oluf Lorenzen

1
Còn SO_BINDTODEVICE thì sao?
Pavel imerda

20

Sử dụng lsof(với quyền 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)

iproute2Cũng sscó thể làm điều này (như 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))

... và cuối cùng, netstat(là 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  

3
Cụ thể, *:sshhoặc 0.0.0.0:22có nghĩa là nó đang nghe trên giao diện ký tự đại diện (nghĩa là tất cả chúng). Một cái gì đó giống host-eth1:sshhoặc 10.0.0.4:22có nghĩa là nó đang nghe trên giao diện cụ thể đó
Vô dụng

Đợi một chút .. Tôi nghĩ đây là câu trả lời hay: D nhưng không, không có giao diện nào trong đó .. Làm thế nào để tôi phát hiện ra rằng một chương trình chỉ nghe trên giao diện đã cho? hoặc không có giải pháp nào cho câu hỏi này? : O
gasko peter

@gaskopeter Bạn có thể thấy giao diện từ địa chỉ IP được hiển thị ( 192.168.1.5hoặc a.lantrong câu hỏi của bạn). Nếu có một *ở nơi này, thì nó lắng nghe trên tất cả các giao diện ( *:sshtrong câu trả lời của sr_).
Philipp Wendler

@Usless: Điều này chỉ đúng trên các hệ thống BSD.
BatchyX

@BatchyX Làm sao vậy? Tôi có thể thấy những gì Vô dụng nói trên ít nhất là Arch Linux và Debian.
x-yuri

9

Theo tôi biết, bạn không thể (ngoại trừ trên các hệ thống BSD, nơi giải pháp của Finkregh hoạt động tốt). Có thể là có thể nhưng bạn không quan tâm, vì hầu hết các ứng dụng đều nghe trên mọi giao diện, ngay cả khi bị ràng buộc với một địa chỉ IP.

Trên linux (và openwrt), cách duy nhất để một ứng dụng chỉ nghe trên một giao diện nhất định là SO_BINDTODEVICEtùy chọn ổ cắm. Rất ít ứng dụng thực sự hỗ trợ điều này, vì nó là hệ điều hành cụ thể. Điều đó, hoặc họ sử dụng ổ cắm gói, nhưng đó là cho các giao thức cấp thấp (như máy chủ dhcp).

Trên linux, sử dụng mô hình máy chủ yếu, mọi ứng dụng đều nghe trên mọi giao diện theo mặc định, ngay cả khi liên kết ổ cắm với địa chỉ IP. Ngoại lệ duy nhất là khi liên kết với 127.0.0.1, điều này đảm bảo rằng ứng dụng chỉ lắng nghe trên logiao diện.

Bạn đã nghe đúng: Nếu bạn có hai giao diện (nói eth0eth1) với hai địa chỉ IP khác nhau, (giả sử 192.0.2.1 cho eth0và 198.51.100.1 cho eth1) và bạn nói với một ứng dụng để liên kết trên 192.0.2.1, ứng dụng sẽ vẫn nghe cả hai giao diện, nhưng sẽ chỉ đáp ứng nếu IP đích là 192.0.2.1. Vì vậy, ai đó trên eth1giao diện, nếu bảng định tuyến của nó được xác định một cách thích hợp, có thể truy cập ứng dụng của bạn bằng cách truy cập nó qua địa chỉ 192.0.2.1 (nhưng không qua 198.51.100.1) trên eth1giao diện.

Giả sử rằng liên kết với một địa chỉ IP giống như liên kết với giao diện mạng là hoàn toàn sai trên Linux. Nếu điều đó làm phiền bạn, hãy sử dụng định tuyến chính sách và / hoặc iptables.


-1

Cũng với netstat nhưng các đối số cụ thể là:

netstat -lp -i wlan0

1
Bạn có thể giải thích đầu ra của lệnh này lâu hơn một chút không? : D
gasko peter

Thành thật mà nói, tôi không biết. Tôi phải làm thế man netstat. Sự khác biệt mà tôi đề xuất là trong việc thay đổi "truy vấn" mà bạn đang chạy để chỉ định rõ ràng giao diện mà bạn muốn kiểm tra.
ếchstarr78

"Netstat -lp -i wlan0" và "netstat -i" đưa ra cùng một phản hồi trên hệ thống Ubuntu của tôi
Bruce Barnett

1
netstat -isẽ liệt kê các giao diện, không phải các cổng nghe, -1 cho câu trả lời không phản ánh đúng thực tế
Mikko Rantalainen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.