ทดสอบว่าพอร์ตบนระบบรีโมตสามารถเข้าถึงได้ (ไม่มี telnet)


353

ในสมัยก่อนเราเคยtelnetตรวจสอบว่าพอร์ตในรีโมตโฮสต์เปิดอยู่หรือไม่: telnet hostname portพยายามเชื่อมต่อกับพอร์ตใด ๆ บนโฮสต์ใด ๆ และให้คุณเข้าถึงสตรีม TCP ดิบ

ทุกวันนี้ระบบที่ฉันทำงานไม่มีการติดตั้ง telnet (เพื่อเหตุผลด้านความปลอดภัย) และการเชื่อมต่อขาออกทั้งหมดไปยังโฮสต์ทั้งหมดจะถูกบล็อกโดยค่าเริ่มต้น เมื่อเวลาผ่านไปมันง่ายที่จะสูญเสียการติดตามพอร์ตที่เปิดไปที่โฮสต์ใด

มีวิธีอื่นในการทดสอบว่าพอร์ตในระบบรีโมตเปิดอยู่หรือไม่โดยใช้ระบบ Linux ที่ติดตั้งแพ็คเกจจำนวน จำกัด และtelnetไม่สามารถใช้งานได้



ฉันมีปัญหาเดียวกันนี้ คำตอบโดย @Subhranath Chunder ด้านล่างช่วย แต่จากนั้นผมก็พบว่าการติดตั้ง Telnet เป็นเรื่องเล็ก ๆ brew install telnetของการทำงาน ดังนั้นผมจึงคาดหวังว่าผู้ใช้ Linux สามารถทำเช่นเดียวกันกับและyum apt-get
Mig82

คำตอบ:


277

Bash สามารถเข้าถึงพอร์ตTCPและUDP ได้ระยะหนึ่ง จากหน้าคน:

/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.

ดังนั้นคุณสามารถใช้สิ่งนี้:

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

Taa Daa!


นอกจากนี้ยังดูเหมือนว่าจะทำงานในMinGW ตัวอย่างเช่นเซิร์ฟเวอร์VNCระยะไกลบน 192.168.2.100 ตอบกลับด้วย "RFB 003.008" โดยใช้ "cat </dev/tcp/192.168.2.100/5900"
Peter Mortensen

1
@ lornix, ok แต่ในกรณีนี้ฉันต้องได้รับผลลัพธ์เดียวกันกับใช้ nc โดยไม่มีตัวเลือก -z แต่ก็ยังใช้งานไม่ได้: # nc -v -w5 127.0.0.1 18080 การเชื่อมต่อกับ 127.0.0.1 18080 พอร์ต [tcp /*] ที่ประสบความสำเร็จ! # cat </dev/tcp/127.0.0.1/18080 เพียงแฮงค์โดยไม่มีผลลัพธ์ใด ๆ เพียงแค่ต้องการที่จะเข้าใจเมื่อฉันสามารถใช้ตัวเลือก "/ dev / tcp / host / port"
Alexandr

5
@Alexandr ... จริง ๆ แล้ว "แฮงค์โดยไม่มีผลใด ๆ " เป็นพฤติกรรมที่คาดหวังมาก แมวกำลังรอสำหรับการป้อนข้อมูล ncมี smarts พิเศษเพื่อให้สามารถรับรู้ว่าไม่มีข้อมูลที่ค้างอยู่และหยุดพยายาม แมวไม่ได้ค่อนข้างเป็นสมาร์ท ลองcat < /dev/tcp/localhost/22คุณควรได้รับส่วนหัว sshd ของคุณ เห็นได้ชัดว่ากระบวนการของคุณที่พอร์ต 18080 รอให้มีบางอย่างเข้ามาก่อนที่จะส่งอะไร พอร์ต 22 ( ssh ) ทักทายคุณด้วยเวอร์ชันและอะไร ลอง!
lornix

1
@ lornix ขอบคุณมากสำหรับคำอธิบาย! ตอนนี้ข้อ จำกัด มีความชัดเจน ฉันคิดว่าการใช้ NC ควรเป็นวิธีที่ต้องการในการตรวจสอบพอร์ต
Alexandr

2
สิ่งนี้มีประโยชน์อย่างเหลือเชื่อเมื่อทำงานกับตัวเทียบท่าที่ไม่มีอะไรติดตั้ง สามารถตรวจสอบได้อย่างรวดเร็วว่าคอนเทนเนอร์มีการเข้าถึงฐานข้อมูลที่ไม่ใช่คอนเทนเนอร์ผ่าน DNS ตัวอย่าง: แมว </ dev / TCP / ชื่อโฮสต์ / 5432
ไมเคิลฮอบส์

404

ดีและ verbose! จากหน้าคน
พอร์ตเดียว:

nc -zv 127.0.0.1 80

หลายพอร์ต:

nc -zv 127.0.0.1 22 80 8080

ช่วงของพอร์ต:

nc -zv 127.0.0.1 20-30

6
ดูเหมือนจะเป็นคำตอบที่ดีที่สุดขอบคุณ ;-)
lpapp

6
สิ่งนี้แขวนเมื่อพยายามในUbuntu 14.04 (Trusty Tahr) สำหรับเซิร์ฟเวอร์ระยะไกล (LAN เดียวกัน) สำหรับพอร์ตที่ปิด (หมดเวลาหลังจาก 127 วินาที) - จึงไม่เหมาะกับสคริปต์ มันทำงานได้ดีสำหรับบริการที่เปิดพอร์ต การใช้ตัวเลือก "-w2" อาจเป็นวิธีแก้ปัญหา
Peter Mortensen

6
ใช้ตัวเลือก -u สำหรับพอร์ต UDP
Efren

8
ในเวอร์ชัน 6.4 ของ ncat -z ไม่เป็นที่รู้จัก ฉันสามารถทำได้โดยไม่ต้อง z
smishra

5
คุณสามารถตรวจสอบหลายช่วงได้ด้วย: nc -zv 127.0.0.1 22,80,8080,20-30,443-446(เวอร์ชัน nc: 1.107-4)
bobbel

102

Netcat เป็นเครื่องมือที่มีประโยชน์:

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

จะส่งออก0หากพอร์ต 123 เปิดอยู่และ1หากปิดอยู่


นี่เป็นคำตอบที่งดงามและเป็นสคริปต์มากกว่าของฉัน มันเป็นเรื่องที่โชคร้ายสำหรับฉันที่ผู้ดูแลระบบด้านความปลอดภัยที่ระงับtelnetไว้nc(เช่น - แปลก - ไม่curlหรือwget)
Steve HHH

ใช่ว่ามันเป็นเรื่องง่ายและไร้เหตุผล
thnee

3
ให้FORข้อความเริ่มต้นขึ้น!
แช้ดแฮร์ริสัน

1
สิ่งนี้แขวนเมื่อพยายามในUbuntu 14.04 (Trusty Tahr) สำหรับเซิร์ฟเวอร์ระยะไกล (LAN เดียวกัน) สำหรับพอร์ตปิด (หมดเวลาหลังจากนั้นประมาณ 127 วินาที) - จึงไม่เหมาะกับสคริปต์ มันทำงานได้ดีสำหรับบริการที่เปิดพอร์ตกลับ 0 โดยใช้ตัวเลือก "-w2" อาจเป็นวิธีแก้ปัญหา
Peter Mortensen

1
ฉันคิดว่า-G 2จะเหมาะสมกว่าสำหรับการหมดเวลา TCP
AB

58

วิธีที่ง่ายที่สุดโดยไม่ต้องใช้เครื่องมืออื่นเช่นดังsocatที่อธิบายไว้ในคำตอบของ @ lornix ด้านบน นี่เป็นเพียงการเพิ่มตัวอย่างจริงของวิธีใช้อุปกรณ์ psuedo /dev/tcp/...ภายใน Bash ถ้าคุณต้องการพูดทดสอบว่าเซิร์ฟเวอร์อื่นมีพอร์ตที่กำหนดให้สามารถเข้าถึงได้ผ่านบรรทัดคำสั่ง

ตัวอย่าง

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

เหตุผลที่คุณต้องการปิดecho > /dev/...วงเล็บในแบบนี้(echo > /dev/...)ก็เพราะว่าถ้าคุณไม่ทำแล้วด้วยการทดสอบการเชื่อมต่อที่ไม่ทำงานคุณจะได้รับข้อความประเภทนี้ปรากฏขึ้น

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

เหล่านี้ไม่เพียง แต่จะเปลี่ยนเส้นทางไปตั้งแต่พวกเขามาจากความพยายามที่จะเขียนออกข้อมูลไปยังอุปกรณ์/dev/null /dev/tcpดังนั้นเราจึงจับเอาท์พุททั้งหมดที่อยู่ในคำสั่งย่อยคือ(...cmds...)และเปลี่ยนเส้นทางของคำสั่งย่อย


มันยอดเยี่ยมมาก หวังว่ามันจะได้รับการโหวตขึ้นไปด้านบน ฉันอ่านมาแค่นี้เท่านั้นเพราะฉันบังเอิญเลื่อนไปก่อนจะปิดมัน
Still.Tony

@ Okuma.Tony - ใช่ว่าเป็นปัญหาของ Q ที่มีคำตอบมากมาย 8-) ขอบคุณสำหรับข้อเสนอแนะ แต่ก็ชื่นชม
slm

46

ฉันพบว่าcurlอาจทำให้งานเสร็จสิ้นในลักษณะที่คล้ายกันtelnetและcurlจะบอกคุณถึงโปรโตคอลที่ผู้ฟังคาดหวัง

สร้าง HTTP URI curlจากชื่อโฮสต์และพอร์ตเป็นอาร์กิวเมนต์แรก หากcurlสามารถเชื่อมต่อได้จะรายงานโปรโตคอลไม่ตรงกันและออก (หากผู้ฟังไม่ใช่เว็บเซอร์วิส) หากcurlไม่สามารถเชื่อมต่อได้จะเป็นการหมดเวลา

ตัวอย่างเช่นพอร์ต 5672 บนโฮสต์ 10.0.0.99 ถูกปิดหรือถูกบล็อกโดยไฟร์วอลล์:

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

อย่างไรก็ตามจากระบบอื่นสามารถเข้าถึงพอร์ต 5672 บนโฮสต์ 10.0.0.99 และดูเหมือนว่ากำลังใช้งานฟัง AMQP

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

สิ่งสำคัญคือต้องแยกความแตกต่างระหว่างข้อความต่าง ๆ : ความล้มเหลวแรกเป็นเพราะcurlไม่สามารถเชื่อมต่อกับพอร์ต ความล้มเหลวที่สองคือการทดสอบความสำเร็จแม้ว่าcurlคาดว่าจะเป็นฟัง HTTP แทนฟัง AMQP


5
หากขดไม่สามารถใช้งานได้ wget อาจจะเป็น wget -qS -O- http://ip.add.re.ss:portควรทำสิ่งเดียวกันได้อย่างมีประสิทธิภาพ
CVn

4
แม้จะใช้งานได้กับชื่อโฮสต์เช่น curl myhost:22.
에이바

สิ่งนี้อาจไม่ถูกต้อง ฉัน havng บริการโพงทำงาน แต่ได้รับข้อผิดพลาด 404 # curl -k 192.168.194.4:6443 <html><head> <title> Apache Tomcat / 7.0.34 - รายงานข้อผิดพลาด </title> <style> <! - H1 --- HR {color: # 525D76;} -> </style> </head><body> <h1> สถานะ HTTP 404 - / </h1> <HR size = "1" noshade = "noshade"> <p> <b> type </b> รายงานสถานะ </p> <p> <b> ข้อความ </b> <u>/</u></p><p> <b> คำอธิบาย </b> <u> ทรัพยากรที่ร้องขอไม่สามารถใช้ได้ </u> </p> <HR size = "1" noshade = "noshade"> <h3> Apache Tomcat / 7.0.34 </h3> </body> </body> </html>

ดูโพสต์ของฉันด้วยวิธีการที่คล้ายกัน
kenorb

12
[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!

หวังว่ามันจะช่วยแก้ปัญหาของคุณ :)


1
ใช่นี่จะดีกว่า - หมดเวลาเกือบทันทีสำหรับพอร์ตที่ปิด
Peter Mortensen

1
สิ่งนี้ใช้ TCP หรือมีวิธีตรวจสอบ UDP เสมอหรือไม่
kmoe

9

นี่คือหนึ่งซับ:

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

โดยใช้ไวยากรณ์ทุบตีอธิบายในคำตอบ @lornix

สำหรับข้อมูลเพิ่มเติมตรวจสอบ: ขั้นสูงทุบตี Scripting-Guide: บทที่ 29/dev/procและ


หมดเวลาสำหรับพอร์ตปิดคืออะไร
Tilo

6

ฉันดิ้นรนทั้งวันเพราะไม่มีคำตอบใดที่ดูเหมือนจะใช้ได้สำหรับฉัน ปัญหาคือเวอร์ชันล่าสุดที่ncไม่มี-zแฟล็กอีกต่อไปขณะที่การเข้าถึงโดยตรงผ่าน TCP (ตามที่ @lornix และ @slm) ล้มเหลวเมื่อโฮสต์ไม่สามารถเข้าถึงได้ ฉันในที่สุดก็พบหน้านี้ที่ในที่สุดผมก็พบว่าไม่หนึ่ง แต่สองตัวอย่างการใช้งาน:

  1. nc -w1 127.0.0.1 22 </dev/null

    ( -wแฟล็กดูแลการหมดเวลาและ</dev/nullแทนที่-zแฟล็ก)

  2. timeout 1 bash -c '(echo > /dev/tcp/127.0.0.1/22) >/dev/null 2>&1'

    ( timeoutคำสั่งจะดูแลการหมดเวลาและส่วนที่เหลือมาจาก @slm)

จากนั้นใช้&&และ / หรือ||(หรือแม้กระทั่ง$?) เพื่อแยกผลลัพธ์ หวังว่าบางคนจะพบว่าข้อมูลนี้มีประโยชน์


4

การรวมคำตอบจาก @kenorb และ @Azukikuru คุณสามารถทดสอบพอร์ตเปิด / ปิด / ไฟร์วอลล์

timeout 1 bash -c '</dev/tcp/127.0.0.1/22 && echo Port is open || echo Port is closed' || echo Connection timeout

อีกวิธีหนึ่งในการม้วนเข้าหาพอร์ตใดก็ได้

curl telnet://127.0.0.1:22

3

นี่คือฟังก์ชันที่จะเลือกหนึ่งในวิธีการที่ขึ้นอยู่กับสิ่งที่ติดตั้งในระบบของคุณ:

# Check_port <address> <port> 
check_port() {
if [ "$(which nc)" != "" ]; then 
    tool=nc
elif [ "$(which curl)" != "" ]; then
     tool=curl
elif [ "$(which telnet)" != "" ]; then
     tool=telnet
elif [ -e /dev/tcp ]; then
      if [ "$(which gtimeout)" != "" ]; then  
       tool=gtimeout
      elif [ "$(which timeout)" != "" ]; then  
       tool=timeout
      else
       tool=devtcp
      fi
fi
echo "Using $tool to test access to $1:$2"
case $tool in
nc) nc -v -G 5 -z -w2 $1 $2 ;;
curl) curl --connect-timeout 10 http://$1:$2 ;;
telnet) telnet $1 $2 ;;
gtimeout)  gtimeout 1 bash -c "</dev/tcp/${1}/${2} && echo Port is open || echo Port is closed" || echo Connection timeout ;;
timeout)  timeout 1 bash -c "</dev/tcp/${1}/${2} && echo Port is open || echo Port is closed" || echo Connection timeout ;;
devtcp)  </dev/tcp/${1}/${2} && echo Port is open || echo Port is closed ;;
*) echo "no tools available to test $1 port $2";;
esac

}
export check_port

2

มันไม่ควรจะมีอยู่ในกล่องของคุณ nmapแต่ลองกับ


4
nmapเป็นเครื่องมือที่ดี แต่ไม่มีในระบบเหล่านี้ แทนที่จะดาวน์โหลดnmapรวบรวมติดตั้งไว้ในโฮมไดเร็กตอรี่ของฉันแล้วคัดลอกไปยังระบบอื่น ๆ ทั้งหมดฉันหวังว่าจะหาวิธีใช้เครื่องมือที่มีอยู่ในการติดตั้ง Linux ส่วนใหญ่
Steve HHH

1

สำหรับการอ้างอิงขยายคำตอบ @peperunas:

วิธีใช้nmapเพื่อทดสอบคือ:

nmap -p 22 127.0.0.1

(ตัวอย่างข้างต้นใช้ localhost เพื่อวัตถุประสงค์ในการสาธิต)


0

หากคุณทดสอบมากกว่าระบบคุณสามารถใช้เครื่องมือทดสอบของเรา dda-serverspec ( https://github.com/DomainDrivenArchitecture/dda-serverspec-crate ) สำหรับงานดังกล่าว คุณอาจกำหนดความคาดหวังของคุณ

{:netcat [{:host "mywebserver.com" :port "443"}
          {:host "telnet mywebserver.com" :port "80"}
          {:host "telnet mywebserver.com" :port "8443"}]}

และทดสอบความคาดหวังเหล่านี้กับ localhost หรือกับโฮสต์ระยะไกล (เชื่อมต่อโดย ssh) สำหรับการทดสอบระยะไกลคุณต้องกำหนดเป้าหมาย:

{:existing [{:node-name "test-vm1"
             :node-ip "35.157.19.218"}
            {:node-name "test-vm2"
             :node-ip "18.194.113.138"}]
 :provisioning-user {:login "ubuntu"}}

คุณสามารถทำการทดสอบด้วย java -jar dda-serverspec.jar --targets targets.edn serverspec.edn

ใต้ฝากระโปรงเราใช้ netcat ตามที่แนะนำข้างต้น ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.