Uzak bir sistemdeki bir bağlantı noktasına ulaşılabilir olup olmadığını test edin (telnet olmadan)


353

Eski günlerde, telnetuzaktaki bir ana bilgisayardaki bir bağlantı noktasının açık olup olmadığını görürüz: telnet hostname portherhangi bir ana bilgisayardaki herhangi bir bağlantı noktasına bağlanmaya çalışır ve ham TCP akışına erişmenizi sağlar.

Bu günlerde, üzerinde çalıştığım sistemler telnet yüklü değil (güvenlik nedeniyle) ve tüm ana bilgisayarlara giden tüm bağlantılar varsayılan olarak engelleniyor. Zamanla, hangi bağlantı noktalarının hangi ana bilgisayara açık olduğunu kaybetmek kolaydır.

Uzak bir sistemdeki bir bağlantı noktasının açık olup olmadığını test etmek için başka bir yol var mı - sınırlı sayıda paket kurulu olan ve kullanılamayan bir Linux sistemi kullanıyor telnetmusunuz?



Ben de aynı sorunu yaşıyordum. @Subhranath Chunder tarafından verilen cevap yardımcı oldu. Ancak Telnet'i kurmanın küçük bir sorun olduğunu öğrendim brew install telnet. Bu yüzden Linux kullanıcıları için de aynısını yapabilirsiniz bekliyoruz yumve apt-get.
Mig82

Yanıtlar:


277

Bash bir süredir TCP ve UDP portlarına erişebildi . Man sayfasından:

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

Böylece böyle bir şey kullanabilirsiniz:

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

Taa Daa!


Bu da MinGW’de işe yarıyor . Örneğin , 192.168.2.100'deki bir uzak VNC sunucusu, "cat </dev/tcp/192.168.2.100/5900" kullanılarak "RFB 003.008" ile yanıt verir.
Peter Mortensen,

1
@lornix, tamam, ama bu durumda -z seçeneği olmayan nc kullanımıyla aynı sonucu almalıyım, ancak hala çalışmıyor: # nc -v -w5 127.0.0.1 18080 127.0.0.1 18080 portuna bağlantı [tcp / *] başarılı oldu! # cat </dev/tcp/127.0.0.1/18080 Sadece sonuçsuz kilitleniyor. Sadece "/ dev / tcp / host / port" seçeneğini ne zaman kullanabileceğimi anlamak istiyorum
Alexandr

5
@Alexandr ... aslında, "herhangi bir sonuç olmadan kilitleniyor" oldukça fazla beklenen davranış. kedi girişi bekliyor. nc bekleyen hiçbir veriyi algılamasını sağlamak için ekstra akıllılara sahiptir ve denemeyi durdurur. Kedi değil oldukça akıllı. Deneyin cat < /dev/tcp/localhost/22, sshd başlığınızı almalısınız. Açıkçası, 18080 numaralı bağlantı noktasındaki işleminiz, herhangi bir şey göndermeden önce bir şeyin gelmesini bekler. Bağlantı Noktası 22 ( ssh ) sizi sürümüyle karşılıyor. Denemek!
lornix

1
@lornix, açıklama için çok teşekkür ederim! Şimdi kısıtlama açıktır. Bence nc kullanarak portları kontrol etmenin tercih edilen bir yolu olmalı.
Alexandr,

2
Bu, hiçbir şey yüklü olmayan bir liman işçisi konteyneriyle çalışırken inanılmaz derecede yardımcı oldu. Konteynerin konteynersiz DB'ye DNS üzerinden erişimi olduğunu hızlı bir şekilde doğrulayabildim. Örnek: cat </ dev / tcp / hostname / 5432
Michael Hobbs

404

Güzel ve ayrıntılı! Erkek sayfalarından.
Tek liman:

nc -zv 127.0.0.1 80

Birden çok bağlantı noktası:

nc -zv 127.0.0.1 22 80 8080

Port aralığı:

nc -zv 127.0.0.1 20-30

6
En iyi cevap gibi görünüyor, teşekkürler. ;-)
lpapp

6
Bu , uzak bir sunucu için Ubuntu 14.04'te (Trusty Tahr) (aynı LAN) kapalı portlar için (127 saniyeden sonra zaman aşımına uğradı) denendiğinde askıya alındı ​​- bu yüzden komut dosyalarına pek uygun değil. Yine de limanı açık olan bir servis için işe yaradı. "-W2" seçeneğinin kullanılması çözüm olabilir.
Peter Mortensen

6
UDP bağlantı noktaları için -u seçeneğini kullanın.
Efren

8
Ncat -z 6.4 sürümünde tanınmıyor. Z
smishra

5
Birden fazla aralığı aşağıdakilerle kontrol edebilirsiniz: nc -zv 127.0.0.1 22,80,8080,20-30,443-446(nc Sürüm: 1.107-4).
bobbel

102

Netcat yararlı bir araçtır:

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

Will çıkış 0portu 123 açıktır ve eğer 1kapalı eğer.


Bu benimkinden çok daha zarif ve yazılabilir bir cevap. Benim için talihli güvenlikli bilinçli sistem yöneticilerinin telnetde nc(tuhaf - olmasa curlda wget) vazgeçmiş olmaları benim için talihsiz bir durumdur .
Steve HHH

Evet bu tamamen keyfi ve saçma.
diz

3
Let FORifadeleri başlar!
Chad Harrison,

1
Bu , uzaktaki bir sunucu için (aynı LAN) Ubuntu 14.04'te (Trusty Tahr) kapalı portlar için denendiğinde (yaklaşık 127 saniye sonra zaman aşımına uğradı) askıya alındı, bu yüzden komut dosyalarında çok uygun değil. Bağlantı noktası açık olan ve 0 döndüren bir hizmet için işe yaradı. "-W2" seçeneğinin kullanılması çözüm olabilir.
Peter Mortensen

1
-G 2TCP zaman aşımı için daha uygun olacağını düşünüyorum
AB

58

En basit yöntem, örneğin, başka bir araç kullanmadan, socatyukarıda @ lornix'in cevabında açıklandığı gibidir. Bu, /dev/tcp/...başka bir sunucunun komut satırından erişilebilen belirli bir bağlantı noktası olup olmadığını sınamak istemeniz durumunda , birinin Bash içindeki psuedo cihazını nasıl kullanacağına dair gerçek bir örnek eklemek içindir .

Örnekler

Diyelim ki ağımda adında bir ana bilgisayar var 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/...Parantez içindeki parantezleri böyle sarmak istemenin nedeni , (echo > /dev/...)eğer yapmazsanız, o zaman bağlantıların kesilip test edilmediğini görüyorsunuz.

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

Bunlar /dev/nullcihaza veri yazma girişiminden geldikleri için yönlendirilemezler /dev/tcp. Böylece, bir alt komut içindeki tüm çıktıları yakalarız, yani alt komutun (...cmds...)çıktısını yeniden yönlendiririz.


Bu mükemmel. En üste oylanmasını diliyorum. Bunu sayfanın hemen ilerisinde okudum çünkü yanlışlıkla kapatmadan önce kaydırdım.
Still.Tony

@ Okuma.Tony - Evet, her zaman Q'ların birçok yanıtı olan bir sorun var 8-). Yine de geri bildirim için teşekkür ederiz.
slm

46

Bunun curlişi benzer şekilde yapabileceğini telnetve curlhatta dinleyicinin beklediği protokolü söyleyeceğini buldum .

İlk argüman olarak ana bilgisayar adından ve bağlantı noktasından bir HTTP URI oluşturun curl. Eğer curlbağlanabilir (dinleyici, bir web hizmeti değilse), bir protokol uyumsuzluğu ve çıkış bildirir. Eğer curlbağlanamaz, bu zaman aşımına uğrar.

Örneğin, 10.0.0.99 ana bilgisayarındaki 5672 numaralı bağlantı noktası güvenlik duvarı tarafından kapatılıyor veya engelleniyor:

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

Ancak, farklı bir sistemden, 10.0.0.99 ana bilgisayarındaki 5672 numaralı bağlantı noktasına ulaşılabilir ve bir AMQP dinleyicisi çalışıyor gibi görünüyor.

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

Farklı mesajları birbirinden ayırmak önemlidir: ilk başarısızlık, curlbağlantı noktasına bağlanamamasıydı. İkinci başarısızlık, curlbir AMQP dinleyicisi yerine bir HTTP dinleyicisi olması beklenen bir başarı testidir .


5
Kıvrılma müsait değilse, wget olabilir. wget -qS -O- http://ip.add.re.ss:portEtkili aynı şeyi yapmalı.
19:13

4
Bu bile eskiden bir hostname ile çalışır. curl myhost:22.
바이 바

Bu yanlış olabilir. Çalışan bir tomcat hizmeti alıyorum ama 404 hata alıyorum. # curl -k 192.168.194.4:6443 <html><head> <title> Apache Tomcat / 7.0.34 - Hata raporu </title> <style> <! - H1 --- HR {color: # 525D76;} -> </style> </head><body> <h1> HTTP Durumu 404 - / </h1> <HR size = "1" noshade = "noshade"> <p> <b> türü </b> Durum raporu </p> <p> <b> ileti </b> <u>/</u></p><p> <b> açıklama </b> <u> İstenen kaynak mevcut değil. </u> </p> <HR size = "1" noshade = "noshade"> <h3> Apache Tomcat / 7.0.34 </h3> </body> </html>

Benim Bkz yazı benzer bir yaklaşımla.
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!

Umarım bu sorunu çözer :)


1
Evet, bu daha iyi - kapalı portlar için neredeyse hemen zaman aşımı.
Peter Mortensen

1
Bu her zaman TCP kullanıyor mu, yoksa UDP'yi kontrol etmenin bir yolu var mı?
kmoe


6

Bir gün boyunca mücadele ediyordum çünkü bu cevapların hiçbiri benim için işe yaramaz gibi görünüyordu. Sorun şu ki, en yeni sürüm ncartık -zbayrağa sahip değil, ancak TCP yoluyla doğrudan erişim (@lornix ve @slm'ye göre), ana bilgisayara erişilemediğinde başarısız oluyor. Sonunda bu sayfayı buldum , sonunda bir değil iki çalışma örneği buldum :

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

    ( -wbayrak zaman aşımına </dev/nullbakar ve -zbayrağın yerini alır )

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

    ( timeoutkomut zaman aşımına bakar ve gerisi @slm'dendir)

Sonra sonucu çıkarmak için basitçe &&ve / veya ||(veya hatta $?) kullanın. Umarım, birileri bu bilgileri yararlı bulacaktır.


4

@Kenorb ve @Azukikuru'dan gelen cevapları birleştirerek portu açık / kapalı / güvenlik duvarı test edebilirsiniz.

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

Herhangi bir limana ulaşmak için curl ile bir başka yaklaşım

curl telnet://127.0.0.1:22

3

Sisteminizde kurulu olanlara bağlı olarak yöntemlerden birini seçecek bir işlev:

# 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

Kutunuzda bulunmamalıdır, ancak deneyin nmap.


4
nmapiyi bir araçtır, ancak bu sistemlerde mevcut değildir. İndirmek nmap, derlemek, ana dizine yüklemek, daha sonra diğer tüm sistemlere kopyalamak yerine, çoğu Linux kurulumunda mevcut araçları kullanarak bir yol bulmayı umuyordum.
Steve HHH

1

başvuru için, @peperunas'ın cevabını genişleterek:

Test etmek için nmap kullanmanın yolu :

nmap -p 22 127.0.0.1

(yukarıdaki örnek, gösteri amacıyla localhost kullanır)


0

Sistemden daha fazla test etmek istiyorsanız, bu tür görevler için dda-serverpec ( https://github.com/DomainDrivenArchitecture/dda-serverspec-crate ) test aracımızı kullanabilirsiniz . Beklentinizi tanımlayabilirsiniz

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

ve bu beklentiyi localhost'a veya uzak ana bilgisayarlara karşı test edin (ssh ile bağlanın). Uzaktan testler için bir hedef tanımlamanız gerekir:

{: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"}}

İle testi yapabilirsiniz java -jar dda-serverspec.jar --targets targets.edn serverspec.edn

Kaputun altında, yukarıda anlatıldığı gibi netcat kullanıyoruz ...

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.