ทดสอบว่าพอร์ตเปิดอยู่บน Linux อย่างมีประสิทธิภาพหรือไม่


197

จากสคริปต์ทุบตีฉันจะทราบได้อย่างรวดเร็วว่าพอร์ต445เปิด / รับฟังบนเซิร์ฟเวอร์หรือไม่

ฉันได้พยายามสองตัวเลือก แต่ฉันต้องการบางสิ่งบางอย่างรวดเร็ว:
1. lsof -i :445 (ใช้เวลาไม่กี่วินาที)
2. netstat -an |grep 445 |grep LISTEN(ใช้เวลาไม่กี่วินาที)
3. telnet(มันไม่กลับ)
4. nmap, netcatจะไม่สามารถใช้ได้บนเซิร์ฟเวอร์

มันจะเป็นการดีที่ได้ทราบวิธีการที่ไม่ระบุจำนวนแรกและ greps หลังจากนั้น


1
netcat พร้อมใช้งานหรือไม่ มันมีเส้นทางที่ล้มเหลวอย่างรวดเร็ว IIRC netcat.sourceforge.net
JimR

5
netstat -lnt(มี-tและไม่มี-a) จะ จำกัด เอาต์พุตเฉพาะการฟังการเชื่อมต่อ TCP เท่านั้น อาจเพิ่มความเร็วขึ้นเล็กน้อย คุณสามารถเพิ่ม-4สำหรับ IPv4 เฉพาะในกรณีที่คุณไม่จำเป็นต้องใช้ IPv6
Bartosz Moczulski

lsof -i เป็นรายการโปรดส่วนตัว
แมตต์จอยซ์

14
netstat -an | grep PORTNUMBER | grep -i listenหากเอาต์พุตไม่มีพอร์ตแสดงว่าไม่ได้ใช้งาน
automatix

ฉันไม่รู้ว่าทำไมlsofช้าสำหรับคุณ แต่โดยปกติแล้วมันเป็นวิธีแก้ปัญหาที่ดีที่สุดที่คุณแจ้งไว้ netstatโซลูชันของคุณไม่น่าเชื่อถือมาก (คุณสามารถคาดเดาได้ทุกครั้งที่ใช้grepอย่างไรก็ตามจะส่งกลับจริงถ้ามีคนฟังอยู่เช่น 4450) telnetและnetcatพยายามสร้างการเชื่อมต่อซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ
petersohn

คำตอบ:


155

แปลกใจที่ผมพบเมื่อเร็ว ๆ นี้ก็คือว่าทุบตี natively สนับสนุนการเชื่อมต่อ TCP เป็นอธิบายไฟล์ ใช้:

exec 6<>/dev/tcp/ip.addr.of.server/445
echo -e "GET / HTTP/1.0\n" >&6
cat <&6

ฉันใช้ 6 เป็นตัวอธิบายไฟล์เพราะ 0,1,2 เป็น stdin, stdout และ stderr 5 บางครั้งถูกใช้โดยBash สำหรับกระบวนการลูกดังนั้น 3,4,6,7,8 และ 9 ควรปลอดภัย

ตามความคิดเห็นด้านล่างเพื่อทดสอบการฟังบนเซิร์ฟเวอร์ในระบบในสคริปต์:

exec 6<>/dev/tcp/127.0.0.1/445 || echo "No one is listening!"
exec 6>&- # close output connection
exec 6<&- # close input connection

หากต้องการตรวจสอบว่ามีคนฟังอยู่หรือไม่ลองเชื่อมต่อด้วยลูปแบ็ค หากมันล้มเหลวพอร์ตจะถูกปิดหรือเราไม่ได้รับอนุญาตให้เข้าถึง หลังจากนั้นให้ปิดการเชื่อมต่อ

แก้ไขสิ่งนี้สำหรับกรณีการใช้งานของคุณเช่นการส่งอีเมลออกจากสคริปต์เมื่อเกิดความล้มเหลวหรือเริ่มบริการที่จำเป็น


2
เพียงแค่นี้แขวนสำหรับฉัน
Aman Jain

@AmanJain cat รอ EOF หรือ Ctrl-C เพื่อออก คุณจะต้องปรับเปลี่ยนนี้สำหรับโปรโตคอลของคุณ BTW คุณใช้สิ่งนี้กับเซิร์ฟเวอร์ระยะไกลหรือไม่?
Spencer Rathbun

ฉันต้องการฝังรหัสตรวจสอบพอร์ตในสคริปต์บนเซิร์ฟเวอร์ภายใต้ /etc/init.d/
Aman Jain

@AmanJain ฉันได้อัปเดตสำหรับระบบภายในเครื่องแล้ว คุณเพียงแค่ต้องการตรวจสอบว่ามันฟังถูกต้องหรือไม่ ไม่มีการตรวจสอบโปรโตคอลเช่นขอหน้าผ่านทาง http หรือไม่
Spencer Rathbun

1
นี่ไม่ใช่วิธีการที่เชื่อถือได้เนื่องจากไม่ใช่ทุก OS (เช่น ubuntu 16 ที่ฉันค้นพบในวันนี้) มาพร้อมกับ bash ที่คอมไพล์แล้วสำหรับการสร้าง/dev/tcp/IP/PORTต้นไม้
dyasny

107

มีสั้นมากกับ "คำตอบอย่างรวดเร็ว" ที่นี่: วิธีการทดสอบว่าพอร์ต TCP ระยะไกลเปิดจากสคริปต์ Shell?

nc -z <host> <port>; echo $?

ฉันใช้กับ 127.0.0.1 เป็นที่อยู่ "ระยะไกล"

ส่งคืน "0" หากพอร์ตเปิดอยู่และ "1" ถ้าพอร์ตปิด

เช่น

nc -z 127.0.0.1 80; echo $?

-z ระบุว่า nc ควรสแกนเพื่อฟัง daemons โดยไม่ต้องส่งข้อมูลใด ๆ ไปยังพวกเขา มันเป็นข้อผิดพลาดที่จะใช้ตัวเลือกนี้ร่วมกับตัวเลือก -l


2
ดูเหมือนจะเป็นวิธีที่ง่ายที่สุดขอบคุณ ลิงค์สคริปต์ตัวอย่างไม่ทำงานอีกต่อไป แต่มันค่อนข้างอธิบายได้ด้วยตนเอง
derFunk

ดี! นี่เร็วกว่าคำตอบอื่น ๆ บนเซิร์ฟเวอร์ที่เปิดพอร์ตจำนวนมาก ส่งกลับใน <0.01 วินาทีสำหรับฉันในขณะที่ netstat / lsof ใช้เวลา 1 วินาที +
Tim

2
แฟล็ก -z ไม่สามารถใช้ได้ใน ncat แบบ ncat ซึ่ง distros ล่าสุดจัดส่งด้วย: Fedora, Centos, ฯลฯ (nmap-ncat-6.01-9.fc18.x86_64)
Zack

9
ตอบโต้ด้วยวิธีนี้ผลตอบแทน "0" ถ้าพอร์ตเปิดและ "1" ถ้าพอร์ตปิด
ฌอน

3
โดยปกติแล้วคำสั่ง @Sean unix จะส่งกลับ '0' เพื่อระบุความสำเร็จและไม่เป็นศูนย์สำหรับความล้มเหลว ดังนั้น '0' แสดงว่าเชื่อมต่อสำเร็จและไม่เป็นศูนย์ซึ่งไม่ได้เชื่อมต่อด้วยเหตุผลบางประการ อย่างไรก็ตามโปรดทราบว่าบางเวอร์ชันของ 'nc' ไม่รองรับอาร์กิวเมนต์ '-z' ดังนั้นstackoverflow.com/a/25793128/6773916จึงเป็นทางออกที่ดีกว่า
เศรษฐี Sedman

89

คุณสามารถใช้ netstat ด้วยวิธีนี้เพื่อผลลัพธ์ที่รวดเร็วยิ่งขึ้น:

บน Linux:

netstat -lnt | awk '$6 == "LISTEN" && $4 ~ /\.445$/'

บน Mac:

netstat -anp tcp | awk '$6 == "LISTEN" && $4 ~ /\.445$/'

สิ่งนี้จะเอาท์พุตรายการกระบวนการที่รับฟังพอร์ต (445 ในตัวอย่างนี้) หรือจะไม่มีผลอะไรถ้าพอร์ตว่าง


1
ไวยากรณ์ netstat ของคุณไม่ถูกต้อง netstat -ln --tcp ใช้งานได้ แต่ยังคงช้าอยู่
Aman Jain

6
ที่จริงมันเป็นไวยากรณ์ที่ถูกต้อง แต่บางทีคุณอาจใช้ Linux และฉันอยู่บน Mac สำหรับ Linux ให้ใช้สิ่งนี้:netstat -lnt | awk '$6 == "LISTEN" && $4 ~ ".445"'
anubhava

21
เอาท์พุทนี้ไม่มีอะไร
Jürgen Paul

1
คำถามคือเกี่ยวกับ linux แม้ว่าดังนั้นความคิดเห็นควรอยู่ในคำตอบ
UpTheCreek

1
เพื่อที่จะตรวจสอบพอร์ต 80 awk '$6 == "LISTEN" && $4 ~ "80$"'ฉันต้องการที่จะใช้ แทนการตรวจสอบจุดก่อนที่หมายเลขพอร์ตที่มีผมใช้\.80 80$มิฉะนั้นนี้ยังจับคู่ที่อยู่ IP ที่มี.80และพอร์ตเริ่มต้นด้วยเช่น80 8000
Patrick Oscity

37

คุณสามารถใช้ netcat สำหรับสิ่งนี้

nc ip port < /dev/null

เชื่อมต่อกับเซิร์ฟเวอร์และปิดการเชื่อมต่ออีกครั้งโดยตรง หาก netcat ไม่สามารถเชื่อมต่อได้จะส่งคืนรหัสออกที่ไม่ใช่ศูนย์ รหัสทางออกถูกเก็บไว้ในตัวแปร $? ตัวอย่างเช่น,

nc ip port < /dev/null; echo $?

จะส่งคืน 0 ถ้าหาก netcat สามารถเชื่อมต่อกับพอร์ตได้สำเร็จ


1
คำตอบนี้ต้องการ upvotes เพิ่มเติม NC ทำงานได้อย่างสมบูรณ์แบบสำหรับกรณีนี้ เคล็ดลับ / dev / tcp นั้นฉลาด แต่ดูเหมือนยากที่จะใช้สคริปต์ที่มีสัญญาณขัดจังหวะ
Avindra Goolcharan

5
ncมีธงเพื่อจุดประสงค์นี้ซึ่งไม่จำเป็นต้องมีการป้อนข้อมูลจาก-z /dev/nullมีคำตอบให้ใช้-zธงด้านบนแล้ว
Abe Voelker

2
@AbeVoelker ไม่ใช่ nc ทุกรุ่นที่สนับสนุนแฟล็ก -z ฉันใช้ CentOS 7 และพบทางออกของโทนี่ว่าเป็นสิ่งที่ฉันต้องการ
Shadoninja

@Shadoninja ดีใจที่รู้! ถ้าฉันสามารถแก้ไขข้อผิดพลาดที่ออกมาจากความคิดเห็นของฉันจาก 2014 ฉันจะ
Abe Voelker

'nc' ไม่รองรับ '-z' อีกต่อไปดังนั้นคำตอบนี้น่าจะเป็นทางออกที่ดีที่สุด
เศรษฐี Sedman

18

ตามคำตอบของ Spencer Rathbun โดยใช้ bash:

true &>/dev/null </dev/tcp/127.0.0.1/$PORT && echo open || echo closed

ดีมันจะระงับข้อความ "ปฏิเสธการเชื่อมต่อ" ออกโดยอัตโนมัติหากบริการยอมรับการเชื่อมต่อโดยไม่ต้องรอตลอดไป
Seff

ทางออกที่ดีที่สุดสำหรับบริการที่ไม่ส่งข้อมูลหลังจากเชื่อมต่อใหม่ เร็วกว่าการโทร netcat ประมาณ 20 เท่า สามารถลงไป: &>/dev/null </dev/tcp/127.0.0.1/$PORT
ens

16

พวกเขากำลังอยู่ในรายการ / proc / net / tcp

มันเป็นคอลัมน์ที่สองหลังจาก ":" ในรูปแบบฐานสิบหก:

> cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                                                     
   0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 10863 1 ffff88020c785400 99 0 0 10 -1                     
   1: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7983 1 ffff88020eb7b3c0 99 0 0 10 -1                      
   2: 0500010A:948F 0900010A:2328 01 00000000:00000000 02:00000576 00000000  1000        0 10562454 2 ffff88010040f7c0 22 3 30 5 3                   
   3: 0500010A:E077 5F2F7D4A:0050 01 00000000:00000000 02:00000176 00000000  1000        0 10701021 2 ffff880100474080 41 3 22 10 -1                 
   4: 0500010A:8773 16EC97D1:0050 01 00000000:00000000 02:00000BDC 00000000  1000        0 10700849 2 ffff880104335440 57 3 18 10 -1                 
   5: 0500010A:8772 16EC97D1:0050 01 00000000:00000000 02:00000BF5 00000000  1000        0 10698952 2 ffff88010040e440 46 3 0 10 -1                  
   6: 0500010A:DD2C 0900010A:0016 01 00000000:00000000 02:0006E764 00000000  1000        0 9562907 2 ffff880104334740 22 3 30 5 4                    
   7: 0500010A:AAA4 6A717D4A:0050 08 00000000:00000001 02:00000929 00000000  1000        0 10696677 2 ffff880106cc77c0 45 3 0 10 -1  

ดังนั้นฉันเดาหนึ่ง:50ในคอลัมน์ที่สามต้องเป็น stackoverflow: o)

ดูในman 5 procรายละเอียดเพิ่มเติม และเลือกว่านอกเหนือจาก sed ฯลฯ ถูกทิ้งไว้เป็นแบบฝึกหัดสำหรับผู้อ่านที่อ่อนโยน ...


10
ss -tl4 '( sport = :22 )'

2ms เร็วพอไหม

เพิ่มโคลอนและใช้งานได้กับ Linux


2
ที่ดีหนึ่งssคือแม้ slighlty ncเร็วกว่า lสำหรับการฟัง , 4สำหรับ IPv4; sportย่อมาจาก (แน่นอน) แหล่งพอร์ต คำสั่งดังกล่าวสมมติว่าพอร์ต TCP คอยรับฟัง ( tตัวเลือก): ใช้uตัวเลือกสำหรับ UDP หรือไม่มีทั้งสองโปรโตคอลสำหรับโปรโตคอล ข้อมูลเพิ่มเติมเกี่ยวกับการssทำงานอยู่ตลอดเวลาNixcraft หมายเหตุ: ssฟิลเตอร์ไม่ได้ทำงานที่นี่ไม่ทราบว่าทำไม (ทุบตี 4.3.11, ยูทิลิตี้เอสเอส, iproute2-ss131122) ต้องไปกับgrep
Campa

น่าเสียดายที่ssคำสั่งไม่ส่งคืนรหัสออกซึ่งสะท้อนถึงการค้นหา มันจะส่งคืนรหัสออก 0 เสมอ
John Greene

| grep LISTEN?
leucos

ฉันได้State Recv-Q Send-Q Local Address:Port Peer Address:Portและตอนนี้ สิ่งนี้หมายความว่า?
Black

6

นี่คือสิ่งที่ใช้ได้กับทั้ง Mac และ Linux:

netstat -aln | awk '$6 == "LISTEN" && $4 ~ "[\\.\:]445$"'

[\\.\:]ฉันคิดว่าคุณได้อย่างปลอดภัยสามารถลบ
Patrick Oscity

6
nc -l 8000

โดยที่ 8000 คือหมายเลขพอร์ต หากพอร์ตว่างจะเริ่มต้นเซิร์ฟเวอร์ที่คุณสามารถปิดได้อย่างง่ายดาย หากไม่ใช่จะเป็นการโยนข้อผิดพลาด:

nc: Address already in use

5

ฉันต้องการตรวจสอบว่าพอร์ตเปิดอยู่บนหนึ่งในเซิร์ฟเวอร์ทดสอบ linux ของเราหรือไม่ ฉันสามารถทำได้โดยพยายามเชื่อมต่อกับ telnet จากเครื่อง dev ของฉันไปยังเซิร์ฟเวอร์ทดสอบ ในเครื่องที่คุณพยายามที่จะเรียกใช้:

$ telnet test2.host.com 8080
Trying 05.066.137.184...
Connected to test2.host.com

ในตัวอย่างนี้ฉันต้องการตรวจสอบว่าพอร์ต8080เปิดอยู่บนโฮสต์test2.host.com หรือไม่


1

tcpingเป็นเครื่องมือที่ยอดเยี่ยมที่มีค่าใช้จ่ายต่ำมากนอกจากนี้ยังมีอาร์กิวเมนต์การหมดเวลาเพื่อให้เร็วขึ้น:

[root@centos_f831dfb3 ~]# tcping 10.86.151.175 22 -t 1
10.86.151.175 port 22 open.
[root@centos_f831dfb3 ~]# tcping 10.86.150.194 22 -t 1
10.86.150.194 port 22 user timeout.
[root@centos_f831dfb3 ~]# tcping 1.1.1.1 22 -t 1
1.1.1.1 port 22 closed.

1
ไม่แน่ใจว่าการติดตั้ง tcping นั้นคุ้มค่าเมื่อโซลูชันของ Spencer ไม่ต้องการการติดตั้งเพิ่มเติม แต่นี่เป็นวิธีการแก้ปัญหาที่สะอาดและมนุษย์อ่านได้มากที่สุด
bdombro

1

คุณสามารถใช้คำสั่ง netcat ได้เช่นกัน

[location of netcat]/netcat -zv [ip] [port]

หรือ

nc -zv [ip] [port]

-z - ตั้งค่า nc ให้สแกนหา daemons โดยไม่ต้องส่งข้อมูลใด ๆ
-v - เปิดใช้งานโหมด verbose


-2

nmapเป็นเครื่องมือที่เหมาะสม เพียงใช้nmap example.com -p 80

คุณสามารถใช้จากเซิร์ฟเวอร์ภายในหรือระยะไกล นอกจากนี้ยังช่วยให้คุณระบุว่าไฟร์วอลล์กำลังบล็อกการเข้าถึง


-4

หากคุณใช้ iptables ให้ลอง:

iptables -nL

หรือ

iptables -nL | grep 445

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