• ベストアンサー

隣接したマシンのWeb上からBSDルータのシェルスクリプトを実行させるには。

現在、BSDをルータにして、ブロードバンドルータのように隣接したWindowsマシンからWebで IPFWの設定をできるようにしようと考えています。 そして現在、独自のルールをシェルスクリプトで作成し、case文でそのコマンドを実行すると そのルールが設定されるようになっています。 例えば [Tt][Ee][Ll][Nn][Ee][Tt])    add allow tcp from any to any 23 setup    ;; という風にあって「sh ./rules.sh telnet」で実行したらルールが設定されます。 これを隣接したマシンのWeb上でやらすために、このルータにapacheとperlを入れました。 CGIを使ってやらせようと思っています。 今は、隣のWindowsマシンからBSDルータにアクセスしてtelnetのチェックボックスとOKボタンを表示させています。 これにチェックを入れ、OKボタンをクリックさせたときにこの「sh ./rules.sh telnet」というコマンドをBSDルータ上で実行させたいとおもいます。 しかし、その処理がわかりません。 どうやってこのコマンドをBSD側に送信して実行させることができるのでしょうか? 今は、CGIでチェックを入れてOKしたら「telnet」がチェックされたという情報を表示するだけの状態です。 実際にBSD側にコマンドを送るにはどうしたらいいでしょうか?

  • BSD系OS
  • 回答数5
  • ありがとう数14

質問者が選んだベストアンサー

  • ベストアンサー
  • rentahero
  • ベストアンサー率53% (182/342)
回答No.5

よくわからないとのことですので、私の考えを実験する方法から説明します。 1. 下のshスクリプトを/tmp/test.shとして書き込みます。 --ここから #!/bin/sh echo "this script is test." whoami echo "script end." --ここまで 2. スクリプトに実行権限をつけます。 chmod 755 /tmp/test.sh を実行します。 3. /etc/servicesを編集します。 /etc/servicesの最後に次の行を追加します。 --ここから testsh 20000/tcp --ここまで 4. inetd.confに次の行を追加します。 --ここから testsh stream tcp nowait root /tmp/test.sh test.sh --ここまで 5. inetdを再起動します killall -HUP inetd この状態で、 telnet localhost 20000 とすると先ほどのスクリプトがroot権限で動きます。 ただ、この状態だとポートスキャンに非常に弱いので、localhostのみをlistenするように新規にinetdを起動する方が安全だ、といいたかったのです。 これなら、perlからでもなんでも、またどんなユーザでも当該ポートに接続してreadするだけで状態が取れるので、ちょっとシステムに偏った作業でも便利に使えます。パスワードのようなものを実装する場合は、スクリプトの最初で1行読み込むようにして、その内容をチェックすればいいでしょう。その場合は接続後にwriteしてやるだけです。 当然、コマンドをパースする気があれば、コマンドも送れます。inetdで動かすほうのスクリプトは標準入力を直接読むだけですので、これも簡単です。(sockをあけなくていい) 一度やってみてください。

usui323
質問者

お礼

再度回答ありがとうございました。 この手順で実行してみたところ、実行されました。 なるほど、ちょっと意味がわかったような気がします。 参考になりました。ありがとうございました!

その他の回答 (4)

  • rentahero
  • ベストアンサー率53% (182/342)
回答No.4

下の回答の訂正: loot→root

  • rentahero
  • ベストアンサー率53% (182/342)
回答No.3

わたしなら、セキュリティのことを考えて、cgiからlocalhostの特定ポートへ接続して、localhostの特定ポートで待ち受けているloot権限のプログラムからスクリプトを起動しますね。 FreeBSDでは、localhostの特定ポートを待ち受けるには、 #/sbin/inetd -wW -a localhost -p /var/run/localhost.pid /etc/localhost.conf などと起動すると、楽にできると思います。 機能をポートで分ければ内容のパースも必要ありませんし。

usui323
質問者

お礼

回答ありがとうございます。 知識不足なので、よくわかりませんがアドバイスありがとうございました。 参考になります。 いろいろと調べているとセキュリティのことがよく書いてありますが、 とりあえず動作だけ確認したいからセキュリティを考えないでやってみようとしてもできない状態です(^_^;)

回答No.2

apache を root 権限で動かしているのでしょうか? ipfw は root 権限が無ければルールの改廃ができないと思いますので、perl CGI で何かするなら  1. apache を root 権限で動かす  2. suidperl を使用して、特定の CGI だけ root 権限で動かす 必要があるでしょう。  また、「できない」ときにどんなメッセージがブラウザあるいは apache のログに出るのかが分かりませんが、CGI としては問題なく動くコードなのでしょうか?  もしコードが分からない、という話であれば、CGI の勉強をお勧めするのですが...

usui323
質問者

お礼

回答ありがとうございました。 apacheはrootの時に動かしています。 suidperlというのがよくわからなかったのですが、 ファイルの実行権を chmod 4755 fwrules.cgiなどと変更してみたりもしましたが、変化なしでした。 エラーログには、「-rws--x--x (4755)」のとき rules.sh : Can't open rules.sh ; Permission denied 「-rwxr-xr-x (755)」のとき ipfw: socket: Operation not permitted と、ファイルの権限によって二種類のエラーメッセージが表示されました。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

試してないですけど、 $status = system("sh ./rules.sh telnet"); とかで実行できませんか?

usui323
質問者

お礼

回答ありがとうございます。 そのままではできませんでしたが、system関数でlsコマンドやpwdコマンドなどは動作しました。 ただ、このシェルスクリプトを動かす命令は反応なしでした。

関連するQ&A

  • シェルスクリプトで困っています 2

    度々申し訳ございません。 現在、Linuxマシン1からLinuxマシン2へTelnetでログインし、Linuxマシン2上にあるシェルスクリプト(/bin/sh)を実行し、Linuxマシン2上のプログラムを実行した後、Linuxマシン2からログアウトするシェルスクリプトを作成中です。 その、Linuxマシン2からログアウトする際に、 "exit"を記述しているのですが、その"exit"がTelnetログアウトの意味で実行されず、シェルスクリプトを終了するの意味で実行されていて困っています。 どなたか上手くTelnetからログアウトできるようにシェルスクリプトを組む方法をご存知ではないでしょうか?もし判りましたらご教授下さい。 よろしくお願い致します。

  • シェルスクリプトで困っています

    自分のLinuxマシン(PC1)から、イーサネットで繋がっているLinuxマシン(PC2)に、自動的にTelnetを用いてログインし、そこでいくつかの操作をするシェルスクリプトを作成中です。 Telnetでログインした後、PC2が持っているプログラムを走らせ、その結果を見て再度そのプログラムを走らせるか、次のプログラムへ移るかを、ユーザのキーボード入力にて判断可能なようにしたいと思っています。 "#!/usr/bin/expect"の、 "expect *** { send **** }"などを使えば、Telnetのような対話型アプリケーションに使えることが分かったのですが、ユーザからのキーボード入力を判定する方法が分かりません。。。 また、"#!/bin/sh"の、"read"コマンドを用いれば、ユーザからのキーボード入力を受け付けることが分かったのですが、Telnetなどをどう扱えばいいのかが分かりません…。 大変あいまいで、分かりにくい質問で申し訳ないのですが、どなたかお分かりになる方がいらっしゃればご教授ください。 分かりにくい点はいくらでも補足いたします。よろしくお願いいたします。

  • Linux間のリモートシェルの実行について

    マシンタイプ:x225 カーネル: 2.4.20-28.7smp OS:Red Hat Linux 7.3 2.96-126)) 上記のLinuxサーバからrshで同じタイプのリモートのLinuxサーバのシェルを起動しようとしましたが正常に起動されません。 状況としては rsh実行時は特にエラーメッセージが出ることもなく、正常に実行されたかのように終了してしまうため、何が悪いのかもわからない状態です。 実行したコマンドとリモート側のシェルの内容は以下の通りです。 rsh server1 /home/test/testrsh.sh <testrsh.sh> #!/bin/ksh time=`date` echo "rsh test $time" >> /home/test/testrsh.log ちなみに rsh server1 date や rsh server1 uname 等のLinuxのコマンドは正常に実行できます。 どこを確認したらよいでしょうか? よろしくお願いします。

  • LoadPowerProfile レジストリ(マシン実行)(マシンサービス)とは何であり、その役割は?教えてください。  

    お世話になります。 「システム構成ユーティリティ」より下記の2つを不具合によるエラーのためチェックを外しました。 ●名前         LoadPowerProfile 読み込み元       レジストリ(マシン実行) コマンド Rndll32.exe powrprof.dll,LoadCurrentPwrScheme ●名前         LoadPowerProfile 読み込み元       レジストリ(マシンサービス) コマンド Rundll32.exe powrprof.dll,LoadCurrentPwrScheme 上記のこの二つを同時に外してのエラーがないような状態です。 ※このどちらが、悪いのかは分かりませんので、ご存知の方の知識で片方か両方共に悪いのかご判断と、上記これらは何なのか?教えてください。

  • sudoコマンドについて。

     sudoコマンドについての質問です。 OSはFreeBSD 5.2です。  sudoコマンドというのは、初めにユーザのパスワードを聞いてきますよね。 っで、BSD上で実行するときはパスワードを入力すれば問題ないのですが、隣接したマシン(Win2000)のWeb上からCGIを使って実行しようとすると、 パスワードでとまってしまい、Webからは実行できなくなってしまいます。 BSD上でパスワードを入力して、その後5分間は(デフォルトのままなので)Web上からでも自由にsudoコマンドが使えます。 ですが、Webを使うにはBSD上でパスワードを入力する必要があるので、この作業もWebで全てさせたいと考えています。 ログイン画面のようなものを作って、sudoコマンド時のユーザーパスワードを入力してログインさせて以降は時間を気にせずsudoが実行できるようにしたいと思っています。 ですが、CGIでフォームを作ってどのようにすればいいでしょうか? 例えば「sudo ipfw show」と現在のIPFWのルール設定を見ようと思ったら 「Password:」と聞いてくるのでそれに対してパスワードを送信しなくてはいけないわけですが、 Web上のテキストボックスに「sudo ipfw show」として送信すると、止まってしまいます。 そのままフリーズのようになってしまい、その後パスワードを入力することができません。 CGIでサーバとの対話的通信(?)のように行ったり来たりの通信をするには どのようにすればいいのでしょうか?

  • シェルスクリプトでのエラー時の処理について

    HTMLにシェルスクリプトを実行するSSIを埋め込んで、 その実行結果をHTML側に出力する、という処理をしようとしております。 大まかな処理内容は、指定の場所のファイルの有無をチェックして それにより"ok"か"ng"かの文字列をHTMLに出力する、というものです。 ====以下、HTMLソース(前後省略)==== <br> 結果は:<!--#exec cmd="./output.sh" --> <br> ====ここまで==== ====以下、シェルスクリプトソース==== #!/bin/sh CHECKFILE=/aaa/bbb/check.txt TEXTA=ok TEXTB=ng if [ -f $CHECKFILE ] ; then echo $TEXTA else echo $TEXTB fi exit ====ここまで==== この処理自体は特に問題無さそうなのですが、 この中に途中で異常終了した際のエラー処理を組み込むことによって、 異常時には固定で"ok"を出力して終了するようにしたいのです。 trap "echo 'ok'; exit" HUP INT QUIT KILL TERM や trap "echo 'ok'; exit" 1 2 3 9 15 などのtrapを入れたりもしたのですが、 思い通りには動かず、結果を返すことなく終了してしまいます。 このような場合、trapに限らず何か良い方法はありますでしょうか。 何かご存知の方おりましたらご助言頂けますでしょうか。。 よろしくお願いいたします。

  • 対話的にコマンドを送受信するには?

    FreeBSD 5.3のIPFWの設定を隣接したWindowsマシンからリモートでさせようとしています。 apacheを入れ、CGIを使って、現在はWeb上からリモート設定が可能な状態となっています。 sudoコマンドを使ってのリモート操作です。 リモートでルールを破棄しようとしているんですが、できずにいます。 BSDマシン上で「ipfw flush」とコマンドを打てばルールはすべて破棄されていましたが、 「sudo ipfw flush」とすると「are you sure?[yn]」と確認されるので ここで「y」とするとルールが破棄できます。 ですが、これをWeb上からリモートでしようとすると、対話的に通信する必要があるため、実現できません。 「sudo ipfw flush」というコマンドは送信できますが、その後に対する「y」というコマンドが送信できません。 こういった、送ったコマンドの返答に対してさらにコマンドを送るといったような、 対話的にコマンドを送信するにはCGIではどのようにしたらいいでしょうか? 一度、「sudo ipfw flush」と送ってしまうと、Web上ではフリーズしてしまい、 その後はapacheをストップして再起動しないと動作がおかしくなってしまいます。 CGIで対話的にコマンドを送受信するにはどのようにすればいいのでしょうか? チャットのようにすればいいのでしょうか?

    • ベストアンサー
    • CGI
  • telnet,rlogin,rshの違いってなに・・・・?

    どのコマンドもリモートホスト(linux系)にログインするコマンドのものですよね? この3つの具体的な違いってなんなのでしょうか?・・・ 日経リナックス(http://homepage2.nifty.com/cs/linux_command/) を参照すると telnet=>他のホストと通信をする rlogin=>リモート・マシンにログインする rsh=>リモート・マシンのコマンドを実行 となっています。 どのコマンドもリモートマシンにログインして実行するものだと思うのですが・・・。

  • telnet接続

    ある装置にtelnet接続し、コマンド(ccc dd ee)を送信して帰ってきた値を outou.dat というファイルに保存するプログラムを作っています。 接続すると login: と表示されるので「aaaa」と入力すると Welcome to aaaa > と表示され、「bbbb」と入力するとプロンプトが「#」に変わります。 >bbbb # そこでコマンド「ccc dd ee」を入力したときに帰ってくる応答をファイルに保存します。 #ccc dd ee ------応答データ-------- これを行うのに下記プログラムを実行しましたが、エラーは出ませんがファイルに何も 保存されませんでした。 何がいけないのかわかる方教えてください。 use strict; use Net::Telnet; my $host = '192.168.1.1'; my $login = 'aaaa'; my $enable = 'bbbb'; my $prompt1 = '/>/'; my $prompt2 = '/\S/'; my $telnet = new Net::Telnet( Timeout => 10, ); $telnet->open($host); $telnet->waitfor('/login:/i'); $telnet->print($login); $telnet->waitfor($prompt1); $telnet->print($enable); $telnet->waitfor($prompt2); my @result; $telnet->print("ccc dd ee"); ($result) = $telnet->waitfor($prompt2); open(OUT, "> outou.dat"); print(OUT "@result\n"); close(OUT); $telnet->close;

  • rshでのバッチ実行環境

    WindowsからUnixマシンに対してジョブ実行するために、rshでsource xxxを実行して環境設定しようとしてもうまく反映されません。 telnetで実行した場合はOKなのですが、rshでうまくできない理由はどんなことが考えられるのでしょうか?