タイトル名の通りのことを今更ながら実感したので、記録を残しておく。
netcat(nc(1))を使って、TCPで簡易的にファイルを転送する方法は2パターンある。ファイルを送る側のコンピュータでlistenする方法と、ファイルを受け取る側のコンピュータでlistenする方法だ。
ファイル送信側がlistenする方法
まず、ファイル送信側にて、netcatでポートをlisten状態で開いておく。この時、送信したいファイルをnetcatにリダイレクトしておく(≒標準入力経由でnetcatに流し込む)。
# ファイル送信側:192.0.2.11 listen_port=10002 nc -l $listen_port <file
次に、ファイル受信側から送信側にnetcatで接続する。送信ファイルの内容が標準出力経由で垂れ流されるので、リダイレクトしてファイルに流し込むようにしておく。
# ファイル受信側:192.0.2.12 target_ip=192.0.2.11 target_port=10002 nc $target_ip $target_port >file
ファイル受信側がlistenする方法
まず、ファイル受信側にて、netcatでポートをlisten状態で開いておく。この時、netcatの標準出力をファイルにリダイレクトしておく(≒標準出力経由で受け取った内容をファイルに書き込む)。
# ファイル受信側:192.0.2.12 listen_port=10002 nc -l $listen_port >file
次に、ファイル送信側からにnetcatで接続する。この時、netcatの標準入力に送信するファイルをリダイレクトしておく(≒送信データを標準入力経由でnetcatに流し込む)。
# ファイル送信側:192.0.2.11受信側 target_ip=192.0.2.12 target_port=10002 nc $target_ip $target_port <file
どちらを使うか?
正直、どちらを使っても問題ない気がする。
ただ、netcatは悪用も可能なツールなので、「可能なら、できる限り『クライアント』マシンとして使いたい」というコンピュータではlistenしないようにした方がよいと思う。
例えば、開発PCがWindowsで、実験用のターゲットPCがMac OS XやLinuxだとする。開発PCからターゲットPCにファイルを転送する場合は「ファイル受信側がlistenする」方法を、その逆の場合は「ファイル送信側がlistenする」方法を使うとよいのではないか?
というのも、Windowsファイアウォールのデフォルト設定では、あるアプリケーションが初めてlisten状態でポートを開こうとした時に、通信を許可するか否かの確認ダイアログが表示される。他のファイアウォール・ソフトでも、同様の機能を持つものは多いはずだ。
netcatは悪用可能なので、できればlisten状態でポートが開かれたことを捕捉できるようにしておいた方がよい。しかしnetcatでlisten状態でポートが開くことが常態化していると、ファイアウォールの設定で許可されているために、意図せぬタイミングでnetcatがlisten状態でポートを開いた際にユーザに何も通知されない可能性がある。まあ、この辺はファイアウォール・ソフトの種類や設定に依存するし、あとnetcatは有名といえば有名なのでプロ仕様(!)のウイルスの類では狙われない*1気もするのだが……。
Windowsにnetcatが入っているのは、正直なところ少々特殊な状況だ。なので、この程度は気を使っておいたほうがよい気がする。気にしすぎかもしれないが。
*1:おそらくもっと別の、より巧妙で気づかれにくい方法を用いるはず。