Linux'ta bir bağlantı noktasının açık olup olmadığını etkili bir şekilde test edin?


197

Bir bash betiğinden, bir bağlantı noktasının 445sunucuda açık / dinleme olup olmadığını nasıl hızlı bir şekilde öğrenebilirim .

Birkaç seçenek denedim, ama hızlı bir şey istiyorum:
1. lsof -i :445 (Saniye sürer)
2. netstat -an |grep 445 |grep LISTEN(Saniye sürer)
3. telnet(geri dönmez)
4. nmap, netcatsunucuda mevcut değildir

İlk önce numaralandırılmayan ve ondan sonra açılan bir yol bilmek güzel olacaktır.


1
Netcat mevcut mu? Hızlı bir başarısızlık yolu IIRC'ye sahiptir. netcat.sourceforge.net
JimR

5
netstat -lnt(olan -tve olmayan -a) çıkışı yalnızca dinleme TCP bağlantılarıyla sınırlar. Biraz hızlanabilir. -4IPv4 için yalnızca IPv6'ya ihtiyacınız yoksa ekleyebilirsiniz .
Bartosz Moczulski

lsof -i kişisel bir favoridir.
Matt Joyce

14
netstat -an | grep PORTNUMBER | grep -i listenÇıktı boşsa, bağlantı noktası kullanımda değildir.
otomatik

Sizin için neden lsofyavaş olduğunu bilmiyorum , ancak normalde listelediğiniz çözümlerin en iyisi. Sizin netstatçözüm çok güvenilir değil (kullandığınız zaman bunu tahmin edebilirsiniz grep; yine de birileri ör 4450 dinleyen true döndürür). telnetve netcataslında her zaman istediğiniz gibi olmayabilecek bir bağlantı oluşturmaya çalışın.
petersohn

Yanıtlar:


155

Son zamanlarda öğrendiğim bir sürpriz, Bash'in yerel olarak tcp bağlantılarını dosya tanıtıcıları olarak desteklemesi . Kullanmak:

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

Dosya tanımlayıcı olarak 6 kullanıyorum çünkü 0,1,2, stdin, stdout ve stderr. 5 bazen tarafından kullanılır Bash tarafından çocuk süreçleri için , bu nedenle 3,4,6,7,8 ve 9 güvenli olmalıdır.

Aşağıdaki açıklamaya göre, bir komut dosyasında yerel bir sunucuyu dinlemeyi test etmek için :

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

Birinin dinleyip dinlemediğini belirlemek için geridöngü ile bağlanmayı deneyin. Başarısız olursa, bağlantı noktası kapatılır veya erişime izin verilmez. Ardından bağlantıyı kapatın.

E-posta gönderme, hata durumunda komut dosyasından çıkma veya gerekli hizmeti başlatma gibi kullanım durumunuz için bunu değiştirin.


2
Bu benim için asıldı.
Aman Jain

@AmanJain kedi EOF veya Ctrl-C'nin çıkmasını bekler. Protokolünüz için bunu ayarlamanız gerekir. BTW bunu uzak bir sunucuya mı çalıştırıyorsunuz?
Spencer Rathbun

Bağlantı noktası kontrol kodunu /etc/init.d/ altında sunucudaki bir komut dosyasına gömmek istiyorum
Aman Jain

@AmanJain Yerel bir sistem için güncelledim. Sadece doğru dinleyip dinlemediğini kontrol etmek mi istiyorsun? Http yoluyla bir sayfa istemek gibi herhangi bir protokol kontrolü yoktur?
Spencer Rathbun

1
Değil tüm OS (örneğin ubuntu 16 bugün gördüğüm kadarıyla) oluşturmak için derlenmiş bash ile sevk edilir çünkü bu güvenilir bir yöntem değildir /dev/tcp/IP/PORTağaç
dyasny

107

Burada "hızlı cevap" ile çok kısa: Shell komut dosyasından uzak TCP bağlantı noktasının açılıp açılmadığı nasıl sınanır?

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

127.0.0.1 ile "uzak" adres olarak kullanıyorum.

bağlantı noktası açıksa "0" ve bağlantı noktası kapalı ise "1" döndürür

Örneğin

nc -z 127.0.0.1 80; echo $?

-z nc'nin, onlara herhangi bir veri göndermeden yalnızca dinleyen cinleri taraması gerektiğini belirtir. Bu seçeneği -l seçeneğiyle birlikte kullanmak bir hatadır.


2
Bu en kolay yol gibi görünüyor, teşekkürler. Örnek komut dosyası bağlantısı artık çalışmıyor, ancak yine de kendi kendini açıklıyor.
derFunk

Güzel! Bu, birçok bağlantı noktası açık olan bir sunucudaki diğer yanıtlardan çok daha hızlıdır. Netstat / lsof 1s + alırken benim için <0.01 saniye içinde döner
Tim

2
Vb Fedora, CentOS, (nmap-NCAT-6.01-9.fc18.x86_64): -z bayrağı En son dağıtımlar ile birlikte gelen nmap dayalı NCAT mevcut değildir
Zack

9
Sezgisel olarak, port açıksa "0" ve kapalıysa "1" değerini döndürür.
Sean

3
@Sean unix komutları genellikle başarıyı göstermek için '0' döndürür ve başarısızlık için sıfırdan farklıdır. Yani '0', başarılı bir şekilde bağlandığını ve sıfırdan farklı bir nedenle bağlanmadığını gösterir. Bununla birlikte, bazı 'nc' sürümlerinin '-z' argümanını desteklemediğini unutmayın, bu nedenle stackoverflow.com/a/25793128/6773916 muhtemelen daha iyi bir çözümdür.
Zengin Sedman

89

Çok daha hızlı sonuçlar için netstat'ı şu şekilde kullanabilirsiniz:

Linux'ta:

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

Mac'te:

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

Bu, bağlantı noktasını dinleyen işlemlerin bir listesini çıkarır (bu örnekte 445) veya bağlantı noktası boşsa hiçbir şey çıktılamaz.


1
netstat sözdiziminiz yanlış. netstat -ln --tcp çalışıyor, ancak yine de yavaş
Aman Jain

6
Aslında doğru sözdizimi ama muhtemelen Linux kullanıyorsunuz ve ben Mac'teyim. Linux için bunu kullanın:netstat -lnt | awk '$6 == "LISTEN" && $4 ~ ".445"'
anubhava

21
bu hiçbir şey çıktı.
Jürgen Paul

1
Soru linux ile ilgiliydi, belki de yorum cevapta olmalı.
UpTheCreek

1
Bağlantı noktası 80'i kontrol etmek için kullanmam gerekiyordu awk '$6 == "LISTEN" && $4 ~ "80$"'. Bağlantı noktası numarasından önceki noktayı kontrol etmek yerine, \.80kullandım 80$. Aksi takdirde, bu aynı zamanda .80ile başlayan ve 80gibi bağlantı noktaları ile eşleşti 8000.
Patrick Oscity

37

Bunun için netcat'i kullanabilirsiniz.

nc ip port < /dev/null

sunucuya bağlanır ve doğrudan bağlantıyı tekrar kapatır. Netcat bağlanamazsa, sıfırdan farklı bir çıkış kodu döndürür. Çıkış kodu $? Değişkeninde saklanır. Örnek olarak,

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

yalnızca netcat bağlantı noktasına başarıyla bağlanabiliyorsa 0 döndürecektir.


1
Bu cevap için daha fazla oy gerekiyor. nc bu durumda mükemmel çalışır. / dev / tcp hile zekidir, ancak sinyal kesintileri olan bir komut dosyası uygulamak zor görünmektedir.
Avindra Goolcharan

5
nc-zbu amaçla bayrağa sahiptir, bu da girdi almayı gerektirmez /dev/null. -zYukarıdaki bayrağı kullanarak bir yanıt zaten var .
Abe Voelker

2
@AbeVoelker nc'nin tüm sürümleri -z bayrağını desteklemez. CentOS 7'deyim ve Tony'nin çözümünü ihtiyacım olan şey olarak buldum.
Shadoninja

@Shadoninja Bilmek güzel! 2014'teki yorumumdan çıkmazlığı düzenleyebilseydim yapardım.
Abe Voelker

'nc' artık '-z'yi desteklemiyor ve bu nedenle bu cevap en iyi çözüm gibi görünüyor.
Zengin Sedman

18

Spencer Rathbun'un bash kullanarak verdiği cevaba dayanarak:

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

Güzel, "Bağlantı Reddedildi" mesajını bastıracak. Hizmet sonsuza kadar beklemeden bağlantıyı kabul ederse otomatik olarak kapanır.
Seff

Yeni bir bağlantıdan sonra veri göndermeyen hizmetler için en iyi çözüm. Netcat'i aramaktan yaklaşık 20 kat daha hızlı. : &>/dev/null </dev/tcp/127.0.0.1/$PORT
20'de ens

16

/ proc / net / tcp içinde listelenir.

":" ifadesinin ardından onaltılı sayıdaki ikinci sütundur.

> 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üçüncü sütundakilerden biri stackoverflow olmalıdır sanırım : o)

bak man 5 procdaha fazla ayrıntı için. ve sed vb. ile ayırmak, nazik okuyucu için bir egzersiz olarak kalır ...


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

2ms yeterince hızlı mı?

İki nokta üst üste ekleyin ve bu Linux'ta çalışır


2
Harika olan, ssdaha da hızlıdır nc. liçindir dinleme , 4IPv4 içindir; sport(tabii ki) kaynak portu anlamına gelir . Yukarıdaki komut, dinleyen bir TCP bağlantı noktası ( tseçenek) olduğunu varsayar : uUDP'ler için seçeneği kullanın veya her iki protokol için bunların hiçbirini kullanmayın . Nixcraft hakkındass her zaman olduğu gibi daha fazla bilgi . NOT: filtreler burada çalışmıyor, neden bilmiyorum (bash 4.3.11, ss yardımcı programı, iproute2-ss131122), grep ile gitmek zorunda . ss
Campa

Bu sskomut çok kötü , bulguyu yansıtan bir çıkış kodu döndürmüyor; her zaman 0 çıkış kodu döndürür.
John Greene

| grep LISTEN?
Leucos

Anladım State Recv-Q Send-Q Local Address:Port Peer Address:Portve şimdi mi? Ne anlama geliyor?
Siyah

6

Hem Mac hem de Linux için çalışan bir tanesi:

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

Sanırım güvenli bir şekilde kaldırabilirsiniz [\\.\:].
Patrick Oscity

6
nc -l 8000

Burada 8000 bağlantı noktası numarasıdır. Bağlantı noktası boşsa, kolayca kapatabileceğiniz bir sunucu başlatacaktır. Değilse bir hata atar:

nc: Address already in use

5

Linux test sunucularımızdan birinde bir portun açık olup olmadığını kontrol etmek istedim. Bunu, dev makinemden test sunucusuna telnet ile bağlanmaya çalışarak başardım. Dev makinede çalıştırmak için deneyin:

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

Bu örnekte test2.host.com ana bilgisayarında 8080 numaralı bağlantı noktasının açık olup olmadığını kontrol etmek istiyorum


1

tcping , çok düşük bir ek yüke sahip harika bir araçtır.Ayrıca daha hızlı hale getirmek için bir zaman aşımı argümanı vardır:

[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
Spencer'ın çözümü ekstra kurulum gerektirmediğinde tcping'in kurulmaya değer olduğundan emin değilim, ancak bu en temiz ve en okunabilir çözümdür.
bdombro

1

Netcat komutunu da kullanabilirsiniz

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

veya

nc -zv [ip] [port]

-z - nc'yi gerçekte herhangi bir veri göndermeden, basitçe dinleyen cinleri tarayacak şekilde ayarlar.
-v - ayrıntılı modu etkinleştirir.


-2

nmapdoğru araçtır. Basitçe kullanınnmap example.com -p 80

Yerel veya uzak sunucudan kullanabilirsiniz. Ayrıca, bir güvenlik duvarının erişimi engelleyip engellemediğini belirlemenize yardımcı olur.


-4

İptables kullanıyorsanız deneyin:

iptables -nL

veya

iptables -nL | grep 445

bu sadece açık portlarla hiçbir korelasyonu olmayan iptables kurallarını listeler.
David Goodwin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.