¿Cómo evitar que los usuarios de sudo ejecuten comandos específicos?

29

Tengo una configuración de red muy sensible y realmente no quiero estropearla. Mi red consta de un grupo de usuarios que tienen privilegios de sudo.

Quiero evitar que corran

service NetworkManager restart
service network restart

comandos

¿Hay alguna manera de lograr esto?

shekhar
fuente
¿Qué distribución estás usando? Los nombres de los servicios son específicos de la distribución y no conozco ninguna distribución que use los nombres que tiene allí. ¿Quieres decir networkingy network-manager? Además, ¿por qué sus usuarios tienen sudoacceso? No deberían, a menos que quieras que tengan todos los privilegios de root.
terdon
@terdon lo he resuelto. Gracias. No puedo publicarlo como respuesta porque soy un usuario nuevo
shekhar
Sí puedes, por favor hazlo. También me gustaría saber la respuesta que encontraste.
terdon
@terdon seguro, pero dice que debo esperar 8 horas para publicar mi propia respuesta porque no tengo ni siquiera 10 reputación
shekhar
1
Ah, sí, lo siento, tienes que esperar. Acabo de votar, tienes el representante ahora :)
terdon

Respuestas:

47

Usar CmndAlias ALLnunca será seguro

Hay 1000 formas de correr service network restartsin hacerlo sudo service network restart. Aquí hay un ejemplo de lo que un usuario travieso podría intentar:

$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax

Si proporciona a los usuarios el ALLalias de comando y luego intenta crear una lista negra, siempre podrán encontrar una forma de evitarlo. Blacklist bash, y usarán python. Pitón lista negra, y usarán Perl. Blacklist Perl, y usarán PHP. Nadie quiere eso!

Si realmente no desea que alguien haga algo, debe hacer lo que dice Thomas y crear una lista blanca de las cosas que tiene permitido hacer.


Configurar una lista blanca con una excepción

Un ejemplo de una pequeña lista blanca con una exclusión se puede encontrar cerca de la parte inferior de man sudoers:

 pete           HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root

The user pete is allowed to change anyone's password except for root on the HPPA
machines.  Note that this assumes passwd(1) does not take multiple user names
on the command line.

(¡De hecho, este ejemplo de la página de manual no es seguro y puede explotarse para cambiar la contraseña de root! Vea los comentarios a continuación para saber cómo hacerlo).

Podemos intentar adaptar eso a su caso, para ofrecer todos los servicecomandos al grupo de personal, pero excluir los service networkcomandos que le conciernen:

%staff ALL =   /usr/sbin/service *,                            \
             ! /usr/sbin/service *network*,                    \
             ! /usr/sbin/service *NetworkManager*

(El ALLen esa posición se refiere al Host_Alias, no al Cmnd_Alias, confuso, ¿no?)

El usuario no podrá ejecutar sudo basho sudo teeo sudo wgeto sudo /path/to/malicious_script. Puede poner en la lista blanca más comandos de administración para sus usuarios si tiene cuidado. ¡Solo sé específico!

Nota: Agregué la *palabra networkanterior a la anterior, en caso de que alguna vez se agregue una bandera inofensiva a la serviceherramienta en el futuro. Imaginemos --verboseque se agregó una bandera en el futuro, luego los usuarios podrán ejecutar lo siguiente:

$ sudo service --verbose network restart

Por lo tanto, necesitamos *consumir cualquier indicador antes del nombre del servicio. La única desventaja es que esto podría bloquear otros servicios que en realidad no le importa que ejecuten los usuarios, por ejemplo, un servicio llamado safe-networko network-monitortambién sería rechazado.


Permitir a los usuarios editar un archivo usando permisos de grupo

A continuación puede encontrar varios intentos de utilizar rnanoa través de sudodejar que los usuarios editar un archivo o archivos. Pero en realidad son más complejos y más peligrosos de lo que deberían ser.

Una solución mucho más simple y segura es cambiar los permisos de grupo en los archivos específicos para los que desea abrir los derechos de edición. Aquí hay un par de ejemplos:

### Give steve the ability to edit his nginx config:
$ chgrp steve /etc/nginx/sites-available/steves_dodgy_project
$ chmod g+rw /etc/nginx/sites-available/steves_dodgy_project

### Let all members of the staff group edit the group_website config:
$ chgrp staff /etc/nginx/sites-available/group_website
$ chmod g+rw /etc/nginx/sites-available/group_website

Si necesita un control más detallado (por ejemplo: acceso para solo 3 usuarios, pero no para todos los miembros del personal), puede crear un nuevo grupo con el addgroupcomando y agregarle unos pocos usuarios.


Permitir a los usuarios editar un archivo a través de sudo

El resto de esta respuesta se convirtió en una investigación sobre lo fácil que es dejar agujeros en su sudoconfiguración al intentar ofrecer flexibilidad a sus usuarios. ¡No recomendaría hacer nada de lo siguiente!

Si desea otorgar a sus usuarios acceso para editar un archivo específico, puede intentar usar rnano:

%staff ALL = /bin/rnano /etc/nginx/sites-available/host

rnanosolo les permitirá editar el archivo especificado. Eso es importante para evitar que un usuario malintencionado edite un servicio de inicio diferente (por ejemplo /etc/init.d/urandom) y agregue una línea que se ejecute service network restart.

Desafortunadamente, no encontré una manera de restringir lo rvimsuficiente (el usuario aún puede abrir cualquier archivo usando :e), por lo que estamos atascados nano.

Desafortunadamente, permitir que los usuarios editen múltiples archivos es mucho más difícil ...


Permita que los usuarios editen múltiples archivos (mucho más difícil de lo que debería ser)

1. Enfoques inseguros

¡Cuidado con los comodines! Si ofrece demasiada flexibilidad (o cualquier flexibilidad), puede explotarse:

%staff ALL = /bin/rnano /etc/nginx/sites-available/*                # UNSAFE!

En este caso, un usuario malintencionado podría editar cualquier otro script de servicio inicial y luego ejecutarlo:

$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system

(Sudo realmente previene .y ..expande el comando, pero desafortunadamente no en los argumentos).

Esperaba que algo como esto pudiera funcionar, pero aún es inseguro:

%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]*   # UNSAFE!

Dado que sudoactualmente solo ofrece patrones globales , eso *coincidirá con cualquier cosa , ¡no es una expresión regular!

(Editar: consideré si podría salirse con la suya en su situación, porque no hay subcarpetas debajo sites-available. Exigimos que coincida un carácter después de la carpeta, y /..debería fallar después de un nombre de archivo. Sin embargo, esto no es un solución viable, porque rnanoacepta múltiples argumentos. ¡Y de todos modos, en general, esto todavía sería inseguro en una carpeta que tenía subcarpetas!)

Incluso si no tenemos subcarpetas, y excluimos cualquier línea que contenga /../, la regla que ofrece un *glob aún podría ser explotada, porque rnanoacepta múltiples argumentos (recorriéndolos <C-X>y el espacio es felizmente aceptado por el *glob.

$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system

2. Empujar el sobre (también en última instancia inseguro)

Entonces, ¿qué pasa si rechazamos cualquier línea que contenga espacios o intentemos alcanzar /..? Entonces, una solución viable final podría ser esta:

# I tried hard to make this safe, but in the end I failed again.
# Please don't use this unless you are really smart or really stupid.

%staff ALL =   /bin/rnano /etc/nginx/sites-available/*,    \
             ! /bin/rnano */..*,                           \
             ! /bin/rnano /etc/nginx/sites-available/,     \
             ! /bin/rnano */.,                             \
             ! /bin/rnano * *

# CONCLUSION: It is still NOT SAFE if there are any subfolders, due to
# the bug in rnano described below.

Aceptamos nada "debajo" de la carpeta, pero también rechazamos cualquier llamada a rnanosi /..o /.o se le pasen, o si la carpeta está dirigido directamente. (Técnicamente, la /.exclusión hace que la /..exclusión sea redundante, pero he dejado a ambos por claridad).

Encontré la carpeta y las /.exclusiones eran necesarias porque de lo contrario el usuario podría apuntar a la carpeta en sí. Ahora podría pensar que rnanose bloquearía si apuntara a una carpeta, pero estaría equivocado. En realidad, mi versión (2.2.6-1ubuntu1) comienza con una advertencia leve y un archivo vacío, luego <C-X>me pide que ingrese cualquier nombre de archivo que quiera guardar, ¡abriendo un nuevo vector de ataque! Bueno, al menos se negó a sobrescribir un archivo existente (en la única prueba que hice). De todos modos, dado que no hay forma de poner en la lista negra subcarpetas con sudo, debemos concluir que este enfoque es nuevamente inseguro. Lo sentimos usuarios!

Este descubrimiento me hizo dudar de la minuciosidad del nanomodo "restringido". Dicen que una cadena es tan fuerte como su eslabón más débil. Estoy empezando a sentir la combinación de sudola magia negra de la lista negra y rnanopuede que no sea más seguro que una cadena de margaritas.

3. Enfoques seguros pero limitados

Los globos son muy restringidos: no nos permiten igualar una clase de personaje varias veces. Usted podría ofrecer múltiples ediciones de archivos, si todos los nombres de archivo tienen la misma longitud (en este caso, hostseguido de un solo dígito):

%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9]       # SAFE

Pero si desea otorgarle al usuario acceso para editar varios archivos, es posible que deba especificar cada archivo explícitamente:

%staff ALL = /bin/rnano /etc/nginx/sites-available/hothost    \
             /bin/rnano /etc/nginx/sites-available/coldhost   \    # SAFE
             /bin/rnano /etc/nginx/sites-available/wethost    \
             /bin/rnano /etc/nginx/sites-available/steves_dodgy_project

No se sienta tentado a usar un*en ningún momento. ¡Vea las secciones 1. y 2. arriba para saber por qué! Recuerde: un pequeño desliz puede comprometer toda la cuenta de superusuario y todo el sistema.

4. Escriba su propio verificador de argumentos (la seguridad es ahora su responsabilidad)

Espero que agreguen soporte de regexp sudoen el futuro; podría resolver muchos problemas si se usa correctamente. Pero también es posible que necesitemos la capacidad de verificar las propiedades de los argumentos (para permitir solo archivos, solo carpetas o solo ciertos indicadores).

Pero hay una alternativa para crear flexibilidad en sudo. Pasar la pelota:

%staff ALL = /root/bin/staffedit *

Luego escriba su propio staffeditscript o ejecutable para verificar si los argumentos pasados ​​por el usuario son legales, y solo lleve a cabo su solicitud si lo son.

joeytwiddle
fuente
55
Esta respuesta tomó mucho tiempo, pero finalmente creo que entiendo cómo funciona sudo. Me rendí en varias ocasiones en el pasado, encontrándome ALL=(ALL:ALL) ALLdemasiado carente de semántica, pero siempre asumí que en algún lugar tendría un verificador de argumentos decente ... Me equivoqué. Es realmente muy limitado. Incluso la exclusión passwd root que se ofrece en la página de manual se puede romper con un simple argumento de línea de comandos, sudo passwd -q root. Bueno, los autores de sudo enumeran [algunas alternativas] (sudo.ws/sudo/other.html) en su sitio web. Espero que agreguen soporte de regexp en el futuro.
joeytwiddle
¿Usas específicamente rnanoen tu descripción aquí porque es una versión de nano que carece de la función 'guardar como'? No estoy familiarizado con el programa.
Shadur
Sí. Si nos preocupamos por la seguridad, el editor solo debería editar el archivo especificado y no debería poder abrir un shell. Para información, $ man nanoentonces/-R<Enter>
joeytwiddle
Corrección: Para romper el ejemplo Pete, la -qtiene que venir después: sudo passwd root -q. El ejemplo de pete se puede endurecer excluyendo *root*.
joeytwiddle
Considere usar sudoeditpara habilitar de forma segura la modificación de archivos con sudo.
Totor
5

Primero, abra el archivo sudoers con sudo visudo. Agregar user ALL=!/usr/sbin/servicewill, IIRC, no permitirá el servicecomando para el usuario user.

Fuentes: http://nixcraft.com/showthread.php/15132-Sudo-Exclude-Commands-And-Disable-sudo-su-Bash-Shell

Zeb McCorkle
fuente
Esto dejará de ejecutar otros servicios también y no quiero eso. Gracias por la respuesta. :)
shekhar
mientras que su respuesta no me ayudó exactamente, pero ayudó a encontrar una solución, gracias. pero sabes dar tu voto positivo o publicar mi respuesta de trabajo No tengo suficiente reputación. Seguramente le daré las gracias una vez que lo esté. Gracias.
shekhar
2
Sí, pero aún así, como han dicho otros, debes tener mucho cuidado con eso. Hay muchas formas de obtener acceso. Cualquier comando que pueda generar un caparazón, etc. Es mucho más fácil descubrir qué comandos realmente necesitan y permitirles, en lugar de tratar de excluir todos los "prohibidos".
Bonsi Scott
3
Las listas blancas son imposibles de mantener en muchos escenarios. El objetivo real puede no ser evitar que hagan algo, sino evitar que hagan algo malo por error sin restringirlo. Las listas negras son buenas en estos casos. Usted pone en una lista negra las formas en que un usuario razonable realizaría la tarea. Pero las listas negras a través de sudo pueden no ser suficientes: las personas pueden y usan 'sudo bash'. Un enfoque sería envolver el comando 'servicio' y, en los casos en que no desee que lo usen, infórmeles. Pero nunca enumerará todas las acciones buenas en una lista blanca, ni todas las malas en una lista negra.
Bob Kerns
1
Estoy de acuerdo contigo Bob. Para permitir la flexibilidad, sin permitir el acceso completo, a menudo necesitará lanzar su propia solución, como un script auxiliar, y solo incluir ese script en la lista blanca. Las listas blancas de sudo pueden hacer lo que necesita, pero a menudo serán demasiado limitadas o demasiado fáciles de explotar.
joeytwiddle
5

He encontrado la solución.

Abrí la terminal y cambié a usuario root con, su -luego escribí visudopara editar.

entonces al final he escrito líneas como

user ALL=!/etc/init.d/NetworkManager restart
user ALL=!/etc/init.d/network restart

Luego tengo guardar y cerrar y reiniciar también.

Ahora si estoy escribiendo como service network restarto service NetworkManager restartentonces no me está permitiendo y dando un error como

Sorry user is not allowed to execute '/sbin/service NetowkrManager restart' as root on localhost.localdomain

y de manera similar para el service network restartcomando también.

shekhar
fuente
12
Eso funcionará para usuarios inexpertos y poco maliciosos, pero es fácil eludir las restricciones de sudo (por ejemplo, sudo cp -p /etc/init.d/network /etc/init.d/network-not-in-sudoy luego sudo /etc/init.d/network-not-in-sudo restart). Es por eso que es mucho más seguro crear inclusiones en lugar de exclusiones en el archivo sudoers, por ejemplo, indicar con qué servicios pueden interactuar.
Thomas
Todo lo que hace el "reinicio de la red de servicio" lo puede hacer con otros comandos, como los que se encuentran en el script de red init.d. Ni siquiera intentaré enumerarlos aquí. Pero si desea, por ejemplo, evitar realmente las modificaciones del estado de la interfaz, una política de SELinux me parece el camino a seguir. Es un tema complejo, pero cuando una lista blanca es demasiado restrictiva o onerosa, y una lista negra es inadecuada, probablemente sea su mejor opción. Se implementa en el núcleo y le permite restringir el acceso a las interfaces de red (y otros recursos) incluso a los usuarios sudo'd.
Bob Kerns
Si es posible con SELinux, estaría más contento. @BobKerns Gracias. Lo intentaré de esa manera.
shekhar
3

La verdadera respuesta a esto es que realmente no puedes evitar esto. Puede evitar que alguien no malintencionado ejecute accidentalmente ese comando a través de los métodos descritos en las otras respuestas, pero si alguien realmente quiere ejecutarlo y está en la lista de sudoers, puede ejecutarlo. Por ejemplo, podrían hacer lo siguiente:

joe@box:~$ sudo bash root@box:~# service network restart

U otro comando divertido que podrían usar para eludir sus restricciones en el archivo sudoers:

sudo visudo

En pocas palabras, si puede sudo y no se limita a ejecutar comandos particulares, puede hacer casi lo que quiera. Incluso si los restringe a un conjunto dado de comandos, deberá asegurarse de que el usuario no pueda copiar algún otro comando que quisiera ejecutar con el mismo nombre que tenía permiso para ejecutar ( como sobrescribiendo el comando que tienen permiso para ejecutar).

reirab
fuente
Sí. Uno debe evitar los comandos que pueden generar un caparazón desde dentro.
Bonsi Scott
1
El problema es que no son los comandos los que desea proteger, sino el estado de los objetos del núcleo, como las tablas de enrutamiento, las interfaces, etc., sin importar qué comando (o llamada al sistema) se use. Y desea protegerlo de algunos, pero no de todos, usuarios root. SELinux está diseñado en torno a este tipo de escenario. Pero primero, comenzaría con una revisión de por qué todos estos usuarios tienen acceso a sudo. Si solo necesitan hacer algunas cosas específicas, las operaciones de lista blanca en sudoers pueden ser todo lo que necesita.
Bob Kerns
2

Use firejail para restringir a los usuarios con sandboxes.

https://github.com/netblue30/firejail/

Establezca firejail como shell en lugar de bash en / etc / passwd, para cada usuario que desee restringir. Es muy fácil de usar y tiene una buena documentación.

Ejemplo:

user:x:1000:1000:user:/home/user:/usr/bin/firejail
Jeff
fuente