2012-07-30 10 views
10

私はPythonをベースにしたWebサーバーを開発しています。これは機能を簡単に拡張できるように "プラグイン"を実行できるはずです。Python:信頼できないスクリプトやサブプロセスをchrootとchjailで保護する

私はこのアプローチでは、いくつかのフォルダ(各プラグインに1つ)とそこにいくつかのイベントが発生する可能性のある定義済みの名前の後に名前が付けられたシェル/ Pythonスクリプトがあると考えました。

たとえば、PDFがサーバーにアップロードされるときに実行されるon_pdf_uploaded.pyファイルを持つことです。これを行うには、Pythonのサブプロセスツールを使用します。

利便性とセキュリティのために、これにより、Unix環境変数を使用して詳細情報を提供し、プロセスの作業ディレクトリ(cwd)を設定して、場所を見つけることなく正しいファイルにアクセスできるようになります。

プラグインコードは信頼できないソースから来ているので、できるだけ安全なものにしたいと思います。私の考えは、サブプロセスでコードを実行することでしたが、サーバー上の他のリソースにアクセスすることができないように、別のユーザーでchroot jailに入れました。

残念なことに、私はこれについて何も見つかりませんでした。私は、信頼できないスクリプトに頼って刑務所に掛けることは望ましくありません。

さらに、サーバーが他の要求に応答している間にプラグインコードが複数のプロセスで同時に実行される可能性があるため、メイン/呼び出しプロセスをchroot jailに入れることはできません。

これは疑問です。chroot jail内のサブプロセス/スクリプトを最低限の特権で実行して、残りのサーバーを信頼できないコードで破損しないようにするにはどうすればよいですか?

ありがとうございました!

+0

これは本当にあなたの仕事ですか?実行中のコードを知ってはいけませんか?何でも...これは助けになるの? [os.chroot()](http://docs.python.org/library/os.html#os.chroot)。さらに、 'os'はuidなどを混乱させるようになっています。したがって、新しいプロセス(os.fork()?)を作成し、次にos.setuidとos.execle()を作成します。 – Logan

答えて

2

あなたの刑務所を作成したら、あなたのPythonソースからos.chrootと呼んでそれに入ります。しかし、それでもなお、インタプリタによってすでに開かれている共有ライブラリやモジュールファイルはまだ開いていて、os.closeでこれらのファイルを閉じるとどうなるか分かりません。私はそれを試したことはありません。

chrootを設定するのは大変な作業ですが、そのメリットは価格に見合う価値があることを確認してください。最悪の場合、使用するすべてのモジュール、すべての依存プログラム、共有ライブラリ、/bin/libなどのファイルは、各jailファイルシステム内で使用できるようにする必要があります。もちろん、これを実行しても他のタイプのリソース、つまりネットワーク宛先、データベースは保護されません。

代わりに、信頼できないコードを文字列として読み取ってからexec code in mynamespaceを読み取ることができます。は、が信頼できないコードに公開するシンボルのみを定義する辞書です。これは、Python VM内の「刑務所」のようなものです。組み込みの__import__関数を置き換えないと、(わかりませんが)importステートメントのようなものを探して、ソースを解析しなければならないかもしれません。

+0

データ交換と例外処理の柔軟性が最も優れているので、私は動的コードローディングアプローチを採用しました。 – BastiBen

4

おそらくこのようなものでしょうか?

その後
# main.py 
subprocess.call(["python", "pluginhandler.py", "plugin", env]) 

# pluginhandler.py 
os.chroot(chrootpath) 
os.setgid(gid) # Important! Set GID first! See comments for details. 
os.setuid(uid) 
os.execle(programpath, arg1, arg2, ..., env) 
# or another subprocess call 
subprocess.call["python", "plugin", env]) 

EDITは:(フォークを使用していた)が、私は実際にそれが何をしたか理解していませんでした。それを見た。新しい コード!

# main.py 
import os,sys 
somevar = someimportantdata 
pid = os.fork() 
if pid: 
    # this is the parent process... do whatever needs to be done as the parent 
else: 
    # we are the child process... lets do that plugin thing! 
    os.setgid(gid) # Important! Set GID first! See comments for details. 
    os.setuid(uid) 
    os.chroot(chrootpath) 
    import untrustworthyplugin 
    untrustworthyplugin.run(somevar) 
    sys.exit(0) 

This有用であったと私はかなりだけでそのコードを盗んだので、まともな例えばその人に賛辞。

+1

これは私の問題をかなり解決しました。物事は、virtualenv内のpsutilのインストールとユーザーのアクセス許可のために、トリッキーでしたが、いくつかの試行錯誤の後、私はそれを修正しました。 – coya

+0

@habnabitあなたはあなたの編集を詳述できますか?私は秩序がなぜ重要であるかに慣れていないので、セキュリティの意味合いがある場合、答えで明示的に呼び出される価値があると信じています。 – Logan

+1

@Logan https://stackoverflow.com/a/11062896 – habnabit

関連する問題