昨日、ようやく回避策が見つかったと思って、ホッと
していたのもつかの間…。
いまひとつ、回避が難しい事態に遭遇。
今やっているのは、Raspbianの初期設定に外付けの
パッケージを極力使わず、設定周りも基本的に
弄らず、使用する言語はPython縛りで、CGI経由で
GPIOをオン/オフするって言う実験。
何が難しい事態かというと…
とりあえず昨日までのあらすじ。
apacheを標準でインストールしておいて、/cgi-bin/
に放り込んだPythonのCGIにPCのブラウザからアクセス
して、GPIOに繋いだ3つのLEDを個別にオン/オフする
って言うスクリプトはどう書いたらいいのかで四苦八苦。
Raspberry Pi上のPythonで、押されたボタンをCGIで
入力してhtmlに編集して表示するのも簡単。GPIOに
ぶら下がったLEDをオン/オフするのも簡単。この場合
のGPIOを弄りに行く処理は、標準で入っているGPIO
ライブラリを使用。(ファイル入出力でもいいんだけど)
問題は、GPIOはroot権限じゃないとアクセスできない
ってこと。
apache配下で起動されるCGIのスクリプトは、root
じゃないユーザで実行されるので、CGIは直接GPIO
叩くことが出来ない。
なので、rootを使わなくてもGPIOを叩きにいける
ライブラリか何かをインストールするか、モロモロ
設定を弄って無理やりアクセス出来るようにしちゃうか、
そんな対応が必要。
セキュリティー上、後者はいやだし、出来るだけ
何らかのパッケージには偏りたくないので前者も
避けたい。
とりあえず最初に考えたのは、set user idを
スクリプトのファイル属性につけちゃう方法。
(実行時のユーザが実行者じゃなく、ファイル
所有者…例えばrootで実行できるので)
どうかな?と思ってやってみると…どうやらPython
に限らず、Raspbianでもスクリプトは全般的に
set user idが無効になっているみたい。
まぁ、セキュリティーを考えれば、スクリプトの類を
自動的にroot権限で実行させるのは危険極まりない
のでI(特にCGIなんて)、まぁどのディストリビューション
でも今は実行できないようになってるんだろうな。
Raspberry Piだって一人前のlinux機なんだし。
んで、次に考えたのが、I/O部分だけをCで書くこと。
これならchmodでset user id付けられるし。
…これやっちゃえば簡単なんだけど、色々アレな
事情があるのでひとまず他の方法を探す。
アブナイとされているジャイルブレイクsystem
のコマンド実行をあえて試す。CGIのスクリプト
から外部のスクリプトをsudoで実行させて、
そっちでGPIOの処理を済ますっていう作戦。
当然ながら、スクリプトインジェクション対策
とかそれなりにとった上でのこと。
やってみる…
とりあえず、CGI用のスクリプトをコマンドライン
から実行かけてみると、無事GPIOを叩くスクリプト
がrootで実行されて、LEDを点灯/消灯できること
がわかった。
(実は、パスワード不要なユーザでもsudoをキック
する際に、ttyからの起動じゃない場合はパスワード
入力に失敗してしまうなので、パスワードを標準入力
から食わせる必要があると判って、一苦労)
http://brown.ap.teacup.com/nekosan0/1871.html
昨日はここまで。
んで、今日はその続きから。
いざ、apacheのCGI用ディレクトリ/cgi-bin/に
CGIスクリプトを放り込んでみると…なぜか動かない。
sudoでスイッチさせてるところが上手く行ってない
みたいだなぁ…
コマンドラインではちゃんと動くのに、なんで
CGIで動かすと上手く行かないんだろう?
理由が分らずしばし考え込む。エラーメッセージを
眺める。
…判った。apacheから実行されるスクリプトの
ユーザは「pi」じゃなくて「www-data」だから、
piのパスワードでsudoが掛からないんだな。
うーーーーーーん。suEXECか?Apacheの設定を
色々弄り倒すか? …とか考えたんだけど、
色々調べてたら、Pythonに簡易型のCGIサーバ機能
が入ってて、2~3行のスクリプトを書けば簡単な
CGIサーバが起動できるって判ったので、そっちを
試す。
http://yife.hateblo.jp/entry/2012/01/25/054210
↑ここ参考。
おぉ。なんと簡単な! たった2行。
んで、さんざんApache用に作ってきたCGIスクリプト
をこっちに持ってきてみる。
…ちょっとばかりアレコレあったけど…
とりあえず希望してた機能は一通り盛り込めた。
(return value = の右に何も書いてないのは、
エラーが何も帰ってきてないって印)
機能的には3つのボタンのどれかを押すと、対応する
LEDが1個だけ光るっていうだけの代物。
あぁ、こんな簡単なことなのに、意外に苦戦したな。
CGI本体部分じゃなく、GPIOがroot権限周りだけ
っていう1点で。
セキュリティーホールを作りまくってもいいなら
もっと簡単なのかも知れないけど、いくらなんでも
ある程度は安全にしておかないと、やっぱアブナイ
からなぁ。Raspbianもそういう設計になっている
みたいだし。
でもまぁ、systemのコマンド実行自体が大きな地雷
なんだけどな。
この後、どうするかな…
コイツの穴をふさぐのか、大人しくwiringPiを使うのか、
https://projects.drogon.net/raspberry-pi/wiringpi/
それともwebIOPiか、
http://code.google.com/p/webiopi/
http://www.raspberrypi.org/phpBB3/viewtopic.php?t=15257
もしくは自分でc言語の外部単機能プログラム作って、
chmodでset user idつけるか。
いずれにしても、Pythonのスクリプト中に文字列で
パスワード書いたままにしておくのはイヤだな。
せめて、他の見えにくいディレクトリにテキスト
ファイルで置いておいて、そいつを読み出して使う
方がいいよな。そこだけは必須だな。
なんかの拍子にエラーが起こって、エラー行を
ブラウザに表示しちゃったりしたら怖いからな。
…っていうか、エラーが起きた途端に表示しちゃう
のが今の仕様だからな。
まぁ、何か1個方法が見つかれば、あとは少しずつ
いいものに乗り換えていけばいいか。ってことで
今日はここまで。
|
特にシステム的な制約を設定してはいないはずなので、teacupのシステムの制約に引っかかっているのかもしれません…。
(すみません、詳しい仕様が判りません)
あと、tokoyaさんが行われているような、webカムとの接続周りで一番ラクチンでトラブル無しなのはどれかな…と物色中です。aptで入るのがいいなぁと探してるんですが…。