要約
cat | nc -l ポート番号
であなたもサーバになれますよという話。
#ただしASCIIなプロトコルに限る。
やりたかったこと
「telnetでSMTPサーバに接続して手動でコマンドを送信すると、メールが送れちゃいますよ」みたいなのはよく見かけると思います。
今回はそれの逆、つまり「クライアントからの接続を待ち受けて、手動でそのリクエストに応答できますよ」がやりたかった。
クライアント側のテストをしたいんだけど手頃なサーバがいない!とかに役立つ気がします。
解説
#あえて解説するまでもないですが、、、
netcat(nc -l ポート番号
)で指定したポートでtcp接続を待ち受けることができますが、telnetのように入力を受け付けてくれたりはしません。
ただ、netcatはパイプでつなぐとデータを転送できるので、catで標準入力を受け付けてnetcatに渡すということができました。
タイピング速度=応答速度なのと、同時接続数が1なのが欠点といえば欠点。
おまけ
cat | nc -l 8888 | sed -e 's/^/> /'
とすると、受信文字列の先頭に>
が付与されるのでログを残すときは便利そう。
例
SMTPサーバになる
クライアント側
[admin@localhost ~]$ echo 'Hello!!' | mail -S smtp=smtp://localhost:2525 -s 'subject' -r from@example.com to@example.com
クライアントにはmailxを使いました。
サーバ側
[admin@localhost ~]$ cat | nc -l 2525 | sed -e 's/^/> /'
220 OK
> HELO localhost
250 OK
> MAIL FROM:<from@example.com>
250 OK
> RCPT TO:<to@example.com>
250 OK
> DATA
354 OK
> Date: Sat, 07 Apr 2018 16:31:52 +0900
> From: from@example.com
> To: to@example.com
> Subject: subject
> Message-ID: <xxxxxxxxxxxxxxxxxxxxxxxxx%from@example.com>
> User-Agent: Heirloom mailx 12.5 7/5/10
> MIME-Version: 1.0
> Content-Type: text/plain; charset=us-ascii
> Content-Transfer-Encoding: 7bit
>
> Hello!!
> .
250 OK
> QUIT
221 OK
^C
[admin@localhost ~]$
プロトコルに従ってしこしこリターンコードを入力すると、クライアントとおしゃべりできます。
HTTPサーバになる
クライアント側
サーバ側
[admin@localhost ~]$ cat | nc -l 8888 | sed -e 's/^/> /'
> GET / HTTP/1.1
> Host: localhost:8888
> Connection: keep-alive
> Cache-Control: max-age=0
> Upgrade-Insecure-Requests: 1
> User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
> Accept-Encoding: gzip, deflate, br
> Accept-Language: ja,en-US;q=0.9,en;q=0.8
>
HTTP/1.0 200 OK
Content-Length: 7
Hello!!
^C
[admin@localhost ~]$
プロトコルに従って、しこしこレスポンスを書きます。
注意事項
改行コード
RFCによるとHTTPとかSMTPの改行コードはCR+LFですが、上記の例だとLFのみになってしまっています。
その辺を厳密にやりたいときはCtrl+v
+ Ctrl+m
でCRを入力できるので、エンターをたたく前に入力してあげてください。
[admin@localhost ~]$ cat | nc -l 1234 | sed -e 's/^/> /'
aaa^Mbbb
^M
の部分がCtrl+v
+ Ctrl+m
。
[admin@localhost ~]$ sudo tcpdump -i lo -nn -n -s 0 -X port 1234
[sudo] password for admin:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
17:20:09.955677 IP 127.0.0.1.1234 > 127.0.0.1.39892: Flags [P.], seq 2056111940:2056111948, ack 2448075712, win 342, options [nop,nop,TS val 3384957060 ecr 3384918152], length 8
0x0000: 4500 003c 07cc 4000 4006 34ee 7f00 0001 E..<..@.@.4.....
0x0010: 7f00 0001 04d2 9bd4 7a8d c744 91ea abc0 ........z..D....
0x0020: 8018 0156 fe30 0000 0101 080a c9c2 5884 ...V.0........X.
0x0030: c9c1 c088 6161 610d 6262 620a ....aaa.bbb.
tcpdumpでみると、0x61
(a)と0x62
(b)の間に0x0d
(CR)がいるのがわかる。