¿Cómo elimino los privilegios de root en los scripts de shell?

13

La opción "--up" en OpenVPN se usa normalmente para enrutamiento, etc. Y, por lo tanto, se procesa antes de que OpenVPN elimine los privilegios de root para ejecutarse como nadie. Sin embargo, estoy invocando scripts de shell que deben ejecutarse como un usuario sin privilegios.

¿Cómo puedo hacer eso? He estudiado los privilegios del proceso de caída , especialmente las respuestas de polinomios y tylerl, pero no entiendo cómo implementarlas. Estoy trabajando en Centos 6.5, y suid está bloqueado, tanto como "chmod u + s" como "setuid ()".

Hay un complemento OpenVPN ("openvpn-down-root.so") que permite que los scripts invocados por la opción "--down" se ejecuten como root. Podría haber un equivalente, como "openvpn-up-user.so", pero no lo he encontrado.

Editar0

Según la respuesta de Nikola Kotur, he instalado las runit-rpm de Ian Meyer . Aunque el comando chpst funciona en la terminal, en el script up falla con "comando no encontrado". Lo que funciona es "sudo chpst" además de configurar la pantalla y el idioma adecuados. Consulte ¿ Por qué mi terminal no genera caracteres Unicode correctamente? Dado eso, el script up necesita estas cuatro líneas:

LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo chpst -u user -U user /home/user/unprivileged.sh &

Editar1

Según el comentario de 0xC0000022L, encuentro que "sudo -u user" funciona tan bien como "sudo chpst -u user -U user":

LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo -u user /home/user/unprivileged.sh &

Estudiaré sudoers de hombre y actualizaré si / cuando consigo sudo solo para trabajar.

mirimir
fuente
comentario dejado por @ user66229: "¿Puedo sugerirle que navegue a sourceforge.net/p/openvpn/mailman y se suscriba a las listas que considere más apropiadas".
slm
@ user66229 Gracias. Pero no creo que esta sea una pregunta específica de OpenVPN. ¿Por qué crees que es así?
mirimir

Respuestas:

7

Yo uso Runit 's chpstherramienta para este tipo de tareas. Por ejemplo, desde la secuencia de comandos superior, llame a su secuencia de comandos sin privilegios:

chpst -u nobody /path/to/script
Nikola Kotur
fuente
Genial, gracias. ¿Es github.com/imeyer/runit-rpm la mejor manera de ejecutar Runit en Centos 6.5? Incluso con los repositorios de Red Hat, no encuentro un paquete.
mirimir
@mirimir, sí, uso ese repositorio cuando necesito crear un paquete de runit para CentOS.
Nikola Kotur
10

Cubrir solo runit y sudo se pierde mucho. En realidad, hay toda una familia de conjuntos de herramientas como runit, y una amplia variedad de herramientas para hacer exactamente esto, la tarea para la que fueron diseñados:

  • Daemontools de Daniel J. Bernstein, tiene setuidgid:

    usuario setuidgid /home/user/unprivileged.sh
  • La libertad de Adam Sampson tiene setuidgid:

    usuario setuidgid /home/user/unprivileged.sh
  • Daemontools-encore de Bruce Guenter tiene setuidgid:

    usuario setuidgid /home/user/unprivileged.sh
  • La runa de Gerrit Pape tiene chpst:

    chpst -u usuario /home/user/unprivileged.sh
  • El asesino de Wayne Marshall tiene runuid:

    usuario runuid /home/user/unprivileged.sh
  • El s6 de Laurent Bercot tiene s6-setuidgid:

    usuario s6-setuidgid /home/user/unprivileged.sh
  • mi nariz tiene setuidgid:

    usuario setuidgid /home/user/unprivileged.sh

No se mezclan en la tarea diferente de agregar privilegios, y nunca caen en un modo interactivo.

Por cierto, sus problemas añadidos son poco más que su olvido de tener sbin, así como binen PATHlos suyos.

Otras lecturas

JdeBP
fuente
3

script que elimina privilegios y ejecuta otro script (pero aquí solo lo hice para ejecutarse):

#!/bin/sh

id=`id -u`
safeuser="nobody"

if [ $id = "0" ]
then
         # we're root. dangerous!
        sudo -u $safeuser $0
else
    echo "I'm not root"
    id
fi

Ejemplo:

root@n3:/tmp/x# id
uid=0(root) gid=0(root) группы=0(root)
root@n3:/tmp/x# ./drop.sh
I'm not root
uid=65534(nobody) gid=65534(nogroup) группы=65534(nogroup)
Yaroslaff
fuente
Si bien el uso de "sudo -u user" funciona para algunos comandos, no proporciona suficiente entorno de usuario para mis propósitos. Y aunque "su -l user" funciona bien en la terminal, no hace nada en los scripts. Supongo que es una característica de seguridad. Entonces parece que me queda la instalación de runit.
mirimir
1
@mirimir: ¿por qué? /etc/sudoerspermite de manera muy específica qué variables de entorno se pueden transmitir a la ejecución del programa por sudoy así sucesivamente. man sudoers. Honestamente, quien lo usa sudosimplemente para sudo su -o para cambiar el contexto del usuario no tiene idea de lo que hay detrás de este increíble programa y cuánto puede bloquear cosas para programas individuales, usuarios, hosts, etc ...
0xC0000022L
@ 0xC0000022L Gracias. Eché otro vistazo al sudo. Y sí, "sudo -u user" más pantalla e idioma también funciona.
mirimir 01 de
1
Hablando de peligroso, no puedes confiar $0; la persona que llama puede configurar un script $0para literalmente cualquier cosa que quiera que sea. Y usa más citas.
Charles Duffy
2
... si su script $0es /directory/name with spaces/script(y recuerde, los usuarios pueden crear enlaces simbólicos arbitrarios en ubicaciones que poseen, incluso si no usan exec -a somename yourscriptpara llamar yourscriptcon un $0de somename), entonces obtendría sudo -u nobody /directory/name with spaces, pasaría withy spacespasaría como argumentos separados a su comando .
Charles Duffy
1

Qué pasa:

sudo -Eu <user> <command>

En un comentario anterior, se quejó del entorno, por lo que también podría comparar las diferencias entre los resultados:

sudo -u <user> printenv
sudo -Eu <user> printenv
thiagowfx
fuente
1

En Linux puede usar runusero setprivsi no se requiere una sesión PAM (ambas de util-linux):

runuser -u USER [--] COMMAND [ARGUMENTS...]

setpriv --reuid=1000 --regid=1000 --init-groups COMMAND [ARGUMENTS...]  # Like su/runuser/sudo
setpriv --reuid=1000 --regid=1000 --clear-groups COMMAND [ARGUMENTS...]  # Like daemontools setuid(8)

Desde la supágina del manual:

su está diseñado principalmente para usuarios no privilegiados, la solución recomendada para usuarios privilegiados (por ejemplo, scripts ejecutados por root) es usar el comando runuser (1) sin establecer el ID de usuario que no requiere autenticación y proporciona una configuración PAM separada. Si la sesión PAM no es necesaria, la solución recomendada es usar el comando setpriv (1) .

dcoles
fuente