- ベストアンサー
sudoでシェルスクリプトを実行させたい
/usr/bin/sudo を使って、xxx.shを実行させたいので、設定でxxx.shを許可しました。 その後Apacheで動くCGI(perlスクリプト)から、``を使って実行させようと考えています。 このときにこのxxx.shがうまく動きません。多分シェルにアクセスできないのだと思いますが、どうしたらこのスクリプトをroot権限で動かす事ができるようになるのでしょうか。関係あるかどうかわかりませんが、xxx.shの中身はディレクトリ作成コマンドなどです。ネットで検索したら、シェルスクリプトだけ許可にすればよいとあったのですが・・。セキュリティ的には/bin/shを許可するのはまずそうな気がするのですが、こちらを許可してもよいものでしょうか。 環境等 xxx.sh 755 所有者(user1) Apache実行ユーザ (apache) CGIの実行ユーザ(apache?) 挑戦したコマンド(とアパッチのログ) `/usr/bin/sudo sh ./xxx.sh`; ->パスワード求められます (/bin/shの権限がない?) `/usr/bin/sudo ./xxx.sh`; ->/usr/bin/sudo: unable to exec ファイルのパス No such file or directory (xxx.shのファイルの場所はあってます) `/usr/bin/sudo フルパス/xxx.sh`; ->/usr/bin/sudo: unable to exec ファイルのパス No such file or directory (xxx.shのファイルの場所はあってます) 不足の点などあればご指摘ください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
なるほど、UNIXユーザを発行する為のいわば管理用画面を作成したいわけですね。 そうなると、確かにユーザ作成の処理にはroot権限が必要です。 しかし、CGIで起動されたプロセスから直接root権限の必要な処理を行うのはあまりうまくない方法です。私なら登録要求の処理と、実際の登録処理は別々にすると思います。 1)とりあえず簡単な方法 CGIで登録するユーザ情報を入力し、それを「特定のディレクトリ」配下にファイルに落とします。ファイル名は時刻+α等ルール化して重複しないようにします。ポイントは、ひとつのファイルに書き込むような仕様はなるべく避けることです。ファイルのロックコントロールは必要以上に処理を複雑にする傾向があります。 かたや、そのファイルを読み込んで実際のユーザ登録等の処理をするシェルスクリプトを作成します。 これは、その時点で「特定のディレクトリ」配下にあるファイルリストを取得し、一つずつ中身を読み込んで各種コマンドラインを生成し、実行します。 より厳密な処理にするのであれば、登録要求処理完了時に、データファイルの他にロックファイルを作成し、リストを取得する際はそのロックファイルを使います。 登録完了後には、そのデータファイル/ロックファイルともに削除します。 そして、そのシェルスクリプトをrootのCRONに登録して毎分実行すれば、ほぼ1分いないには、ユーザが登録されると言うわけです。 2)どうしても登録要求からのタイムラグが許せない場合 CGI側は同じですが、root権限で動かす登録用のプログラムをデーモン化します。 まあ、PerlやRubyなどでまじめなデーモンを作成するもよし、シェルスクリプトをデーモンもどきとして動かすもよしです。 参考までにこれを・・・ http://okweb.jp/kotaeru.php3?q=230337 http://okweb.jp/kotaeru.php3?q=1059932 処理内容は、1)のシェルと同じ内容でいいでしょう。 もう少し面白い処理にしたいのなら、CGIとデーモンがソケットを使って通信するようにし、ネットワーク越しに登録要求を伝えるようすれば、完全なリアルタイム処理になりますね。ただし、ネットワークデーモンはセキュリティホールを作らないように作るのは結構面倒なので、そこいら辺はやや面倒かもしれません。 リアルタイムな処理にするメリットは、登録完了の通知がそのまま画面に出せることでしょうか。 工夫すれば、他のやり方も画面に完了通知を出すのは不可能じゃないですね。 例えばロックファイルがなくなるのをずっと監視しておくとか。(あまりスマートなやり方じゃないですが) とりあえず、さくっと思いつくのはこんなところですね。 深いこだわりが無いのなら、1)がお勧めですね。動作検証がしやすいし、何か問題が起こっても対処がしやすいです。 一般的に、どのようなプログラムを作る際にも言えることですが、ある目的を達するまでの処理を如何に細かい処理の塊として捕らえられるかは重要なことです。 処理の区切れがはっきりすれば、一つ一つの処理は単純になるし、デバッグも簡単です。 ちょっと長くなりましたが、こんなところでどうでしょうか。
その他の回答 (4)
- odacle
- ベストアンサー率0% (0/2)
cgiプログラムの実行権を変更するには、suexecなどがありますがroot権限で実行できるようにするのはよくありません。(suexecのソースコードにはrootで実行できないようにチェックルーチンがあります。)これは、cgiプログラムに設計ミスがあった場合にどんなコードでも実行ができてしまうからです。 ユーザの追加、削除をブラウザから行いたいのであれば、オープンソースで利用できるものや製品として販売されているものもあります。 オープンソースの代表的なものとして BlueQuartrz(かつてSun Cobaltという商品でした) http://bluequartz.org/ Webmin http://webmin.com/ などがあります。セキュリティの面や機能面からいってもこのようなものを使う方がよいと思います。
お礼
ありがとうございます。実はこのシステムを自分でくみ出す前にそちらの方が早いだろうし、安全かなと思って色々探してみたんです。だけど、散々探してそれこそ6時間とか探しました。それでも見つからないので、組んだ方が早いって事になってしまったんです。そういえばその時2chの掲示板でWebminというのは乗ってましたが、何故か(何を思ったか)Userminの方をいれてしまって、使ったんですけど、なにかしっくりこなかったんですよね。ファイルマネージャー機能などはセキュリティー的にも怖いなとおもいましたので・・使えなくもできるみたいですけど・・。webminでは何が出来るのかそういえばまだ検証してませんでした。もしかしたらやろうとしてる事ができたのでしょうか。。 BlueQuartzの方はちょっと調べてみます。貴重な情報ありがとうございました
補足
貴重な情報をいただいておいて申し訳ないのですが、タイトルの趣旨で次点をつけさせていただきました。すみません
- you-m
- ベストアンサー率58% (190/327)
そもそも何でrootじゃないとできないと思い込んでいるのかが良く分かりません。 rootでないとできないから、rootで実行する方法が知りたいというよりも、これこれこういうことをrootにならずに実現する方法はないかという質問のほうが、何倍も勉強になるし、使いまわしのきくノウハウになると思います。 実行ユーザを変更するというのは、簡単な解決策のように見えるかもしれませんが、分かりにくいトラブルや環境への理解を妨げる大きな要因になります。 具体的に何がしたいのかを説明していただければ、力になれることもあるかもしれませんよ。
お礼
ありがとうございます。そうですね。素人が考えるよりも識者の方にご意見を伺った方がスマートでより正しい解決策がでますよね。 最終目標としては、CGIからユーザを発行できるシステムを組んでみたいんです。 なのでシェルスクリプトの中身は aduser mkdir chmod になってます。ユーザの追加はrootじゃないと駄目かなと気がしたので、がんばってルートでやろうとしてたのですが、他になにかうまい解決策ありますでしょうか ここまで試行錯誤でやってますのでそろそろ作り出してから鈍行20時間くらいもたってますが、骨格が出来てきましたのでこれは出来たら使いたいなと思ってます。 c言語はサンプルがあったので今c言語でラッパー?を組んでみましたが(これ自体は拍子抜けするくらい簡単でした)、setuidしてやってもかえって引数でバッファーオーバーランとかのセキュリティーホールになりそうで怖いのと、何故かそもそもルートで実行されてないトラブルに見舞われてます(汗)前途多難ですね(汗)
- you-m
- ベストアンサー率58% (190/327)
sudoは、インタラクティブに使う前提のコマンドで、バッチ処理から使用するのは難しいです。 また、sudoは/etc/sudoersで許可されたユーザのみが使用することができます。 また、明示的にユーザを指定しない場合、デフォルトではroot権限で動こうとします。 いずれにしても、パスワードの入力を省略することはできないので、必ず認証が発生します。STDINから流し込むことはできますが、いずれにしてもコマンドラインにパスワードが現れることになるでしょう。 一般的に特定のコマンドを特定のユーザ権限で実行したい場合は、chmodを使ってsetuidしておくことで対応します。 passwdや、crontab等がこのような設定になっています。 しかしながら、シェルスクリプトに対してこの操作を行っても無効です。 セキュリティ的にも、決してお勧めできない為、そもそもroot権限が必要な処理そのものを見直す方が先々を考えても建設的だと思います。
お礼
ためになるご回答ありがとうございます。 setuidについてよく分からなかったので調べてみましたが、なるほどこのような方法もあったのですね。でもシェルスクリプトでは使えないとのことですし、本格的なプログラムを作るのは敷居が高そうですので、今回はつかえなさそうですね。 まだまだ私linuxについて勉強中でして、そんな私の考えではroot使わないと出来そうにないんです。本当はroot使わないでも出来るかもしれないですが、目標としてる事ができないのでは本末転倒なので、なんとか、このスクリプトをroot権限で実行させる方法はないでしょうか・・ あ、もしかしたらc言語でこのシェルスクリプトを実行するためのラッパーをつくればよいのでしょうか。それを、setuidで・・・。むずかしそうですね・・。 まだ/bin/shを有効にする方法は試してないですが、最低でもこれはやらないほうがよいですよね・・
- moco0220
- ベストアンサー率38% (22/57)
商用UNIXサポートの仕事をしていますので、LINUXはあまり得意ではないのですが、 /etc/sudoersは正しく設定されていますか? 次のように記述すれば、動くと思いますが... apache ALL = (root) NOPASSWD:/フルパス/xxx.sh いずれにしても該当するsudoersを示されたほうが、 他の方もアドバイスしやすいかと思います。
お礼
早速のご回答とご指摘ありがとうございます。/etc/sudoersは設定用のvisudoコマンドか何かが使えませんでしたのでviで以下の様に編集しました。 apache ALL = NOPASSWD:/usr/local/apache2/htdocs/root/xx/xxx.sh あとこれも関係あるかどうかよくわからないのですが、ログインシェルは/bin/falseになってます。 apache:x:nnn:nnn::/var/apache:/bin/false 他にも お気づきの点があればご指導の程お願いいたします。
お礼
root権限はやっぱり必要なのですね。あながち間違えてもなくてよかった。なるほど、こうすればルート権限プロセスを外部からのタイミングで起動されることはないわけですね。そしてそっちの方が安全なんですね。これなら出来そうです。今途中まで組んでいるシステムを少し変えて生かして上で実現できそうですのでよかったです。 2のデーモン式はまた敷居が高そうですし、そこまでこだわりもありませんから、1分コロン式でやってみたいと思います。あと処理の単純化のアドバイス今後の参考にさせていただきます。詳細な解説と丁寧なご指導ありがとうございました!