Подтвердить что ты не робот

Навсегда отказаться от привилегий root на современном Linux

После запуска я хочу, чтобы моя Linux-программа потеряла права root и переключилась на незащищенную учетную запись. Я нашел несколько примеров в Интернете, но ничто не канонически для моих требований, в частности:

  • Это постоянное падение
  • оба (e) uid и (e) gid должны переключиться на non-root
  • поддержка только 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).

Однако, поскольку безопасность вызывает беспокойство, я бы хотел быть увереннее, что правильно сбросил все несущественные привилегии. Как я могу быть уверен?

Спасибо.

4b9b3361

Ответ 1

"Канонический" способ сделать это был реализован Д. Дж. Бернштейном в его "setuidgid" коде, который изначально использовался в его программе QMail, в настоящее время включенной в "daemontools".

Фактический код, используемый в GNU coreutils, основан на описании процедуры DJB, ее код отображается здесь https://github.com/wertarbyte/coreutils/blob/master/src/setuidgid.c