Usar CmndAlias ALL
nunca será seguro
Hay 1000 formas de correr service network restart
sin 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 ALL
alias 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 service
comandos al grupo de personal, pero excluir los service network
comandos que le conciernen:
%staff ALL = /usr/sbin/service *, \
! /usr/sbin/service *network*, \
! /usr/sbin/service *NetworkManager*
(El ALL
en esa posición se refiere al Host_Alias, no al Cmnd_Alias, confuso, ¿no?)
El usuario no podrá ejecutar sudo bash
o sudo tee
o sudo wget
o 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 network
anterior a la anterior, en caso de que alguna vez se agregue una bandera inofensiva a la service
herramienta en el futuro. Imaginemos --verbose
que 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-network
o network-monitor
también sería rechazado.
Permitir a los usuarios editar un archivo usando permisos de grupo
A continuación puede encontrar varios intentos de utilizar rnano
a través de sudo
dejar 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 addgroup
comando 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 sudo
configuració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
rnano
solo 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 rvim
suficiente (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 sudo
actualmente 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 rnano
acepta 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 rnano
acepta 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 rnano
si /..
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 rnano
se 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 nano
modo "restringido". Dicen que una cadena es tan fuerte como su eslabón más débil. Estoy empezando a sentir la combinación de sudo
la magia negra de la lista negra y rnano
puede 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, host
seguido 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 sudo
en 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 staffedit
script o ejecutable para verificar si los argumentos pasados por el usuario son legales, y solo lleve a cabo su solicitud si lo son.
networking
ynetwork-manager
? Además, ¿por qué sus usuarios tienensudo
acceso? No deberían, a menos que quieras que tengan todos los privilegios de root.