Câu hỏi Kiểm tra xem một cổng trên một hệ thống từ xa có thể truy cập được (không có telnet)


Trong những ngày cũ, chúng tôi đã sử dụng telnet để xem một cổng trên máy chủ từ xa đã mở chưa: telnet hostname port sẽ cố gắng kết nối với bất kỳ cổng nào trên bất kỳ máy chủ lưu trữ nào và cung cấp cho bạn quyền truy cập vào luồng TCP thô.

Những ngày này, các hệ thống tôi làm việc trên không có cài đặt telnet (vì lý do bảo mật) và tất cả các kết nối gửi đi tới tất cả các máy chủ đều bị chặn theo mặc định. Theo thời gian, thật dễ dàng để mất khả năng theo dõi cổng nào được mở cho máy chủ nào.

Có cách nào khác để kiểm tra xem một cổng trên hệ thống từ xa có đang mở hay không - sử dụng hệ thống Linux với số lượng gói giới hạn được cài đặt và telnet không có sẵn?


251
2017-07-19 16:54


gốc


Liên quan: kiểm tra trạng thái của một cổng trên máy chủ từ xa tại SO - kenorb


Các câu trả lời:


Bash đã có thể truy cập TCP và UDP cổng trong một thời gian. Từ trang người đàn ông:

/dev/tcp/host/port
    If host is a valid hostname or Internet address, and port is an integer port number
    or service name, bash attempts to open a TCP connection to the corresponding socket.
/dev/udp/host/port
    If host is a valid hostname or Internet address, and port is an integer port number
    or service name, bash attempts to open a UDP connection to the corresponding socket.

Vì vậy, bạn có thể sử dụng một cái gì đó như thế này:

xenon-lornix:~> cat < /dev/tcp/127.0.0.1/22
SSH-2.0-OpenSSH_6.2p2 Debian-6
^C pressed here

Taa Daa!


215
2017-07-22 10:37



Điều này cũng có vẻ hoạt động MinGW. Ví dụ, một điều khiển từ xa VNC máy chủ trên 192.168.2.100 phản hồi bằng "RFB 003.008" bằng cách sử dụng "cat </dev/tcp/192.168.2.100/5900". - Peter Mortensen
Tuy nhiên trên các cổng không mở nó hết thời gian chờ sau 22 giây (thử trên Ubuntu 14.04 (Trusty Tahr) cho một máy chủ từ xa). Điều thú vị là, khoảng thời gian chờ ngắn hơn nhiều so với thời gian chờ cho nc (xem câu trả lời của thnee). - Peter Mortensen
@ lornix, ok, nhưng trong trường hợp này tôi phải nhận được kết quả tương tự với việc sử dụng nc mà không có tùy chọn -z, nhưng nó vẫn không hoạt động: # nc -v -w5 127.0.0.1 18080 Kết nối tới 127.0.0.1 18080 port [tcp / *] đã thành công! # cat </dev/tcp/127.0.0.1/18080 Chỉ bị treo mà không có kết quả nào. Chỉ muốn hiểu khi nào tôi có thể sử dụng tùy chọn "/ dev / tcp / host / port" - Alexandr
@ Alexandr ... thực sự, "treo mà không có bất kỳ kết quả" là hành vi khá nhiều dự kiến. con mèo đang chờ đầu vào. nc có thêm thông minh để cho phép nó cảm nhận không có dữ liệu đang chờ xử lý và ngừng thử. con mèo không phải khá thông minh. Thử cat < /dev/tcp/localhost/22, bạn sẽ nhận được tiêu đề sshd của bạn. Rõ ràng, quá trình của bạn trên cổng 18080 chờ đợi một cái gì đó để đi vào, trước khi gửi bất cứ điều gì. Cổng 22 (ssh) chào đón bạn với phiên bản của nó và không có gì. Hãy thử nó! - lornix
@ lornix, cảm ơn bạn rất nhiều vì đã giải thích! Bây giờ hạn chế là rõ ràng. Tôi nghĩ rằng bằng cách sử dụng nc nên là một cách ưa thích để kiểm tra cổng. - Alexandr


Đẹp và tiết tú! Từ các trang của người đàn ông.
Cổng đơn:

nc -zv 127.0.0.1 80

Nhiều cổng:

nc -zv 127.0.0.1 22 80 8080

Phạm vi của các cổng:

nc -zv 127.0.0.1 20-30

297
2017-12-03 21:34



Dường như đến nay là câu trả lời tốt nhất, cảm ơn. ;-) - lpapp
Này treo cổ khi cố gắng trên Ubuntu 14.04 (Trusty Tahr) cho một máy chủ từ xa (cùng một mạng LAN) cho các cổng đã đóng (nó đã hết thời gian sau 127 giây) - do đó không phù hợp lắm trong các kịch bản lệnh. Nó đã làm việc mặc dù cho một dịch vụ đã có một cổng mở. Sử dụng tùy chọn "-w2" có thể là giải pháp. - Peter Mortensen
Sử dụng tùy chọn -u cho các cổng UDP. - Efren
Trên phiên bản 6.4 của ncat -z không được nhận dạng. Tôi đã có thể làm mà không có z - smishra
Bạn có thể kiểm tra nhiều phạm vi với: nc -zv 127.0.0.1 22,80,8080,20-30,443-446 (nc Phiên bản: 1.107-4). - bobbel


Netcat là một công cụ hữu ích:

nc 127.0.0.1 123 &> /dev/null; echo $?

Sẽ đầu ra 0 nếu cổng 123 mở, và 1 nếu nó đóng cửa.


96
2017-07-19 18:07



Đây là một câu trả lời rất thanh lịch và dễ hiểu hơn tôi. Thật không may với tôi rằng những người quản trị hệ thống có ý thức bảo mật bị giữ lại telnet cũng bị giữ lại nc (mặc dù - kỳ lạ - không curl hoặc là wget). - Steve HHH
Vâng, đó là hoàn toàn tùy ý và ngớ ngẩn. - thnee
Hãy để FOR báo cáo bắt đầu! - Chad Harrison
Này treo cổ khi cố gắng trên Ubuntu 14.04 (Trusty Tahr) cho một máy chủ từ xa (cùng một mạng LAN) cho các cổng đóng (nó hết thời gian sau khoảng 127 giây) - do đó không phù hợp lắm trong các kịch bản lệnh. Nó đã làm việc mặc dù cho một dịch vụ có một cổng mở, trở về 0. Sử dụng tùy chọn "-w2" có thể là giải pháp. - Peter Mortensen
Tôi nghĩ -G 2 sẽ thích hợp hơn cho thời gian chờ TCP - A B


Phương pháp đơn giản nhất, không sử dụng công cụ khác, chẳng hạn như socat, như được mô tả trong câu trả lời của @ lornix ở trên. Đây chỉ là để thêm một ví dụ thực tế về cách một người sẽ sử dụng thiết bị psuedo /dev/tcp/... bên trong Bash nếu bạn muốn, nói, kiểm tra xem máy chủ khác có một cổng nhất định có thể truy cập thông qua dòng lệnh hay không.

Ví dụ

Giả sử tôi có một máy chủ lưu trữ trên mạng của tôi có tên skinner.

$ (echo > /dev/tcp/skinner/22) >/dev/null 2>&1 \
    && echo "It's up" || echo "It's down"
It's up

$ (echo > /dev/tcp/skinner/222) >/dev/null 2>&1 && \
    echo "It's up" || echo "It's down"
It's down

Lý do bạn muốn quấn echo > /dev/... trong ngoặc đơn như thế này, (echo > /dev/...) là vì nếu bạn không làm như vậy, thì với các kiểm tra kết nối bị hỏng, bạn sẽ nhận được các loại thông báo này hiển thị.

$ (echo > /dev/tcp/skinner/223) && echo hi
bash: connect: Connection refused
bash: /dev/tcp/skinner/223: Connection refused

Chúng không thể được chuyển hướng đến /dev/null vì chúng đến từ nỗ lực ghi dữ liệu vào thiết bị /dev/tcp. Vì vậy, chúng tôi nắm bắt tất cả đầu ra đó trong một lệnh phụ, tức là (...cmds...) và chuyển hướng đầu ra của lệnh phụ.


48
2017-09-02 17:59



Thật tuyệt vời. Muốn nó sẽ được bình chọn lên đến đỉnh. Tôi chỉ đọc cái này ở phía dưới trang vì tôi vô tình cuộn xuống trước khi đóng nó lại. - Still.Tony
@ Okuma.Tony - vâng, đó luôn là vấn đề với câu hỏi của Q có nhiều câu trả lời 8-). Cảm ơn phản hồi mặc dù, nó được đánh giá cao. - slm


Tôi thấy rằng curl có thể hoàn thành công việc theo cách tương tự telnetcurl thậm chí sẽ cho bạn biết giao thức người nghe mong đợi.

Xây dựng một URI HTTP từ tên máy chủ và cổng làm đối số đầu tiên curl. Nếu curl có thể kết nối, nó sẽ báo cáo một giao thức không khớp và thoát (nếu người nghe không phải là một dịch vụ web). Nếu curl không thể kết nối, nó sẽ hết thời gian chờ.

Ví dụ: cổng 5672 trên máy chủ lưu trữ 10.0.0.99 bị đóng hoặc chặn bởi tường lửa:

$ curl http://10.0.0.99:5672
curl: (7) couldn't connect to host

Tuy nhiên, từ một hệ thống khác, cổng 5672 trên máy chủ lưu trữ 10.0.0.99 có thể đạt được và dường như đang chạy trình nghe AMQP.

$ curl http://10.0.0.99:5672
curl: (56) Failure when receiving data from the peer
AMQP

Điều quan trọng là phải phân biệt giữa các thông điệp khác nhau: lỗi đầu tiên là vì curl không thể kết nối với cổng. Thất bại thứ hai là một thử nghiệm thành công, mặc dù curl mong đợi một người nghe HTTP thay vì một người nghe AMQP.


35
2017-07-19 17:05



Nếu curl không có sẵn, wget có thể được. wget -qS -O- http://ip.add.re.ss:portnên làm điều tương tự. - Michael Kjörling
Điều này thậm chí làm việc với một tên máy, ví dụ. curl myhost:22. - 에이바
Điều này có thể không chính xác. Tôi đang chạy một dịch vụ tomcat, nhưng bị lỗi 404. # curl -k 192.168.194.4:6443 <html> <head> <title> Apache Tomcat / 7.0.34 - Báo cáo lỗi </ title> <style> <! - H1 --- HR {color: # 525D76;} -> </ style> </ head> <body> <h1> Trạng thái HTTP 404 - / </ h1> <HR size = "1" noshade = "noshade"> <p> <b> loại </ b> Báo cáo trạng thái </ p> <p> <b> thông báo </ b> <u> / </ u> </ p> <p> <b> mô tả </ b> <u> Tài nguyên được yêu cầu không có sẵn. </ u> </ p> < Kích thước nhân sự = "1" noshade = "noshade"> <h3> Apache Tomcat / 7.0.34 </ h3> </ body> </ html> - Mohammad Shahid Siddiqui
Xem của tôi bài đăng với cách tiếp cận tương tự. - kenorb


[admin@automation-server 1.2.2]# nc -v -z -w2 192.168.193.173 6443
nc: connect to 192.168.193.173 port 6443 (tcp) failed: Connection refused

[admin@automation-server 1.2.2]# nc -v -z -w2 192.168.194.4 6443
Connection to 192.168.194.4 6443 port [tcp/sun-sr-https] succeeded!

Hy vọng nó giải quyết vấn đề của bạn :)


8
2018-06-02 06:27



Có, điều này là tốt hơn - thời gian ra gần như ngay lập tức cho các cảng đóng cửa. - Peter Mortensen
Điều này luôn luôn sử dụng TCP hoặc là có một cách để làm cho nó để kiểm tra UDP? - kmoe


Dưới đây là một lớp lót:

</dev/tcp/localhost/11211 && echo Port is open || echo Port is closed

bằng cách sử dụng cú pháp Bash được giải thích trong câu trả lời @lornix.

Để biết thêm thông tin, hãy kiểm tra: Hướng dẫn viết kịch bản lệnh Bash nâng cao: Chương 29. /dev và /proc.


7
2018-03-16 11:21