OpenWrt BB rc3上のuhttpdのCGIが思うように動作しない

後で出てくる横線以下は作業しながら自分用のメモに記録していたもの。それでも後で整理しようと思ったが諦めた。ちなみに”Bad Gateway.”というエラーが最初出ていたが、これは自分のCGIスクリプトの初歩的ミスによるもの。

ポータブル・ルータTP-Link TL-WR703NにOpenWrtを載せているのだが、そのBarrier Breaker (14.07-rc3, r42056)が公開されたのでインストールしてみた。理由は後日。

これには、ルータの各種設定ができるWeb UI (”Luci”と呼ばれている)を提供するため、uhttpdというWebサーバーがプリインストールしてあり、デフォルトでは自動で起動するようになっている。これは別の目的にも利用してきた。うちの玄関にあるIPカメラのアラーム端子に接続されたブザーを押すと、IPカメラはアラーム入力があったと判断し、「アラームサーバー」に通知してくれる。この「アラームサーバーへの通知」は実際には、Webサーバに対して特定のURLをGETすることで行われる。(この辺は以前”Wifiカメラ用偽アラーム・サーバ “書いた。)パスは/api/alarm.asp?… なのだが、OpenWrt上のuhttpdに対してアクセスするようにし、このalarm.aspをuhttpdのCGIスクリプトとして実現し、そのスクリプトで父と自分のAndroid端末に通知するようにしてきた。

ところがBB rc3にアップグレードしてから動かなくなってしまった。

IPカメラから192.168.11.170にあるOpenWrtルーターに対して

GET /api/alarm.asp?username=AAA&userpwd=BBB&rea=2&io=0 HTTP/1.0.

というリクエストが送られるのだが、それに対応するhttp://192.168.11.170/api/alarm.asp?username=AAA&userpwd=BBB&rea=2&io=0というURLをブラウザでアクセスすると、期待された動作をする。

ブラウザから送られた場合は、IPカメラから送られる上のシンプルなリクエストだけではなく、いろいろヘッダが付いている。それが動作の違いの理由かと考え、”cURL – How To Use“を参考にして、余計なヘッダがつかない同じリクエストが送られるよう:

$ curl -H "User-Agent:" -H "Accept:" -H "Host:" -0 -G "http://192.168.11.170/api/alarm.asp?username=AAA&userpwd=BBB&rea=2&io=0"

としてみると、それでも期待された動作をする。

念のためngrepを使い、”ngrep(8): network grep – Linux man page“参照して

ngrep -W byline -q port 80

などとしてルーター上のパケットを眺めてみても、IPカメラからのリクエストと、他のPCからcURLからのそれとの見かけの違いは見当たらない。しかし、uhttpdはなぜか前者に対しては全く反応しない(OKもなし)。

パッと見えない違いとしては、ひょっとしてIPカメラからのGETでは、行末が正しく(CR+LF) x 2 になってないのかと疑ったが、以下を見るとちゃんとなっている模様(ngrepの-xオプションはヘキサ表示を指示するもの。なお、これら実験の過程で、複数の「アラームサーバー」の挙動を比較するため、アラームサーバーのポートをいろいろと換えたので一定していない)。

root@OpenWrt:/www/api# ngrep -x -q port 8081
eth0: no IPv4 address assigned: Cannot assign requested address
interface: eth0
filter: (ip) and ( port 8081 )

T 192.168.11.81:2148 -> 192.168.11.170:8081 [AP]
 47 45 54 20 2f 61 70 69 2f 61 6c 61 72 6d 2e 61 GET /api/alarm.a
 73 70 3f 75 73 65 72 6e 61 6d 65 3d 41 41 41 26 sp?username=AAA&
 75 73 65 72 70 77 64 3d 42 42 42 26 72 65 61 3d userpwd=BBB&rea=
 32 26 69 6f 3d 30 20 48 54 54 50 2f 31 2e 30 0d 2&io=0 HTTP/1.0.
 0a 0d 0a ...

それではWebサーバーをuhttpdではなく何か他のものにしてみればいいのではないかと、”Web Server Overview – OpenWrt Wiki“を参考にmini_httpdを選んでインストール。mini-httpd – OpenWrt Wikiを参考に設定。ところが、mini-httpdだと、1度目はCGIスクリプトが起動されるがその後成功しない。2度目以降も、スクリプトにあるtelnetコマンドで端末に接続はするようなのだが、Android端末側(SSH Serverアプリ)でError shell: sendto failed: EPIPE (Broken Pipe)というエラーを吐いていて、肝心の通信は行われない模様。ちなみに、Luciはmini-httpdでも動くのだが、uhttpdで動かす場合に比べると目に見えて遅い。

もうやけになって、netcatに影響を受けて作られたとするNcatを使い、なんちゃってWebサーバーを作ってごまかすことにした。”ncat(1) – Linux manual page“や”Neat Tricks“を参考にして、以下を/etc/rc.localに含めることでスタートアップ時に実行されるようにした。

/usr/bin/ncat --recv-only -lk -p 8081 --sh-exec "awk '/^GET/ {system(\"/www/api/alarm.asp 2>&1 > /dev/null\")}'" &

IPカメラからは1回の通知につきGET文と空行の2行が送られてくるので、Awkで前者にだけ(本来はCGI用だった)スクリプトが起動されるようにした。

本当はパスをしっかり確認するなどもっときちんと処理すべきなんだろうが、実際上はこれで問題はない。ともかく安定して動いてくれることが大事。それは達成できたと思う。


T 192.168.11.81:2097 -> 192.168.11.170:80 [AP]
GET /api/alarm.asp?username=AAA&userpwd=BBB&rea=2&io=0 HTTP/1.0.
.


T 0.0.0.0 -> 0.0.0.0
...........................
Y...........

T 192.168.11.63:49276 -> 192.168.11.170:80 [A]
......

T 192.168.11.63:49276 -> 192.168.11.170:80 [AP]
GET /api/alarm.asp?username=AAA&userpwd=BBB&rea=2&io=0 HTTP/1.1.
User-Agent: curl/7.37.0.
Host: 192.168.11.170.
Accept: */*.
.


T 192.168.11.170:80 -> 192.168.11.63:49276 [AP]
HTTP/1.1 502 Bad Gateway.
Connection: Keep-Alive.
Transfer-Encoding: chunked.


T 192.168.11.63:49276 -> 192.168.11.170:80 [A]
......

T 192.168.11.170:80 -> 192.168.11.63:49276 [AP]
Keep-Alive: timeout=20.
Content-Type: text/html.
.
14.

Bad Gateway

. 28. The process did not produce any response. 0. .

cURL – How To Use

$ curl -H "User-Agent:" -H "Accept:" -H "Host:" -0 -G "http://192.168.11.170/api/alarm.asp?username=AAA&userpwd=BBB&rea=2&io=0"

Bad Gateway

The process did not produce any response

T 192.168.11.63:50248 -> 192.168.11.170:80 [AP]
GET /api/alarm.asp?username=AAA&userpwd=BBB&rea=2&io=0 HTTP/1.0.
.


T 192.168.11.170:80 -> 192.168.11.63:50248 [AP]
HTTP/1.0 502 Bad Gateway.
Connection: close.


T 192.168.11.170:80 -> 192.168.11.63:50248 [AFP]
Content-Type: text/html.
.

Bad Gateway

The process did not produce any response

Web Server Overview – OpenWrt Wiki

mini_httpd

mini-httpd – OpenWrt Wiki

mini-httpdを使っていると以下のような不審な交信が起こってて気持ち悪い。

T 192.168.11.1:1304 -> 192.168.11.170:80 [R]
......

T 192.168.11.170:80 -> 192.168.11.1:1308 [AP]
(null) 400 Bad Request.
Server: mini_httpd/1.19 19dec2003.
Date: Mon, 18 Aug 2014 08:06:44 GMT.
Cache-Control: no-cache,no-store.
Content-Type: text/html; charset=%s.
Connection: close.
.
<HTML>
<HEAD><TITLE>400 Bad Request</TITLE></HEAD>
<BODY BGCOLOR="#cc9999" TEXT="#000000" LINK="#2020ff" VLINK="#4040cc">
<H4>400 Bad Request</H4>
Can't parse request.
<HR>
<ADDRESS><A HREF="http://www.acme.com/software/mini_httpd/">mini_httpd/1.19 19dec2003</A></ADDRESS>
</BODY>
</HTML>

ncat -lkC -p 8081 –sh-exec “/www/api/alarm.asp 2>&1 > /dev/null”

Cオプションは行末文字をサーバが期待するCRLFに変更するもの。”ncat(1) – Linux manual page” “Neat Tricks

広告

OpenWrt BB rc3上のuhttpdのCGIが思うように動作しない」への3件のフィードバック

  1. ピンバック: TP-Link TL-WR703NのOpenWrtをBarrier Breaker RC3にアップグレード | あくまで暫定措置としてのブログ
  2. ピンバック: 自宅内LANの整理 | あくまで暫定措置としてのブログ
  3. ピンバック: OpenWrt導入済みルータにUSBオーディオアダプタを介してスピーカ接続 | あくまで暫定措置としてのブログ

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中