2017-07-30 18 views
0

私はユーザーに代わってファイルを読み書きできるはずのRustで小さなWebアプリケーションを構築したいと考えています。ユーザーは自分のUNIX資格情報で認証し、アクセス可能なファイルのみを読み書きすることができます。アプリケーションスレッドのユーザーとグループを切り替えることは可能ですか?

私の最初のアイデアは、私にとって最も安全だと思われるが、アプリケーションスレッドのユーザーコンテキストを切り替えてそこにすべての読み取り/書き込みを行うことだろう。これは可能ですか?

これが可能であれば、パフォーマンスはどのように見えますか?私は、要求が来るたびにオペレーティングシステムのスレッドを生成すると考えていますが、非常に高いオーバーヘッドがあります。これを行うより良い方法はありますか?

本当に私のアプリケーション全体をrootとして実行し、権限を手動で確認するのは嫌いです。

答えて

2

GNU/Linuxでは、プロセスの1つのスレッドに対してUIDとGIDを切り替えることはできません。 Linuxカーネルはスレッドごとの資格情報を維持しますが、POSIXはプロセスごとに1つの資格証明セットを必要とします。POSIX setuidはすべてのスレッドのUIDを変更する必要があります。 glibcはPOSIXの動作をエミュレートするのに非常に時間がかかりますが、それは非常に困難です。

新しいスレッドだけでなく、要求ごとに完全に新しいプロセスを作成する必要があります。プロセスの作成はLinux上ではかなり安いですが、それでもパフォーマンス上の問題になる可能性があります。プロセスのプールを繰り返して、繰り返しのプロセス作成によるオーバーヘッドを避けることができます。一方で、何年も前、Webサイトの多く(かなり大きいものを含む)はCGIを使ってWebページを生成していました。

1

@Florianはこれを元の答えで後ろ向きにしていると思います。 man 2 setuidは、カーネルレベルで

Cライブラリ/カーネルの違いは、ユーザーIDとグループIDは、スレッドごとの属性ですと言います。ただし、POSIXでは、プロセス内のすべてのスレッドが同じ資格情報を共有する必要があります。 NPTLスレッド実装では、 UIDとGIDを変更するさまざまな システムコールのラッパー関数を提供することにより、 POSIX要件を処理します。これらのラッパー関数(setuid()のものも含む)はシグナルベースの手法を採用しており、 スレッドが資格を変更すると、プロセス内の他のすべてのスレッドも資格情報を変更します。詳細は、nptl(7)を参照してください。

libcはプロセス全体に対してシグナルダンスを行うので、バイパスするために直接システムコールを行う必要があります。

これはLinux固有のものです。他のほとんどのUNIX変種は、libcでそれをエミュレートする代わりに、カーネルレベルでposixに従うように見えます。

+0

私は私の答えを明確にしました。 GNU/Linuxでは、私はGNU(glibc)ユーザランドを持つLinuxカーネルを意味しました。他のlibcs​​は動作が異なるかもしれません。 glibcは、直接システムコールでUID/GIDの変更にうまく反応しないことがあります。 –

関連する問題