起動後、Linux プログラムで root 権限を削除し、権限のないアカウントに切り替えたいと考えています。オンラインでさまざまな例を見つけましたが、具体的には私の要件に対して標準的なものはありません:
- これは永続的なドロップです
- (e)uid と (e)gid の両方を非ルートに切り替える必要があります
- Linux サポートのみ (カーネル > 2.6.32)
- 補助グループは必要ありません
私が見つけた最良のアプローチは次のとおりです。
uid_t new_uid = ...;
gid_t new_gid = ...;
gid_t rgid, egid, sgid;
if (setresgid(new_gid, new_gid, new_gid) < 0)
{
perror("setresgid");
exit(EXIT_FAILURE);
}
if (getresgid(&rgid, &egid, &sgid) < 0)
{
perror("getresgid");
exit(EXIT_FAILURE);
}
if (rgid != new_gid || egid != new_gid || sgid != new_gid)
{
printf("unexpected gid");
exit(EXIT_FAILURE);
}
if (setgroups(0, 0) != 0)
{
perror("setgroups");
exit(EXIT_FAILURE);
}
uid_t ruid, euid, suid;
if (setresuid(new_uid, new_uid, new_uid) < 0)
{
perror("setresuid");
exit(EXIT_FAILURE);
}
if (getresuid(&ruid, &euid, &suid) < 0)
{
perror("getresuid");
exit(EXIT_FAILURE);
}
if (ruid != new_uid || euid != new_uid || suid != new_uid)
{
printf("unexpected uid");
exit(EXIT_FAILURE);
}
これを exe にラップし、次のコマンドを使用して uid と gid が正しく表示されることを実証できます。
ps -eO user,uid,ruid,suid,group,gid,rgid,sgid
プログラムは、特権ポートにバインドしたり、ほとんどのルート所有ファイルを操作したりできないため、それで問題ありません。
また、プロセスに予期しない機能がないことを確認するcaptestプログラム (libcap-ng-utils に含まれています) も見つけました(7)。
ただし、セキュリティが懸念事項であるため、必須ではないすべての特権を正しく削除したことをより確信したいと思います。どうすれば確信できますか?
ありがとう。