58

私はrootとして開始されるデーモンを持っています(それでそれは低いポートにバインドすることができます)。初期化後、安全上の理由からルート権限を削除してもらいたいと思います。

誰かがこれを行うCの既知の正しいコードを教えてもらえますか?

私はマニュアルページを読み、さまざまなアプリケーションでのこれのさまざまな実装を見てきましたが、それらはすべて異なり、それらのいくつかは本当に複雑です。これはセキュリティ関連のコードであり、他の人が犯しているのと同じ間違いを再発明したくありません。私が探しているのは、それが正しくなるという知識の中で使用できる、ベストプラクティスであり、よく知られている、ポータブルなライブラリ関数です。そのようなものは存在しますか?

参考までに:私はrootとして始めています。別のuidとgidで実行するように変更する必要があります。補足グループを正しく設定する必要があります。後でroot権限に戻す必要はありません。

4

3 に答える 3

48

すべての特権 (ユーザーとグループ) を削除するには、ユーザーの前にグループを削除する必要があります。とにドロップ先のユーザーとグループの ID が含まれている場合、有効な ID もルートであると仮定すると、これは setuid() と setgid() を呼び出すことによってuserid実現ますgroupid

if (getuid() == 0) {
    /* process is running as root, drop privileges */
    if (setgid(groupid) != 0)
        fatal("setgid: Unable to drop group privileges: %s", strerror(errno));
    if (setuid(userid) != 0)
        fatal("setuid: Unable to drop user privileges: %S", strerror(errno));
}

偏執狂的である場合は、ルート権限を取り戻そうとすることができますが、失敗するはずです。失敗しない場合は、次のように救済します。

 if (setuid(0) != -1)
     fatal("ERROR: Managed to regain root privileges?");

また、まだ偏執的である場合は、seteuid()setegid()も使用したい場合がありますが、プロセスが root によって所有されている場合、setuid() と setgid() は既にすべての ID を設定しているため、必要ではありません。

補助グループを設定する POSIX 関数がないため ( getgroups()はありますが、 setgroups() はありません)、補助グループ リストは問題です。使用できるBSD および Linux 拡張機能setgroups()があります。

chdir("/")プロセスがルート所有のディレクトリに残らないように、他のディレクトリにも移動する必要があります。

あなたの質問は一般的な Unix に関するものなので、これは非常に一般的なアプローチです。Linux では、これはもはや推奨される方法ではないことに注意してください。現在の Linux バージョンでは、実行可能ファイルにCAP_NET_BIND_SERVICE機能を設定し、通常のユーザーとして実行する必要があります。root アクセスは必要ありません。

于 2010-07-28T21:53:47.610 に答える