7

したがって、次の問題があります。LinuxのTomcat7サーバー内でWebサービスを実行しています。ただし、Webサービスはいくつかのコマンド(主にコピーやマウントなどのファイル操作)を実行する必要があります。コピー私はjava.nioに置き換えましたが、の代わりになるとは思いませんmount

そのため、TomcatJavaプロセスからシェルコマンドを実行しようとしています。残念ながら、コマンドは実行されません。以前、Javaでシェルコマンドの実行を実装しました。だから私のコードは正しいはずです:

Process pr = Runtime.getRuntime().exec("mount -o loop -t iso9660 <myimage> <mymountpoint>");
pr.waitFor();

<myimage><mymountpoint>は絶対パスなので、問題もありません。

  • コマンドをデバッグしましたが、コンソールで実行すると機能します。
  • 他のコマンドを送ってみました。idやなどの簡単なコマンドが機能しpwdています!
  • を使ってみましたが/bin/bash -c "<command>"、うまくいきませんでした。
  • コマンドを実行するシェルスクリプトを実行しようとしましたが、機能しませんでした。
  • コマンドのスペースをエスケープしようとしましたが、機能しませんでした。

それで、私はさらに深く掘り下げました、そして今、私はコマンドを実行することを妨げるいくつかのTomcatセキュリティポリシー(サンドボックス?)を疑っています。セキュリティは私にとって問題ではないので(これは内部システムであり、外界から完全に隔離されています)、最近非常に人気が出たハックを試しました。

System.setSecurityManager(null);

これもうまくいきませんでした。RHEL6でJava7とTomcat7を使用しています。Tomcat7が抽出されました!/ etc/..または/opt/ tomcat /以外のフォルダーにファイルがありません。ここで、Tomcatホームページからzipを抽出しました。/ opt / tomcat / confフォルダーでセキュリティ設定を検索しましたが、見つかったのはファイルcatalina.policyだけで、シェルコマンドにセキュリティレベルを設定できるようには見えませんでした。

何か案は?

4

5 に答える 5

7

いくつかのこと:

System.setSecurityManager(null);

アプリケーションのセキュリティを無効にしました。

はい、Tomcatはrootとして実行されています。idを実行すると、私もrootになります。

これをすぐに修正してください!

さて、質問に移りましょう。Tomcatに何かを実行させるべきではありません。これを、シェルスクリプトであろうと別のJavaプログラムであろうと、別のプロセスに延期する必要があります。これにより、Tomcatを実行しているrootへの依存関係(私は願っています)も削除されます。このコマンドは、システムに正常にログインできない非特権ユーザーとして実行できるはずです。/etc/fstabこれを行うには、同じユーザーにこれを行うためのアクセス許可を構成して提供します。純粋なセキュリティPOVから、マウントするプロセスはTomcatユーザーが所有するべきではありません。また、Tomcatユーザーがrootになることもありません。要約すると、
1)Tomcatのルートとしての実行を停止し
ます。2)このマウントを実行するために、Tomcatのコンテキスト外に別のプロセスを作成します。
3)tomcatユーザーを作成します。このユーザーはシステムにログインできず、特権ユーザー(admin、superユーザーなど)であってはなりません
。4)プロセスユーザーを作成します。このユーザーはtomcatユーザーとまったく同じように構成する必要があります。
5)編集/etc/fstabして、プロセスユーザーに正しくマウントするために必要な権限を与えます。

于 2012-09-22T22:00:48.473 に答える
6

一般に、の単一文字列形式を使用することはお勧めできませんRuntime.exec。より良いオプションは、を使用ProcessBuilderし、Javaに依存して引数を分割するのではなく、自分で引数を分割することです(これは非常に素朴です)。

ProcessBuilder pb = new ProcessBuilder("/bin/mount", "-o", "loop", /*...*/);
pb.redirectErrorStream(true); // equivalent of 2>&1
Process p = pb.start();

RHELを使用しているとのことですが、selinuxをアクティブにしていますか?ログをチェックして、これがあなたをブロックしているものであるかどうかを確認してください(あなたが探しているのはaudit.logだと思います。私がselinuxを使用してから数年になります)。これが問題であることが判明した場合は、おそらくSOではなくスーパーユーザーまたはserverfaultで質問する必要があります...

于 2012-09-21T21:26:33.243 に答える
1

私は最近、Swingアプリからこのようなことをしなければなりませんでした。

Ianの回答のように、ProcessBuilderを使用してそれを実行できる可能性がありますが、物事が複雑になり始めたら、必要なことを実行するシェルスクリプトを作成する方が簡単であり、渡すパラメーターをできるだけ少なくすることができます。可能。次に、ProcessBuilderを使用してシェルスクリプトを呼び出します。

本当に最小限の出力を超えるものを呼び出す場合は、出力バッファーがいっぱいになったときにプロセスがブロックされないように、出力ストリームとエラーストリームも読み取る必要があります。

于 2012-09-22T01:19:03.587 に答える
1

それが問題であるかどうかはわかりませんが、関連する出力バッファーを読み取らずにRuntime.exec()を使用すると問題が発生します。詳細な説明と考えられる解決策はここにあります。出力ストリームとエラーストリームを読み取ると、コマンドを実行したときにOSレベルで何が起こっているかを把握するのにも役立ちます。

于 2012-09-21T20:23:58.787 に答える
1

sudo -Sコマンドの前とtomcat7ユーザーに使用します。tomcat7 ALL=(ALL) NOPASSWD:ALL

于 2017-11-09T13:48:23.980 に答える