Estoy ejecutando sudo-1.8.6 en CentOS 6.5. Mi pregunta es muy simple: ¿cómo evito que SHELL se propague del entorno de un usuario a un entorno de sudo?
Por lo general, las personas van por el otro lado: quieren preservar una variable de entorno. Sin embargo, tengo un problema en el que mi usuario "zabbix" cuyo shell /sbin/nologinintenta ejecutar un comando a través de sudo. Sudo está preservando /sbin/nologinpara que la raíz no pueda ejecutar subcapas. (Actualización: esta parte es verdadera, pero no es la variable de entorno SHELL. El problema es el valor de shell que se extrae de / etc / passwd).
Incluyo una prueba que ilustra el problema; Este no es mi caso de uso del mundo real, sino que simplemente ilustra que el SHELL del usuario que llama se conserva. Tengo un programa que se ejecuta como usuario zabbix. Llama /usr/bin/sudo -u root /tmp/doit(la programación se ejecuta como zabbixun demonio, por lo que el /sbin/nologinshell en el archivo de contraseña no lo impide). /tmp/doites un script de shell que simplemente tiene:
#!/bin/sh
env > /tmp/outfile
(su modo es 755, obviamente). En outfilepuedo ver que SHELLes /sbin/nologin. Sin embargo, en este punto, el script se ejecuta como root, a través de sudo, por lo que no debería tener las variables de entorno del usuario anterior, ¿verdad?
Aquí está mi / etc / sudoers:
Los valores predeterminados requieren Por defecto! Visiblepw Valores predeterminados always_set_home Valores predeterminados env_reset Valores predeterminados env_keep = "PANTALLA DE COLORES NOMBRE DEL HOSTAL TAMAÑO INPUTRC KDEDIR LS_COLORS" Valores predeterminados env_keep + = "CORREO PS1 PS2 QTDIR NOMBRE DE USUARIO LANG LC_ADDRESS LC_CTYPE" Valores predeterminados env_keep + = "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" Valores predeterminados env_keep + = "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE" Valores predeterminados env_keep + = "LC_TIME LC_ALL IDIOMA LINGUAS _XKB_CHARSET XAUTHORITY" Valores predeterminados secure_path = / sbin: / bin: / usr / sbin: / usr / bin: / usr / local / bin: / usr / local / sbin ## Permitir a la raíz ejecutar cualquier comando en cualquier lugar root ALL = (ALL) ALL #includedir /etc/sudoers.d
Y aquí está mi /etc/sudoers.d/zabbix:
Valores predeterminados: zabbix! Requiretty zabbix ALL = (root) NOPASSWD: / tmp / doit
Editar: Un poco más de información:
El proceso que ejecuta el sudo es zabbix_agentd, desde el software de monitoreo Zabbix. Hay una entrada en el /etc/zabbix/zabbix_agentd.d/userparameter_disk.confarchivo que se parece a:
UserParameter = example.disk.discovery, / usr / local / bin / zabbix_raid_discovery
/usr/local/bin/zabbix_raid_discoveryes un script de Python Lo he modificado para simplemente hacer esto:
print subprocess.check_output (['/ usr / bin / sudo', '-u', 'root', '/ tmp / doit'])
/tmp/doit simplemente hace esto:
#! / bin / sh env >> / tmp / outfile
Ejecuto lo siguiente en mi servidor Zabbix para ejecutar el /usr/local/bin/zabbix_raid_discoveryscript:
zabbix_get -s client_hostname -k 'ejemplo.disco.discovery'
Luego reviso el /tmp/outfile, y veo:
SHELL = / sbin / nologin TERM = linux USUARIO = root SUDO_USER = zabbix SUDO_UID = 497 USERNAME = root RUTA = / sbin: / bin: / usr / sbin: / usr / bin: / usr / local / bin: / usr / local / sbin CORREO = / var / mail / root PWD = / LANG = en_US.UTF-8 SHLVL = 1 SUDO_COMMAND = / tmp / doit INICIO = / root LOGNAME = root SUDO_GID = 497 _ = / bin / env
Esa SHELLlínea realmente me molesta. El archivo es propiedad de root, por lo que sé que está siendo creado por el usuario root, pero el shell es del usuario llamante ( zabbix).
fuente

sudo env SHELL=/bin/sh shProporciona un aviso con / bin / sh establecido como la variable SHELL en su sistema?env_delete, pero estoy de acuerdo el quid de la cuestión es que el comportamiento predeterminado de env_reset...causes commands to be executed with a new, minimal environment.Tenemos un sistema Linux con PAM, lo que de acuerdo a la página del manual,The new environment contains the ... SHELL ... (variable). Como puede ver en mi/etc/sudoersarchivo anterior, no permitimosSHELLen elenv_keep. PorSHELLlo tanto , no se debe preservar; deberíamos tener el usuario rootSHELL.zabbix ALL=(root) NOPASSWD: /bin/env SHELL=/bin/sh /tmp/doit *a mi/etc/sudoers/zabbixarchivo y tiene un shell adecuado. Gracias, ahora tengo una solución. La pregunta es, ¿por qué necesitaba incluirlo? Parece peligroso (y roto) pasar el SHELL de la persona que llama, pero no puedo encontrar ningún lugar donde sudo esté configurado para modificarlo. He corridofind /etc/sudoers /etc/sysconfig -type f -exec grep env_ {} \;y no encuentro banderas rojas;/etc/sudoerscontiene la únicaenv_cadena Así que no creo que haya una bandera sudoers interfiriendo ...sudo bashdebe iniciar un shell bash como root y DEBE tener la variable SHELL establecida en el valor de / etc / password. Usted informa que SHELL se está configurando en (o se conserva como)/sbin/nologin. Ese es un problema de seguridad, el shell iniciado por root no debe ser controlado por una variable de entorno establecida por un usuario. Eso es algo que debes investigar.Respuestas:
Entonces la respuesta es que
sudotiene un error. Primero, la solución: puse esto en mi/etc/sudoers.d/zabbix file:y ahora subcomandos llamados desde el
zabbix_raid_discoverytrabajo.Un parche para arreglar esto estará en sudo 1.8.15. Del mantenedor, Todd Miller:
Este es solo un caso de "siempre ha sido así". No hay Realmente una buena razón para ello. El diff a continuación debe hacer el comportamiento coincide con la documentación. - todd diff -r adb927ad5e86 plugins / sudoers / env.c --- a / plugins / sudoers / env.c Mar 06 de octubre 09:33:27 2015 -0600 +++ b / plugins / sudoers / env.c Mar Oct 06 10:04:03 2015 -0600 @@ -939,8 +939,6 @@ CHECK_SETENV2 ("USERNAME", runas_pw-> pw_name, ISSET (didvar, DID_USERNAME), verdadero); } más { - if (! ISSET (didvar, DID_SHELL)) - CHECK_SETENV2 ("SHELL", sudo_user.pw-> pw_shell, falso, verdadero); / * Configuraremos LOGNAME más adelante en el caso def_set_logname. * / if (! def_set_logname) { if (! ISSET (didvar, DID_LOGNAME)) @@ -984,6 +982,8 @@ if (! env_should_delete (* ep)) { if (strncmp (* ep, "SUDO_PS1 =", 9) == 0) ps1 = * ep + 5; + else if (strncmp (* ep, "SHELL =", 6) == 0) + SET (didvar, DID_SHELL); más if (strncmp (* ep, "PATH =", 5) == 0) SET (didvar, DID_PATH); más if (strncmp (* ep, "TERM =", 5) == 0) @@ -1039,7 +1039,9 @@ if (reset_home) CHECK_SETENV2 ("INICIO", runas_pw-> pw_dir, verdadero, verdadero); - / * Proporcione valores predeterminados para $ TERM y $ PATH si no están configurados. * / + / * Proporcione valores predeterminados para $ SHELL, $ TERM y $ PATH si no está configurado. * / + if (! ISSET (didvar, DID_SHELL)) + CHECK_SETENV2 ("SHELL", runas_pw-> pw_shell, falso, falso); if (! ISSET (didvar, DID_TERM)) CHECK_PUTENV ("TERM = desconocido", falso, falso); if (! ISSET (didvar, DID_PATH))fuente
Provide default values for $SHELL, $TERM and $PATH if not set.es:... if not set.. Cualquier valor establecido será preservado por sudo. ¿Quién está configurando SHELL?La pregunta era sobre dónde pensé que estaba el problema, pero resulta que el problema no es qué le sucede a la variable SHELL, sino qué hace realmente sudo. Por ejemplo:
Hasta aquí todo bien. ... pero el problema es que sudo usa el shell de la persona que llama en lugar de la persona que llama, a diferencia de los documentos. De hecho, si cambio mi shell editando / etc / passwd, puede ver que sudo sigue el shell de la persona que llama y no
SHELL:No puedo usar
sudo -iporque no quiero simular un inicio de sesión inicial.sudo -sfuncionará, siempre que tenga el comando adecuado en el archivo sudoers. Sin embargo, el comportamiento esperado (como se refleja en la página del manual: "The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables") es que el intérprete de comandos sea el llamado. Si nos fijamos en elPATH,HOME,LOGNAME, yUSERvariables para sudo env verá las cosas de raíz.SHELLdebería ser también la cáscara de la raíz.fuente