Uji apakah port pada sistem jarak jauh dapat dijangkau (tanpa telnet)

353

Di masa lalu, kami biasa telnetmelihat apakah port pada host jarak jauh terbuka: telnet hostname portakan mencoba untuk terhubung ke port mana saja pada host apa pun dan memberi Anda akses ke aliran TCP mentah.

Saat ini, sistem yang saya gunakan tidak menginstal telnet (untuk alasan keamanan), dan semua koneksi keluar ke semua host diblokir secara default. Seiring waktu, mudah untuk kehilangan jejak port mana yang terbuka untuk host mana.

Apakah ada cara lain untuk menguji apakah port pada sistem jarak jauh terbuka - menggunakan sistem Linux dengan sejumlah paket yang diinstal, dan telnettidak tersedia?

Steve HHH
sumber
Saya mengalami masalah yang sama. Jawaban oleh @Subhranath Chunder di bawah ini membantu. Namun, saya kemudian mengetahui bahwa menginstal Telnet adalah masalah kecil dalam menjalankannya brew install telnet. Jadi saya berharap pengguna Linux dapat melakukan hal yang sama dengan yumdan apt-get.
Mig82

Jawaban:

277

Bash telah dapat mengakses port TCP dan UDP untuk sementara waktu. Dari halaman manual:

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

Jadi Anda bisa menggunakan sesuatu seperti ini:

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

Taa Daa!

lornix
sumber
Ini sepertinya juga berfungsi di MinGW . Misalnya, server VNC jarak jauh pada 192.168.2.100 merespons dengan "RFB 003.008" dengan menggunakan "cat </dev/tcp/192.168.2.100/5900".
Peter Mortensen
1
@ lornix, ok, tetapi dalam hal ini saya harus mendapatkan hasil yang sama dengan menggunakan nc tanpa opsi -z, tetapi masih tidak berfungsi: # nc -v -w5 127.0.0.1 18080 Koneksi ke 127.0.0.1 18080 port [tcp / *] berhasil! # cat </dev/tcp/127.0.0.1/18080 Hanya hang tanpa hasil. Hanya ingin mengerti kapan saya bisa menggunakan opsi "/ dev / tcp / host / port"
Alexandr
5
@Alexandr ... sebenarnya, "hang tanpa hasil" cukup banyak perilaku yang diharapkan. kucing sedang menunggu input. nc memiliki kecerdasan ekstra untuk memungkinkannya merasakan tidak ada data yang tertunda dan berhenti mencoba. kucing tidak cukup pintar. Coba cat < /dev/tcp/localhost/22, Anda harus mendapatkan sshd header Anda. Jelas, proses Anda pada port 18080 menunggu sesuatu masuk, sebelum mengirim apa pun. Port 22 ( ssh ) menyambut Anda dengan versi itu dan yang lainnya. Cobalah!
lornix
1
@lornix, terima kasih banyak untuk penjelasannya! Sekarang batasannya jelas. Saya pikir menggunakan nc harus menjadi cara yang disukai untuk memeriksa port.
Alexandr
2
Ini sangat membantu ketika bekerja dengan wadah buruh pelabuhan yang tidak menginstal apa pun. Mampu memverifikasi dengan cepat bahwa wadah memiliki akses ke DB non-kemas via DNS. Contoh: cat </ dev / tcp / hostname / 5432
Michael Hobbs
404

Bagus dan bertele-tele! Dari halaman manual.
Port tunggal:

nc -zv 127.0.0.1 80

Beberapa port:

nc -zv 127.0.0.1 22 80 8080

Rentang port:

nc -zv 127.0.0.1 20-30
Subhranath Chunder
sumber
6
Tampaknya ini jawaban terbaik, terima kasih. ;-)
lpapp
6
Ini digantung ketika dicoba di Ubuntu 14.04 (Trusty Tahr) untuk server jarak jauh (LAN yang sama) untuk port yang ditutup (batas waktu setelah 127 detik) - sehingga tidak sangat cocok dalam skrip. Itu berhasil meskipun untuk layanan yang memiliki port terbuka. Menggunakan opsi "-w2" bisa menjadi solusinya.
Peter Mortensen
6
Gunakan opsi -u untuk port UDP.
Efren
8
Pada versi 6.4 dari ncat -z tidak dikenali. Saya dapat melakukannya tanpa z
smishra
5
Anda dapat memeriksa beberapa rentang dengan: nc -zv 127.0.0.1 22,80,8080,20-30,443-446(Versi nc: 1.107-4).
bobbel
102

Netcat adalah alat yang berguna:

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

Akan ditampilkan 0jika port 123 terbuka, dan 1jika ditutup.

lutut
sumber
Ini adalah jawaban yang jauh lebih elegan dan bisa dituliskan daripada jawaban saya sendiri. Sangat disayangkan bagi saya bahwa sysadmin sadar keamanan yang ditahan telnetjuga ditahan nc(meskipun - anehnya - tidak curlatau wget).
Steve HHH
Ya itu sepenuhnya sewenang-wenang dan konyol.
Lutut
3
Biarkan FORpernyataan dimulai!
Chad Harrison
1
Ini digantung ketika dicoba di Ubuntu 14.04 (Trusty Tahr) untuk server jarak jauh (LAN yang sama) untuk port yang ditutup (batas waktu setelah sekitar 127 detik) - sehingga tidak sangat cocok dalam skrip. Itu berhasil meskipun untuk layanan yang memiliki port terbuka, kembali 0. Menggunakan opsi "-w2" bisa menjadi solusi.
Peter Mortensen
1
Saya pikir -G 2akan lebih tepat untuk batas waktu TCP
AB
58

Metode paling sederhana, tanpa menggunakan alat lain, seperti socat, adalah seperti yang dijelaskan dalam jawaban @ lornix di atas. Ini hanya untuk menambahkan contoh aktual tentang bagaimana seseorang menggunakan perangkat psuedo di /dev/tcp/...dalam Bash jika Anda ingin, katakanlah, uji apakah server lain memiliki port tertentu yang dapat diakses melalui baris perintah.

Contohnya

Katakanlah saya memiliki host di jaringan saya yang bernama 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

Alasan Anda ingin membungkus echo > /dev/...dalam tanda kurung seperti ini, (echo > /dev/...)adalah karena jika Anda tidak melakukannya, maka dengan tes koneksi yang menurun, Anda akan mendapatkan jenis pesan ini muncul.

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

Ini tidak bisa hanya diarahkan /dev/nullkarena berasal dari upaya untuk menulis data ke perangkat /dev/tcp. Jadi kami menangkap semua output dalam sub-perintah, yaitu (...cmds...)dan mengarahkan ulang output dari sub-perintah.

slm
sumber
Ini luar biasa. Berharap itu akan dipilih ke atas. Saya hanya membaca ini jauh di bawah halaman karena saya tidak sengaja menggulir sebelum menutupnya.
Masih. Tony
@ Okuma.Tony - ya itu selalu masalah dengan Q yang punya banyak jawaban 8-). Terima kasih atas umpan baliknya, ini sangat dihargai.
slm
46

Saya menemukan bahwa curlmungkin menyelesaikan pekerjaan dengan cara yang sama telnet, dan curlbahkan akan memberi tahu Anda protokol yang diharapkan pendengar.

Bangun HTTP URI dari hostname dan port sebagai argumen pertama curl. Jika curldapat terhubung, itu akan melaporkan ketidakcocokan protokol dan keluar (jika pendengar bukan layanan web). Jika curltidak dapat terhubung, itu akan habis.

Misalnya, port 5672 pada host 10.0.0.99 ditutup atau diblokir oleh firewall:

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

Namun, dari sistem yang berbeda, port 5672 pada host 10.0.0.99 dapat dicapai, dan tampaknya menjalankan pendengar AMQP.

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

Sangat penting untuk membedakan antara pesan yang berbeda: kegagalan pertama adalah karena curltidak dapat terhubung ke port. Kegagalan kedua adalah tes sukses, meskipun curldiharapkan pendengar HTTP bukan pendengar AMQP.

Steve HHH
sumber
5
Jika ikal tidak tersedia, mungkin wget. wget -qS -O- http://ip.add.re.ss:portharus secara efektif melakukan hal yang sama.
CVn
4
Ini bahkan berfungsi dengan nama host, mis. curl myhost:22.
에이 바
Ini mungkin salah. Saya memiliki layanan kucing jantan berjalan, tetapi mendapatkan 404 kesalahan. # curl -k 192.168.194.4:6443 <html><head> <title> Apache Tomcat / 7.0.34 - Laporan kesalahan </title> <style> <! - H1 --- HR {color: # 525D76;} -> </style> </head><body> <h1> Status HTTP 404 - / </h1> <ukuran SDM = "1" noshade = "noshade"> <p> <b> jenis </b> Laporan status </p> <p> <b> pesan </b> <u>/</u></p><p> <b> deskripsi </b> <u> Sumber daya yang diminta tidak tersedia. </u> </p> <HR size = "1" noshade = "noshade"> <h3> Apache Tomcat / 7.0.34 </h3> </body> </html>
Lihat posting saya dengan pendekatan serupa.
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!

Semoga ini bisa menyelesaikan masalah Anda :)

Mohammad Shahid Siddiqui
sumber
1
Ya, ini lebih baik - penghentian waktu segera untuk port tertutup.
Peter Mortensen
1
Apakah ini selalu menggunakan TCP atau apakah ada cara untuk mendapatkannya untuk memeriksa UDP?
kmoe
6

Saya berjuang sepanjang hari karena tidak ada jawaban yang sepertinya cocok untuk saya. Masalahnya adalah bahwa versi terbaru dari nctidak lagi memiliki -zbendera, sedangkan akses langsung melalui TCP (sesuai dengan @lornix dan @slm) gagal ketika tuan rumah tidak dapat dijangkau. Saya akhirnya menemukan halaman ini , di mana saya akhirnya menemukan bukan hanya satu tapi dua contoh yang berfungsi:

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

    ( -wBendera mengurus batas waktu, dan </dev/nullmenggantikan -zbendera)

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

    ( timeoutperintah mengatur timeout, dan sisanya dari @slm)

Kemudian, cukup gunakan &&dan / atau ||(atau bahkan $?) untuk mengekstrak hasilnya. Semoga seseorang akan menemukan informasi ini berguna.

Azukikuru
sumber
4

Menggabungkan jawaban dari @kenorb dan @Aukukikuru Anda dapat menguji port terbuka / tertutup / firewall.

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

Pendekatan lain dengan curl untuk mencapai port apa pun

curl telnet://127.0.0.1:22
Miguel Ferreira
sumber
3

Berikut adalah fungsi yang akan memilih salah satu metode tergantung pada apa yang diinstal pada sistem Anda:

# 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
Robert Boyd
sumber
2

Seharusnya tidak tersedia di kotak Anda, tetapi coba dengan nmap.

peperunas
sumber
4
nmapadalah alat yang baik, tetapi tidak tersedia di sistem ini. Daripada mengunduh nmap, mengompilasinya, menginstalnya ke direktori home saya, lalu menyalinnya ke semua sistem lain, saya berharap menemukan cara menggunakan alat yang ada yang tersedia di sebagian besar instalasi Linux.
Steve HHH
1

untuk referensi, perluas jawaban @peperunas:

cara menggunakan nmap untuk menguji, adalah:

nmap -p 22 127.0.0.1

(contoh di atas menggunakan localhost untuk tujuan demonstrasi)

pengguna138278
sumber
0

Jika Anda telah menguji lebih dari pada sistem Anda dapat menggunakan alat uji kami dda-serverspec ( https://github.com/DomainDrivenArchitecture/dda-serverspec-crate ) untuk tugas-tugas tersebut. Anda dapat menentukan harapan Anda

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

dan uji harapan ini terhadap localhost atau terhadap host jarak jauh (terhubung dengan ssh). Untuk pengujian jarak jauh Anda harus menentukan target:

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

Anda dapat menjalankan tes dengan java -jar dda-serverspec.jar --targets targets.edn serverspec.edn

Di bawah tenda kami menggunakan netcat seperti yang diusulkan di atas ...

Jerger
sumber