nc — 任意の TCP および UDP 接続とリスン
概要
nc [-46bCDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl] [-m minttl] [-O length]
[-P proxy_username] [-p source_port] [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable]
[-W recvlimit] [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]] [destination] [port]
説明
nc (または netcat) ユーティリティは、TCP、UDP、または Unix ドメインソケットに関連するあらゆる処理に使用できます。TCP 接続を開いたり、UDP パケットを送信したり、任意の TCP および UDP ポートでリッスンしたり、ポートスキャンを実行したり、IPv4 と IPv6 の両方を処理したりできます。telnet(1) とは異なり、nc はスクリプトに適しており、エラーメッセージを標準出力に送信するのではなく、標準エラーに出力します。
一般的な使用例には、以下のようなものがあります。
シンプルな TCP プロキシ
シェルスクリプトベースの HTTP クライアントとサーバー
ネットワークデーモンのテスト
[ssh]({filename}../../ssh)(1) の SOCKS または HTTP ProxyCommand
その他多数
オプションは次のとおりです。
-4 IPv4 アドレスのみを使用します。
-6 IPv6 アドレスのみを使用します。
-b ブロードキャストを許可します。
-C CRLF を行末文字として送信します。入力データ内の各改行 (LF) 文字は、ソケットに書き込む前に CR+LF に変換されます。すでにキャリッジリターン (CR) で始まる改行文字は変換されません。受信データには影響しません。
-D ソケットでデバッグを有効にします。
-d stdin からの読み込みを試みません。
-F 最初に接続されたソケットを sendmsg(2) を使用して stdout に渡し、終了します。これは、nc がプロキシを使用して接続を設定し、残りの接続を別のプログラムに委ねる場合 (例: [ssh]({filename}../../ssh)(1) で ssh_config(5) の ProxyUseFdpass オプションを使用する場合) に役立ちます。-U と共に使用することはできません。
-h nc のヘルプテキストを表示して終了します。
-I length
TCP 受信バッファーのサイズを指定します。
-i interval
送信および受信するテキスト行の間隔を秒単位で指定します。また、複数のポートに接続する場合にも、遅延時間を設けます。
-k 接続が完了すると、別の接続をリッスンします。-l と共に使用する必要があります。-u オプションと組み合わせて使用すると、サーバーソケットは接続されず、複数のホストから UDP データグラムを受信できます。
-l リモートホストへの接続を開始するのではなく、着信接続をリッスンします。
リッスンする宛先とポートは、オプション引数として、または -s および -p オプションを使用してそれぞれ指定できます。-x または -z と共に使用することはできません。さらに、-w オプションで指定されたタイムアウトはすべて無視されます。
-M ttl 送信パケットのTTL/ホップ制限を設定します。
-m minttl
TTL/ホップ制限がminttl未満の受信パケットを破棄するようにカーネルに要求します。
-N 入力のEOF後にネットワークソケットを[シャットダウン]({filename}../../shutdown)(2)します。一部のサーバーでは、これを実行して処理を完了する必要があります。
-n ドメイン名解決を実行しません。DNSなしで名前を解決できない場合、エラーが報告されます。
-O length
TCP送信バッファのサイズを指定します。
-P proxy_username
認証が必要なプロキシサーバーに提示するユーザー名を指定します。ユーザー名が指定されていない場合、認証は行われません。プロキシ認証は、現時点ではHTTP CONNECTプロキシでのみサポートされています。
-p source_port
ncが使用する送信元ポートを指定します。ただし、権限の制限と可用性に左右されます。
-q seconds
stdinのEOF後、指定された秒数待機してから終了します。秒数が負の場合、永久に待機します(デフォルト)。非負の秒数を指定すると、-Nが暗示されます。
-r 範囲内で順番に、またはシステムが割り当てる順に送信元ポートと/または宛先ポートをランダムに選択する代わりに、ランダムに選択します。
-S RFC 2385 TCP MD5署名オプションを有効にします。
-s sourceaddr
パケットを送信する送信元アドレスを設定します。複数のインターフェイスを持つマシンで役立ちます。Unixドメインデータグラムソケットの場合、一時的なローカルソケットファイルを作成して使用するように指定し、データグラムを受信できるようにします。-xと一緒に使用することはできません。
-T keyword
IPv4 TOS/IPv6トラフィッククラス値を変更します。keywordは、critical、inetcontrol、lowcost、lowdelay、netcontrol、throughput、reliabilityのいずれか、またはDiffServコードポイントのいずれか(ef、af11...af43、cs0...cs7)、または10進数または16進数の数値にすることができます。
-t RFC 854 DOとWILLリクエストに対して、RFC 854 DON'TとWON'T応答を送信します。これにより、ncを使用してtelnetセッションをスクリプト化できます。
-U Unixドメインソケットを使用します。-Fまたは-xと一緒に使用することはできません。Linuxでは、名前がアットマーク(@)で始まる場合、抽象ネームスペースソケットとして扱われます。先頭の@は、バインドまたは接続する前にNULLバイトに置き換えられます。詳細はunix(7)を参照してください。
-u TCPの代わりにUDPを使用します。-xと一緒に使用することはできません。Unixドメインソケットの場合、ストリームソケットの代わりにデータグラムソケットを使用します。Unixドメインソケットが使用される場合、-sフラグが指定されていない限り、一時的な受信ソケットは/tmpに作成されます。
-V rtable
使用するルーティングテーブルを設定します。
-v より詳細な出力を生成します。
-W recvlimit
ネットワークからrecvlimit個のパケットを受信した後、終了します。
-w timeout
接続を確立できない場合、またはアイドル状態の接続は、timeout秒後にタイムアウトします。-wフラグは、-lオプションには影響しません。つまり、ncは、-wフラグの有無にかかわらず、接続を永久にリッスンします。デフォルトではタイムアウトはありません。
-X proxy_protocol
プロキシサーバーと通信するときに proxy_protocol を使用します。サポートされているプロトコルは、4(SOCKS 4、4A(SOCKS v.4A)、5(SOCKS v.5)、および connect(HTTPS プロキシ)です。プロトコルが指定されていない場合、SOCKS バージョン 5 が使用されます。SOCKS v.4 プロトコルは非常に制限されており、宛先ホストを IPv4 アドレスに解決できる場合にのみ使用できることに注意してください。他のプロトコルは、宛先を文字列としてリモートプロキシに渡して解釈させるため、この制限はありません。
-x proxy_address[:port]
proxy_address とポートで指定されたプロキシを使用して、宛先への接続を行います。ポートが指定されていない場合、プロキシプロトコルの既知のポート(SOCKS の場合は 1080、HTTPS の場合は 3128)が使用されます。IPv6 アドレスは、proxy_address を角括弧で囲むことで明確に指定できます。プロキシは、-lsuU のいずれかのオプションで使用できません。
-Z DCCP モード。
-z リスニングデーモンのみをスキャンし、デーモンにデータを送信しません。-l と一緒に使用することはできません。
destination は、数値 IP アドレスまたはシンボリックホスト名にすることができます(ただし、-n オプションが指定されている場合は除きます)。一般に、宛先は指定する必要がありますが、-l オプションが指定されている場合はローカルホストが使用されます。Unix ドメインソケットの場合、宛先は接続するソケットパス(または -l オプションが指定されている場合はリスニングするソケットパス)です。
port は、数値ポート番号またはサービス名として指定できます。ポート範囲は、nn-mm の形式の数値ポート番号として指定できます。一般に、宛先ポートは指定する必要がありますが、-U オプションが指定されている場合は指定する必要はありません。一部のオプションでは、値 0 はシステムにポート番号を選択させることを要求します。
クライアント/サーバーモデル
nc を使用して、非常に基本的なクライアント/サーバーモデルを簡単に構築できます。一方のコンソールで、特定のポートで接続をリッスンするように nc を起動します。たとえば、次のようにします。
$ nc -l 1234
nc は現在、ポート 1234 で接続をリッスンしています。別のコンソール(または別のマシン)で、リッスンしているマシンとポートに接続します。
$ nc -N 127.0.0.1 1234
これで、両方のポート間に接続が確立されます。一方のコンソールで入力した内容は、他方のコンソールに連結され、その逆も同様です。接続が確立されると、nc はどちらの側が「サーバー」として、どちらの側が「クライアント」として使用されているかをあまり気にしません。接続は、EOF('^D')を使用して終了できます。-N フラグが指定されているためです。
この netcat には、-c または -e オプションはありませんが、ファイル記述子をリダイレクトすることで、接続が確立された後にコマンドを実行することはできます。ポートを開いて、任意の人がサイトで任意のコマンドを実行できるようにすることは危険です。どうしてもこれを行う必要がある場合は、次の例を参照してください。
「サーバー」側:
$ rm -f /tmp/f; mkfifo /tmp/f
$ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
「クライアント」側:
$ nc host.example.com 1234
$ (shell prompt from host.example.com)
これを行うと、/tmp/f に FIFO を作成し、nc がアドレス 127.0.0.1 のポート 1234 でリッスンするようにします。 「サーバー」側で「クライアント」がそのポートへの接続に成功すると、/bin/sh が「サーバー」側で実行され、シェルプロンプトが「クライアント」側に与えられます。
接続が終了すると、nc も終了します。-k オプションを使用すると、nc はリッスンを継続しますが、コマンドが終了すると、このオプションは nc を再起動または実行し続けないことに注意してください。また、不要になった場合は、ファイル記述子を削除することを忘れないでください。
$ rm -f /tmp/f
データ転送
前のセクションの例を拡張して、基本的なデータ転送モデルを構築できます。
一方の接続の端に送信された情報は、もう一方の端に出力され、入力と出力を簡単にキャプチャして、ファイル転送をエミュレートできます。
まず、特定のポートでリッスンするように nc を使用し、出力をファイルにキャプチャします。
$ nc -l 1234 > filename.out
別のマシンで、リッスンしている nc プロセスに接続し、転送するファイルを送信します。
$ nc -N host.example.com 1234 < filename.in
ファイルが転送されると、接続は自動的に閉じます。
サーバーとの通信
ユーザーインターフェイスを介さずにサーバーと「手動で」通信することは、場合によっては役立つことがあります。
これは、クライアントから送信されたコマンドに対してサーバーが送信するデータを検証する必要がある場合に、トラブルシューティングに役立つ場合があります。たとえば、Web サイトのホームページを取得するには、次のようにします。
$ printf "GET / HTTP/1.0\r\n\r\n" | nc host.example.com 80
これにより、Web サーバーによって送信されるヘッダーも表示されます。必要に応じて、sed(1) などのツールを使用して、これらをフィルタリングできます。
ユーザーがサーバーに必要なリクエストの形式を知っている場合、さらに複雑な例を作成できます。別の例として、SMTP サーバーに電子メールを送信するには、次のようにします。
$ nc [-C] localhost 25 << EOF
HELO host.example.com
MAIL FROM:<_>
RCPT TO:<_>
DATA
Body of email. . QUIT EOF
ポートスキャン
ターゲットマシンのどのポートが開いていて、サービスが実行されているかを知ることが役立つ場合があります。
-z フラグを使用して、nc に接続を開始するのではなく、開いているポートを報告するように指示できます。通常、これは -v オプションと組み合わせて使用すると、標準エラー出力で詳細な出力をオンにすることが役立ちます。
たとえば、次のようにします。
$ nc -zv host.example.com 20-30
Connection to host.example.com 22 port [tcp/ssh] succeeded! Connection to host.example.com 25 port [tcp/smtp] succeeded!
ポート範囲は、検索をポート 20 ~ 30 に制限するために指定され、昇順でスキャンされます(-r フラグが設定されていない場合)。
ポートのリストを指定することもできます。たとえば、次のようにします。
$ nc -zv host.example.com http 20 22-23
nc: connect to host.example.com 80 (tcp) failed: Connection refused
nc: connect to host.example.com 20 (tcp) failed: Connection refused
Connection to host.example.com port [tcp/ssh] succeeded! nc: connect to host.example.com 23 (tcp) failed: Connection refused
ポートは、指定された順にスキャンされます(-r フラグが設定されている場合を除く)。
あるいは、実行されているサーバーソフトウェアとバージョンを知っておくと役立つ場合があります。 この情報は、多くの場合、挨拶バナーに含まれています。 これを取得するには、最初に接続を作成し、バナーが取得されたら接続を中断する必要があります。 これは、-w フラグで短いタイムアウトを指定するか、サーバーに「QUIT」コマンドを発行することで実現できます。
$ echo "QUIT" | nc host.example.com 20-30
SSH-1.99-OpenSSH_3.6.1p2
プロトコルが一致しません。
220host.example.com IMS SMTP Receiver Version 0.84 Ready
例
host.example.com のポート 42 に TCP 接続を開き、ソースポートとして 31337 を使用し、タイムアウトを 5 秒に設定します。
$ nc -p 31337 -w 5 host.example.com 42
host.example.com のポート 53 に UDP 接続を開きます。
$ nc -u host.example.com 53
host.example.com のポート 42 に TCP 接続を開き、ローカル端の接続の IP アドレスとして 10.1.2.3 を使用します。
$ nc -s 10.1.2.3 host.example.com 42
Unix ドメインストリームソケットを作成し、リッスンします。
$ nc -lU /var/tmp/dsocket
10.2.3.4 のポート 8080 にある HTTP プロキシを介して host.example.com のポート 42 に接続します。 この例は ssh(1) でも使用できます。詳細については、ssh_config(5) の ProxyCommand ディレクティブを参照してください。
$ nc -x10.2.3.4:8080 -Xconnect host.example.com 42
同じ例をもう一度示します。今回は、プロキシが認証を必要とする場合に、ユーザー名「ruser」でプロキシ認証を有効にします。
$ nc -x10.2.3.4:8080 -Xconnect -Pruser host.example.com 42
関連項目
著者
元の実装は *Hobbit* <_> による。 IPv6 サポートを追加して Eric Jackson <_> が書き直した。 Debian ポート用に Aron Xu ⟨_⟩ が修正。
注意点
-uz フラグの組み合わせを使用して UDP ポートをスキャンすると、ターゲットマシンの状態に関係なく、常に成功と報告されます。 ただし、ターゲットマシンまたは中間デバイスでトラフィックスニッファーを使用すると、-uz の組み合わせは、通信の診断に役立つ場合があります。 UDP トラフィックの量は、ハードウェアリソースまたは構成設定によって制限される場合があります。