linux – リモートシステムのポートが到達可能かどうかをテストする (telnet なし)

linux networking port

昔は、リモートホストのポートが開いているかどうかを調べるために telnet を使っていました。telnet hostname port は、どのホストのどのポートにも接続しようとし、生の TCP ストリームにアクセスできるようにしていました

最近では、私が仕事をしているシステムにはtelnetがインストールされておらず(セキュリティ上の理由から)、すべてのホストへのすべてのアウトバウンド接続がデフォルトでブロックされています。時間が経つにつれて、どのホストにどのポートが開いているかを見失うことは簡単です

リモートシステム上のポートが開いているかどうかをテストする別の方法はありますか?Linuxシステムを使用して、限られた数のパッケージがインストールされていて、telnetが利用できない場合に?

  399  None  2013-07-19


ベストアンサー

Bashはしばらくの間、TCPUDPのポートにアクセスできるようになりました。マンページから

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

321  lornix  2013-07-22


饒舌でナイス!男のページから。 シングルポート

nc -zv 127.0.0.1 80

Multiple ports:

nc -zv 127.0.0.1 22 80 8080

ポートの範囲

nc -zv 127.0.0.1 20-30

450  Subhranath Chunder  2013-12-03


Netcatは便利なツールです

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

123番ポートが開いていれば0、閉じていれば1を出力します

106  thnee  2013-07-19


socat のような他のツールを使わない最も簡単な方法は、上の @lornix の回答にあるような方法です。これは、例えば、他のサーバがコマンドラインからアクセス可能なポートを持っているかどうかをテストしたい場合に、Bash 内の psuedo-device /dev/tcp/... をどのように利用するかの実例を追加したものです

Examples

ネットワーク上に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/tcp/skinner/223) && echo hi
bash: connect: Connection refused
bash: /dev/tcp/skinner/223: Connection refused

これらはデバイス /dev/tcp にデータを書き出そうとしているので、単純に /dev/null にリダイレクトすることはできません。そこで、これらの出力をすべてサブコマンド、つまり (...cmds...) の中に取り込み、サブコマンドの出力をリダイレクトします

65  slm  2014-09-02


curltelnet と似たような方法で仕事をしてくれるかもしれないし、curl はリスナーがどのプロトコルを期待しているかまで教えてくれることがわかりました

curlの第一引数としてホスト名とポートからHTTP URIを構築します。curl が接続できた場合、プロトコルの不一致を報告して終了します (リスナーがウェブサービスでない場合)。curl が接続できない場合はタイムアウトする

例えば、ホスト10.0.0.0.99のポート5672は、ファイアウォールによって閉じられているか、ブロックされています

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

しかし、別のシステムからは、ホスト10.0.0.99のポート5672に到達することができ、AMQPリスナーを実行しているように見えます

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

最初の失敗は、curlがポートに接続できなかったためです。curl は AMQP リスナーではなく HTTP リスナーを期待していましたが、2 番目の失敗は成功テストです

49  Steve HHH  2013-07-19


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

それがあなたの問題を解決することを願っています。)

13  Mohammad Shahid Siddiqui  2015-06-02


ワンライナーです

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

@lornix の回答 で説明されている Bash 構文を使用しています

詳細については、チェックしてみてください。Advanced Bash-Scripting Guide.第29章を参照してください。/dev/proc を参照してください

11  kenorb  2016-03-16


これらの回答のどれも私には効きそうになかったので、丸一日苦戦していました。問題は、ncの最新バージョンでは-zフラグがなくなっており、TCP経由での直接アクセスは(@lornixと@slmによると)ホストに到達できない場合に失敗するということです。結局、このページを見つけましたが、そこには1つではなく2つの動作例がありました

  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 から)

そして、単純に && および/または || (あるいは $?) を使って結果を抽出します。うまくいけば、誰かがこの情報を役に立つと思ってくれることを願っています

8  Azukikuru  2017-05-31


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

7  Miguel Ferreira  2018-08-10


ここでは、システムにインストールされているものに応じて、いずれかの方法を選択する機能があります

# 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

4  Robert Boyd  2019-02-12


お使いの箱では使えないはずですが、nmapで試してみてください

2  peperunas  2013-07-19


参考までに、@peperunasさんの回答を拡大します

nmapを使ってテストする方法です

nmap -p 22 127.0.0.1

(上記の例ではデモ用にlocalhostを使用しています)

1  user138278  2019-08-07


システム以上のテストをしなければならない場合は、そのようなタスクのために私たちのテストツール 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"}]}

を定義し、これらの期待値をローカルホストまたはリモートホスト (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でテストを実行してもよい

フードの下では、上記のproprosedとしてnetcatを使用しています

0  jerger  2018-10-26


curlをインストールしている場合

curl -v telnet://$host:$port/$path

0  groo  2020-10-14


タイトルとURLをコピーしました