Tengo un proceso que comienza con un damon que se ejecuta como root, ahora quiero "degradar" los privilegios de este proceso a los de su usuario promedio. es posible? Si es así, ¿cómo?
PD: ejecutar unix en una mac
Tengo un proceso que comienza con un damon que se ejecuta como root, ahora quiero "degradar" los privilegios de este proceso a los de su usuario promedio. es posible? Si es así, ¿cómo?
PD: ejecutar unix en una mac
Respuestas:
El proceso en sí tiene que llamar a setuid (2). También debe investigar ejecutarlo dentro de chroot (8) si aún no lo ha hecho. Hasta donde yo sé, no hay forma de que root cambie el uid de otro proceso.
Si la razón por la que lo está ejecutando como root es para vincular puertos, le sugiero que lo ejecute como un usuario normal en un puerto superior y use ipfw (8) en OS X para reenviar el puerto 80/443 / etc al puerto superior:
http://support.crashplanpro.com/doku.php/recipe/forward_port_443_to_pro_server_on_mac_osx
setuid()
solo no es suficiente.
sudo tcpdump -Z
usa initgroups (3), setgid (2) y setuid (2) para eliminar los privilegios de raíz de su propio proceso.
# code taken from:
# http://www.opensource.apple.com/source/tcpdump/tcpdump-32/tcpdump/tcpdump.c
/* Drop root privileges and chroot if necessary */
static void
droproot(const char *username, const char *chroot_dir)
{
...
if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
username,
(unsigned long)pw->pw_uid,
(unsigned long)pw->pw_gid,
pcap_strerror(errno));
exit(1);
}
...
}
initgroups
, setgid
, setuid
(Última!) Es precisamente el paradigma de la derecha en UNIX, y siempre se debe seguir. Además, una función responsable de "droproot" verifica que su uid y gid realmente se hayan configurado, incluso si las tres funciones principales devolvieron el éxito.
Puede ejecutar comandos como otros usuarios usando su
:
su USERNAME -c COMMAND
Se ejecutará COMMAND
con privilegios reducidos a USER
.
Tenga en cuenta que, de forma predeterminada, su
utilizará el intérprete de shell del usuario objetivo para ejecutar el comando. Por el contrario, el comportamiento predeterminado de sudo
es tratar el COMMAND
como un programa independiente, es decir, ejecutar el entorno actual. Por supuesto, estos comportamientos predeterminados se pueden cambiar con varios modificadores y variables de entorno.
su
que no funciona si USERNAME no tiene un shell definido (o /bin/false
) mientras que sudo sí funciona.
su
lo reflejará. Sin embargo, uno siempre puede anular eso usando el -s
interruptor. Tenga en cuenta que el propósito de su
es imitar el comportamiento de un usuario dado, que normalmente está influenciado por su shell. Por el contrario, sudo
ignoraría (por defecto) la configuración del shell del usuario objetivo.
Para eliminar privilegios, necesita un usuario que no sea root para acceder. Entonces es solo cuestión de cambiar a ese usuario:
#define UNPRIV_UID 48
#define UNPRIV_GID 48
if (getuid() == 0) { // we are root
// setting UID/GID requires root privileges, so if you don't set
// the GID first, you won't be able to do it at all.
if (setgid(UNPRIV_GID)!=0) die("Failed to set nonroot GID");
if (setuid(UNPRIV_UID)!=0) die("Failed to set nonroot UID");
}
ASSERT(getuid() != 0);
Tenga en cuenta que esto se realiza dentro del propio programa , en lugar de hacerlo en un script de contenedor. Muchos programas requieren privilegios de root para algún propósito específico (por ejemplo, para enlazar a un puerto de número bajo), pero no necesitan root después de eso. Entonces, estos programas comenzarán como root, pero luego abandonarán los privilegios una vez que ya no sean necesarios.
Si no necesita privilegios de root, simplemente no lo ejecute como root. P.ej:
# Change this:
myprog -C /my/config/file
# To this:
sudo -u someuser myprog -C /my/config/file
# Or this
su someuser -c "myprog -C /my/config/file"
setuid
función solo establece el UID efectivo , no el UID real. Debería usarlo setreuid
si no desea que el proceso pueda recuperar los privilegios. (Y el código anterior no tratar con privilegios de grupo suplementarios ya sea Es adecuado sólo para el lanzamiento de código sobre todo de confianza..)
setuid()
establece usuarios reales y guardados; usted puede estar pensando seteuid()
. No todos los sistemas tienen setreuid()
, por lo que no se puede usar en todas partes. La semántica exacta de setuid()
se complica, pero si tiene euid 0, podrá eliminar todos los privilegios de identificación de usuario tradicionales setuid()
. La mayor omisión en esta respuesta es que initgroups
o setgroups
debe llamarse así como setgid
y setuid
, y que al final deben hacerse afirmaciones más exhaustivas.
Si está ejecutando un ejecutable diferente, es decir, está llamando a execve
otra función de la exec
familia, tal vez indirectamente a través de una función como system
o popen
, y el proceso secundario debería ejecutarse sin privilegios desde el principio, entonces la forma más simple es obtener un shell involucrado, y llame su
. Aquí hay una descripción general de cómo se vería el código en Perl, mostrando las citas necesarias para:
$shell_command = quotemeta($path_to_executable) . " --option";
$shell_command =~ s/'/'\\''/; # protect single quotes for the use as argument to su
$su_command = sprintf("su -c '%s' %s", $shell_command, quotemeta($user_name));
open(PIPE, "$su_command |") or die;
Si el proceso secundario necesita comenzar como root pero luego elimina los privilegios, vea el código en esta respuesta , que ilustra cómo degradar los privilegios en un proceso.