昔は、リモートホストのポートが開いているかどうかを調べるために telnet
を使っていました。telnet hostname port
は、どのホストのどのポートにも接続しようとし、生の TCP ストリームにアクセスできるようにしていました
最近では、私が仕事をしているシステムにはtelnetがインストールされておらず(セキュリティ上の理由から)、すべてのホストへのすべてのアウトバウンド接続がデフォルトでブロックされています。時間が経つにつれて、どのホストにどのポートが開いているかを見失うことは簡単です
リモートシステム上のポートが開いているかどうかをテストする別の方法はありますか?Linuxシステムを使用して、限られた数のパッケージがインストールされていて、telnet
が利用できない場合に?
399 None 2013-07-19
Bashはしばらくの間、TCPとUDPのポートにアクセスできるようになりました。マンページから
/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
curl
は telnet
と似たような方法で仕事をしてくれるかもしれないし、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つの動作例がありました
nc -w1 127.0.0.1 22 </dev/null
(
-w
フラグがタイムアウトの処理を行い、</dev/null
が-z
フラグに置き換わる)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