web-dev-qa-db-ja.com

nc:バインドに失敗しました:アドレスは既に使用されています

スクリプトからncコマンドを実行しようとしています。スクリプトは、同じソースポートを使用して、宛先の異なるポートでncコマンドを実行しています。

例:

nc -p 8140 -z -v -n 10.X.X.9 9090
nc -p 8140 -z -v -n 10.X.X.9 9091
nc -p 8140 -z -v -n 10.X.X.9 9092
nc -p 8140 -z -v -n 10.X.X.9 9093
and so on ...

1回目のncの実行後、残りのすべての行について、以下のエラーメッセージが表示されます。

nc: bind failed: Address already in use
nc: bind failed: Address already in use
nc: bind failed: Address already in use

この状況を回避する方法はありますか?

5
saurav

バックグラウンド

このようにncを使用しようとすると、TCPポートが開いたままになり、宛先が完了した要求の受信を確認するまで待機します。これは強調表示されています。 WikipediaのTCP記事 にあります。

待ち時間

(サーバーまたはクライアントのいずれか)は、リモートが確実に接続するのに十分な時間待機することを表しますTCPは、その接続終了要求の確認応答を受信しました。 MSL(最大セグメントライフタイム)として知られる最大4分間。]

同様にncを使用すると、この影響を確認できます。

$ nc -p 8140 -v -n 192.168.1.105 80

ポート8140の状態を見る:

$ netstat -anpt | grep 8140
tcp        0      0 192.168.1.3:8140       192.168.1.105:80         TIME_WAIT   -

実際、ほとんどのLinuxシステムでは、このTIME_WAITは60秒に設定されています。

$ cat /proc/sys/net/ipv4/tcp_fin_timeout
60

自分で効果を確認したい場合は、このスニペットを使用して、ポートが解放されたときに監視できます。

$ date; nc -p 8140 -v -n 192.168.1.105 80 -w 1; date; \
    while netstat -anpt | grep 8140; do date; sleep 10; done; date
Tue Mar 25 09:46:59 EDT 2014
Connection to 192.168.1.105 80 port [tcp/*] succeeded!
Tue Mar 25 09:47:00 EDT 2014
tcp        0      0 192.168.1.3:8140       192.168.1.105:80        TIME_WAIT   -
Tue Mar 25 09:47:00 EDT 2014
tcp        0      0 192.168.1.3:8140       192.168.1.105:80        TIME_WAIT   -
Tue Mar 25 09:47:10 EDT 2014
tcp        0      0 192.168.1.3:8140       192.168.1.105:80        TIME_WAIT   -
Tue Mar 25 09:47:20 EDT 2014
tcp        0      0 192.168.1.3:8140       192.168.1.105:80        TIME_WAIT   -
Tue Mar 25 09:47:30 EDT 2014
tcp        0      0 192.168.1.3:8140       192.168.1.105:80        TIME_WAIT   -
Tue Mar 25 09:47:40 EDT 2014
tcp        0      0 192.168.1.3:8140       192.168.1.105:80        TIME_WAIT   -
Tue Mar 25 09:47:50 EDT 2014
Tue Mar 25 09:48:00 EDT 2014
$

方法#1-ncを使用する

ポート8140の解放には時間がかかる。あなたはそれが完全に解放されるまで待つ必要があります(その間にいくつかのスリープを置くことは1つの簡単な方法でしょう)または別のポートを使用することによって。

Host @ Hostが開いているかどうかを確認するだけの場合は、-p 8140をドロップするだけです。

$ nc -zv -n 10.X.X.9 9090-9093

$ nc -zv -n 192.168.1.200 2024-50000 |& grep -v refu
Connection to 192.168.1.200 5672 port [tcp/*] succeeded!
Connection to 192.168.1.200 35766 port [tcp/*] succeeded!

注:-wオプションをncに追加して、一定の時間だけ待機するように指示したくなるかもしれません。デフォルトでは、ncは永久に待機します。したがって、コマンドは次のようになります。

$ nc -p 8140 -zv -n 10.X.X.9 9090 -w 1

ただし、1.84を使用するCentOS 5.9システムでの私のテストでは、その後も引き続きポートを使用中のままにしているため、-w 60が有効になるまでの時間が最も短いため、TIME_WAITを使用するのが最善です。

方法#2-nmapを使用する

ポートのセットをスキャンするためにより適切なアプリを使用したい場合は、代わりにnmapを使用することをお勧めします。

$ Sudo nmap -sS --source-port 8140 -p 9090-9093 10.X.X.9

$ Sudo nmap -sS --source-port 8140 -p 80-85 homer

Starting Nmap 6.40 ( http://nmap.org ) at 2014-03-24 21:22 EDT
Nmap scan report for homer (192.168.1.105)
Host is up (0.0059s latency).
PORT   STATE  SERVICE
80/tcp open   http
81/tcp closed hosts2-ns
82/tcp closed xfer
83/tcp closed mit-ml-dev
84/tcp closed ctf
85/tcp closed mit-ml-dev
MAC Address: 00:18:51:43:84:87 (SWsoft)

Nmap done: 1 IP address (1 Host up) scanned in 11.36 seconds

ここでは、iptrafを使用してフィルターをセットアップし、トラフィックが8140のソースポートを使用してこれらのポートに送信されることを証明しています。

注:図の#1に特に注意してください。送信元ポート8140、#2は、私が選択したいくつかの宛先ポート、主に80と83を示しています。

ss #1

参考文献

10
slm

私はそれが答えであるかもしれないと思うので、少なくとも読みやすいです:

i=0 ; until { 
    nc -p 8140 -av -n 10.X.X.9 909${i} &&
        [ $((i=i+1)) -gt 4 ]
} 2>&- 
    do sleep 1 
done

真実は、@ slmはnmap-についてポイントを持っているということです。ネットワークの処理とペンのテストには欠かせないツールです。ただし、5:1ポート構成の2台のマシン間の接続をテストする場合は、少し時間がかかる場合があります。繰り返しになりますが、多分これはそれを使うことを学ぶ絶好の機会です。

とにかく、それを自由に利用できない場合は、netcatは非常に柔軟です。そして、おそらくもっと重要なことは、ncにはsu rootやるべきことi/oと同じように動作するnmap

上記の答えでは$iターゲットポートの最後の桁を0最初のラウンドと$i 'sその後、増分された値。私が信じているように、ローカルポートをバインドできる限り、nctrueを返すはずなので、変数- $iは、8140が開いていて、ncを使用してダイヤルアウトできる場合にのみ増加します。

$iはテストで増分され、9094指定したポート範囲。この時点で最終的にtrueが返され、それによりuntilが満たされ、ループ。

そういえば、untilあなたcan bindローカル8140 -portループはsleep 1秒(@slmが推奨)。再試行する前。

stderr2>&-なので、端末をスパムしているバインドできませんでした...メッセージを見る必要はありません。 sleepが呼び出されるたびに$iも増加します-ループが中断した最後を除いて-反復間の1秒の一時停止は、バインドされたローカルポートを削除し、次の反復で使用するために再び開くのに十分な場合があります。

ncの戻り値とそれを間違ってしまった場合returns falseそれでもcanローカルで8140を保護しますが、ターゲットポートは閉じていますが、これは$?-お知らせください。

1
mikeserv