序
かなり高い頻度でこの話はしていると思っていたのだが、ChienomiではLinux的にWindowsをバックアップしてみる, 誤家庭のLinuxで大規模ストレージを取り扱う, 新品コンピュータを初期状態に戻せるようにバックアップ, 2000-2005年ころのLinuxとインターネットとパソコンと4回登場しているものの、これ自体を解説した記事がなかったので、書いておく。
これは、概要としては、 “Bashではリダイレクトの特殊な構文としてTCP/UDPによる通信が可能である” ということである。
構文
command > /dev/tcp/host/portまず、前提として述べておくが、 あくまでCONNECTだけでLISTENはできない。
hostは名前解決の対象になる。
また、仮に全二重でネットワーク接続したとしても、リダイレクトの構文として読み戻すことができないので、あくまでもBashからCONNECTしたら一方的に書き込むか読み出すかのどちらかしかできない。
例
例えばホストserverで次のようにして待ち受ける。
socat -u TCP-LISTEN:10000 STDOUTホストclientから次のようにする。
echo 'Hello, world!' > /dev/tcp/server/10000これを利用して、ファイルを転送できる。サーバー側
socat -u TCP-LISTEN:10000 CREATE:somefileクライアント側
cat somefile > /dev/tcp/server/10000ファイル群の転送も可能である。サーバー側
socat -u TCP-LISTEN:10000 STDOUT | tar xvf -クライアント側
tar cvf - . > /dev/tcp/server/10000あくまでCONNECTであるというだけであり、読み出し側になれないという意味ではない。 だから、Bashのほうでファイルを受け取るようなことも可能だ。 サーバー側
tar cvf - . | socat -u STDIN TCP-LISTEN:10000クライアント側
tar xvf < /dev/tcp/server/10000もう少し解説
実際に/dev/tcpや/dev/udpというファイルがあるわけではなく、Bashであっても例えば
cat /dev/tcp/server/10000のようにしても普通にエラーになる。
これは、あくまで「リダイレクト先として/dev/tcpや/dev/udpが指定されたときに、Bashが特別な扱いとしてネットワーク通信をする」という仕組みである。
なお、同じようなものとして/dev/fd/n, /dev/stdin, /dev/stdout, /dev/stderrという仮想ファイルが用意されている。UNIXドメインソケットには対応していない。
nc(netcat)とsocat
nc(netcat)は昔からあるネットワーク通信プログラムである。 標準入出力を使ってTCP/UDP/UNIX domain Socketでの通信を行うことができる。
socatはより汎用性を高めた現代的なプログラムである。ファイルデスクリプタ, TCP, UDP, ソケットのほか、ファイル、SCTP, 名前付きパイプ, コマンド, PTY, OpenSSL/TCP/IP, SOCKS4/5などもサポートしており、これらを自由につなぐことができる。HTTPプロキシ経由の接続も可能だ。
以前はnetcatがデフォルトで入っていることが多くて、とりあえずnetcatは使えるケースが多かったのだが、最近のディストリビューションはnetcatも入っていないことが多く、一方socatもnetcatも公式パッケージとして存在することが多いようだ。
このため、使うのであればsocatのほうがお勧めではある。 netcatにまつわる面倒な要素もないし。
ヒント
通信における片側がBashさえあれば良い、ということで、ライブCDなどでブートしてそのままファイル転送に使うことができる。
古いコンピュータなどにおいて古いライブディストリビューションを利用してネットワークファイル転送を行ったり、Windowsでは転送しづらいファイルをWindowsオフラインでバックアップしたい場合などにLinuxによるライブブートで転送するといったことが簡単にできる。
また、netcatやsocatの入っていないLinux環境からネットワーク接続をテストしたり、仮想マシンのホスト/ゲスト間で通信したりするのにも便利。