Linuxでポートが開いているかどうかを効率的にテストしますか?


197

bashスクリプトから、ポート445がサーバー上で開いているか、リッスンしているかどうかをすばやく確認するにはどうすればよいですか。

私はいくつかのオプションを試しましたが、簡単なものが欲しいです:
1. lsof -i :445 (数秒かかります)
2. netstat -an |grep 445 |grep LISTEN(数秒かかります)
3. telnet(戻りません)
4. nmapnetcatサーバーで使用できません

最初に列挙せず、その後に歩む方法を知っておくといいでしょう。


1
netcatは利用できますか?高速フェイルパスIIRCがあります。 netcat.sourceforge.net
JimR

5
netstat -lnt(あり-t、なし-a)では、リスニングTCP接続のみに出力が制限されます。少しスピードアップするかもしれません。-4IPv6が必要ない場合にのみ、IPv4 を追加できます。
Bartosz Moczulski 2012年

lsof -iは個人的なお気に入りです。
Matt Joyce、

14
netstat -an | grep PORTNUMBER | grep -i listen出力が空の場合、ポートは使用されていません。
オートマティック

なぜlsofあなたにとって遅いのかはわかりませんが、通常はあなたが挙げたソリューションの中で最高です。あなたのnetstat解決策はあまり信頼できません(あなたが使うときはいつでもそれを推測できますgrep;とにかく誰かが例えば4450で聞いているならそれはtrueを返します)。telnetそして、netcat実際に接続を作成しようとしますが、それが常に希望するものであるとは限りません。
petersohn 2015

回答:


155

私が最近発見した驚きは、Bashがtcp接続をファイル記述子としてネイティブでサポートしていることです。使用するには:

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

0、1、2はstdin、stdout、およびstderrであるため、ファイル記述子として6を使用しています。5はBashによって子プロセスに使用されることがあるので、3、4、6、7、8、9は安全です。

以下のコメントのとおり、スクリプトでローカルサーバーのリッスンをテストするには:

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

誰かが聞いているかどうかを確認するには、ループバックで接続してみます。失敗した場合、ポートが閉じているか、アクセスが許可されていません。その後、接続を閉じます。

電子メールの送信、失敗した場合のスクリプトの終了、必要なサービスの開始などの使用例に合わせてこれを変更します。


2
これはちょうど私のために絞首刑にされました。
Aman Jain

@AmanJain猫はEOFまたはCtrl-Cが終了するのを待ちます。これをプロトコルに合わせて調整する必要があります。ところで、これをリモートサーバーに対して実行していますか?
Spencer Rathbun 2012年

/etc/init.d/の下のサーバー上のスクリプトにポートチェックコードを埋め込みたい
Aman Jain

@AmanJainローカルシステム用に更新しました。あなたはそれが正しく聞いているかどうかを確認したいだけですか?http経由でページをリクエストするなどのプロトコルチェックはありませんか?
Spencer Rathbun 2012年

1
すべてのOS(たとえば、今日発見したubuntu 16)が/dev/tcp/IP/PORTツリー構築用にコンパイルされたbashで出荷されるわけではないため、これは信頼できる方法ではありません
dyasny

107

ここに「速い答え」と非常に短いがあります:リモートTCPポートがシェルスクリプトから開かれているかどうかをテストする方法は?

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

「リモート」アドレスとして127.0.0.1を使用しています。

これは、ポートが開いている場合は「0」を返し、ポートが閉じている場合は「1」を返します。

例えば

nc -z 127.0.0.1 80; echo $?

-z ncがデータを送信せずに、待機しているデーモンをスキャンすることを指定します。このオプションを-lオプションと組み合わせて使用​​すると、エラーになります。


2
これが最も簡単な方法のようです。サンプルスクリプトリンクはもう機能していませんが、それでもとにかく自明です。
derFunk、2015年

いいね!これは、多くのポートが開いているサーバーでの他の回答よりもはるかに高速です。netstat / lsofが1秒以上かかる間、0.01秒未満で戻ります
Tim

2
-zフラグは、最新のディストリビューションに同梱されているnmapベースのncatでは使用できません:Fedora、Centosなど(nmap-ncat-6.01-9.fc18.x86_64)
Zack

9
直観に反して、これはポートが開いている場合は「0」を返し、ポートが閉じている場合は「1」を返します。
Sean

3
@Sean unixコマンドは通常、成功を示すために「0」を返し、失敗に対してはゼロ以外を返します。したがって、「0」は接続に成功したことを示し、ゼロ以外は何らかの理由で接続しなかったことを示します。ただし、「nc」の一部のバージョンは「-z」引数をサポートしていないため、stackoverflow.com / a / 25793128/6773916の方が間違いなく優れたソリューションであることに注意してください。
リッチセドマン2017

89

この方法でnetstatを使用すると、より高速な結果が得られます。

Linuxの場合:

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

Macの場合:

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

これは、ポート(この例では445)でリッスンしているプロセスのリストを出力するか、ポートが空いている場合は何も出力しません。


1
netstat構文が正しくありません。netstat -ln --tcpは動作しますが、まだ遅い
Aman Jain

6
実際には正しい構文ですが、おそらくLinuxを使用していて、Macを使用しています。Linuxは、使用については、この:netstat -lnt | awk '$6 == "LISTEN" && $4 ~ ".445"'
anubhava

21
これは何も出力しませんでした。
ユルゲンポール

1
質問はLinuxに関するものだったので、おそらくコメントが答えにあるはずです。
UpTheCreek 2013

1
ポート80を確認するには、を使用する必要がありましたawk '$6 == "LISTEN" && $4 ~ "80$"'。でポート番号の前のドットをチェックする代わりに\.80、私はを使用しました80$。それ以外の場合、これはなどので.80始まるおよびを含むIPアドレスにも一致し80ました8000
Patrick Oscity 14

37

これにはnetcatを使用できます。

nc ip port < /dev/null

サーバーに接続し、再び接続を直接閉じます。netcatが接続できない場合は、ゼロ以外の終了コードを返します。終了コードは変数$?に格納されます。例として、

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

netcatがポートに正常に接続できた場合にのみ、0を返します。


1
この回答にはもっと賛成票が必要です。この場合、ncは完全に機能します。/ dev / tcpのトリックは巧妙ですが、シグナル割り込みを使用したスクリプトを実装するのは難しいようです。
Avindra Goolcharan、2014年

5
nc-zこの目的のためのフラグがあり、からの入力を必要としません/dev/null-z上記のフラグを使用した答えはすでにあります。
Abe Voelker、2014年

2
@AbeVoelker ncのすべてのバージョンが-zフラグをサポートしているわけではありません。私はCentOS 7を使用していて、Tonyのソリューションが必要なものであることがわかりました。
Shadoninja

@Shadoninja知っておきたい!2014年のコメントから軽薄さを編集できたら、編集します。
Abe Voelker 16

「nc」は「-z」をサポートしなくなったため、この回答が最良の解決策のようです。
リッチセドマン2017

18

Spencer Rathbunの回答に基づいて、bashを使用します。

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

良い、それは「接続拒否」メッセージを抑制します。サービスが永遠に待機することなく接続を受け入れる場合、自動終了します。
Seff

新しい接続後にデータを送信しないサービスに最適なソリューション。netcatを呼び出すよりも約20倍高速です。短縮可能: &>/dev/null </dev/tcp/127.0.0.1/$PORT
ens

16

それらは/ proc / net / tcpにリストされています。

これは、 ":"の後の2番目の列(16進数)です。

> 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は3列目のそれらの1つがstackoverflowでなければならないと思います:o)

man 5 proc詳細を確認してください。そして、セッドなどでそれを分けることは、穏やかな読者のための練習として残されます...


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

2msは十分速いですか?

コロンを追加すると、これはLinuxで機能します


2
素晴らしいものは、ssよりもはるかに速いですncl以下のためであるリスニング4IPv4のためのものです。sport(もちろん)送信元ポートを意味します。上記のコマンドは、リスニングTCPポート(tオプション)を想定していますu。UDPのオプションを使用するか、両方のプロトコルでそれらのいずれも使用しないでください。詳細はss、いつものようにNixcraft。注:ssフィルターはここでは機能しません。理由(bash 4.3.11、ssユーティリティー、iproute2-ss131122)がgrepで実行する必要がある理由がわかりません。
Campa 2015

このssコマンドは、その結果を反映した終了コードを返しません。常に0の終了コードを返します。
ジョングリーン

| grep LISTEN
ロイコス2018年

ええState Recv-Q Send-Q Local Address:Port Peer Address:Port、今?これは何を意味するのでしょうか?
ブラック


6
nc -l 8000

ここで、8000はポート番号です。ポートが空いている場合は、簡単に閉じることができるサーバーを起動します。そうでない場合は、エラーがスローされます。

nc: Address already in use

5

Linuxテストサーバーの1つでポートが開いているかどうかを確認したいと思いました。私の開発マシンからテストサーバーにtelnetで接続することで、これを行うことができました。あなたの開発マシンで実行してみてください:

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

この例では、ホストtest2.host.comでポート8080が開いているかどうかを確認します


1

tcpingは、オーバーヘッドが非常に少ない優れたツールです。また、タイムアウトを引数にして高速化します。

[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のソリューションが追加のインストールを必要としない場合、tcpingをインストールする価値があるかどうかはわかりませんが、これは最もクリーンで人間が読めるソリューションです。
bdombro

1

netcatコマンドも使用できます

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

または

nc -zv [ip] [port]

-z –実際にデータを送信せずに、listenデーモンをスキャンするようにncを設定します。
-v –詳細モードを有効にします。


-2

nmap正しいツールです。単に使うnmap example.com -p 80

ローカルサーバーまたはリモートサーバーから使用できます。また、ファイアウォールがアクセスをブロックしているかどうかを識別するのにも役立ちます。


-4

iptablesを使用している場合:

iptables -nL

または

iptables -nL | grep 445

これは、iptablesルールをリストするだけです...開いているポートとは相関がない場合があります。
デビッドグッドウィン2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.