Utilisation de CmndAlias ALL
ne sera jamais en sécurité
Il y a 1000 façons d'exécuter service network restart
sans faire sudo service network restart
. Voici un exemple de ce qu'un utilisateur malveillant pourrait essayer :
$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax
Si vous fournissez aux utilisateurs le ALL
alias de commande, puis essayez de créer une liste noire, ils seront toujours en mesure de trouver un moyen de la contourner. Blacklist bash, et ils utiliseront python. Blacklist python, et ils utiliseront Perl. Blacklist Perl, et ils utiliseront PHP. Personne ne veut ça !
Si vous ne voulez vraiment pas que quelqu'un fasse quelque chose, vous devriez faire comme Thomas le dit et créer une liste blanche des choses qu'ils sont autorisé à faire.
Configurer une liste blanche avec une exception
Un exemple de petite liste blanche avec une exclusion peut être trouvé près du bas 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.
(En fait, cet exemple de la page de manuel n'est pas sûr et peut être exploité pour changer le mot de passe de root ! Voir les commentaires ci-dessous pour savoir comment faire.)
Nous pouvons essayer d'adapter cela à votre cas, pour offrir tous les service
commandes au groupe du personnel, mais exclure le service network
commandes qui vous concernent :
%staff ALL = /usr/sbin/service *, \
! /usr/sbin/service *network*, \
! /usr/sbin/service *NetworkManager*
(Le ALL
dans cette position fait référence à Host_Alias, pas à Cmnd_Alias - déroutant n'est-ce pas ?)
L'utilisateur ne pourra pas exécuter sudo bash
ou sudo tee
ou sudo wget
ou sudo /path/to/malicious_script
. Vous pouvez mettre en liste blanche plus de commandes d'administration pour vos utilisateurs si vous êtes prudent. Soyez juste précis !
Remarque :j'ai ajouté le *
avant le mot network
ci-dessus, juste au cas où un indicateur inoffensif serait ajouté au service
outil à l'avenir. Imaginons un --verbose
drapeau a été ajouté à l'avenir, les utilisateurs pourront alors exécuter ce qui suit :
$ sudo service --verbose network restart
Nous avons donc besoin du *
pour consommer tous les drapeaux avant le nom du service. Le seul inconvénient est que cela peut bloquer d'autres services qui ne vous dérangent pas vraiment, par ex. un service appelé safe-network
ou network-monitor
serait également rejeté.
Autoriser les utilisateurs à modifier un fichier à l'aide des autorisations de groupe
Vous trouverez ci-dessous différentes tentatives utilisant rnano
via sudo
pour permettre aux utilisateurs de modifier un ou plusieurs fichiers. Mais en réalité, ils sont plus complexes et plus dangereux qu'ils ne devraient l'être.
Une solution beaucoup plus simple et plus sûre consiste à modifier les autorisations de groupe sur les fichiers spécifiques pour lesquels vous souhaitez ouvrir les droits de modification. Voici quelques exemples :
### 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 vous avez besoin d'un contrôle plus précis (par exemple :accès pour seulement 3 utilisateurs, mais pas pour tous les membres du personnel), vous pouvez créer un nouveau groupe à l'aide du addgroup
commande et n'y ajoutez que quelques utilisateurs.
Autoriser les utilisateurs à modifier un fichier via sudo
Le reste de cette réponse est devenu une enquête sur la facilité avec laquelle il est possible de laisser des trous dans votre sudo
configuration lorsque vous essayez d'offrir de la flexibilité à vos utilisateurs. Je ne recommanderais aucune des actions suivantes !
Si vous souhaitez autoriser vos utilisateurs à modifier un fichier spécifique, vous pouvez essayer d'utiliser rnano
:
%staff ALL = /bin/rnano /etc/nginx/sites-available/host
rnano
ne les laissera modifier que le fichier spécifié. C'est important pour empêcher un utilisateur malveillant de modifier un autre service parvenu (par exemple /etc/init.d/urandom
), et en y ajoutant une ligne qui exécuterait service network restart
.
Malheureusement, je n'ai pas trouvé de moyen de restreindre rvim
suffisamment (l'utilisateur peut toujours ouvrir n'importe quel fichier en utilisant :e
), nous sommes donc bloqués avec nano
.
Malheureusement, permettre aux utilisateurs de modifier plusieurs fichiers est beaucoup plus difficile...
Laissez les utilisateurs modifier plusieurs fichiers (beaucoup plus difficile qu'il ne devrait l'être)
1. Approches dangereuses
Attention aux caractères génériques ! Si vous offrez trop de flexibilité (ou n'importe quelle flexibilité), elle peut être exploitée :
%staff ALL = /bin/rnano /etc/nginx/sites-available/* # UNSAFE!
Dans ce cas, un utilisateur malveillant pourrait modifier n'importe quel autre script de service parvenu, puis l'exécuter :
$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system
(Sudo empêche en fait .
et ..
développement sur la commande, mais malheureusement pas sur les arguments.)
J'espérais que quelque chose comme ça pourrait fonctionner, mais ce n'est toujours pas sûr :
%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]* # UNSAFE!
Depuis sudo
ne propose actuellement que glob modèles, que *
correspondra à tout - ce n'est pas une expression rationnelle !
(Edit :j'ai réfléchi si vous pourriez partez avec ce qui précède dans votre situation, car il n'y a pas de sous-dossiers sous sites-available
. Nous avons demandé qu'un caractère soit mis en correspondance après le dossier, et /..
devrait échouer après un nom de fichier. Cependant, ce n'est pas une solution viable, car rnano
accepte plusieurs arguments. Et de toute façon, en général, ce serait toujours dangereux sur un dossier qui avait des sous-dossiers !)
Même si nous n'avons pas de sous-dossiers et que nous excluons toutes les lignes contenant /../
, la règle offrant un *
glob pourrait encore être exploité, car rnano
accepte plusieurs arguments (en les parcourant sur <C-X>
, et l'espace est accepté avec plaisir par le *
global.
$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system
2. Repousser les limites (également finalement dangereux)
Et si nous rejetons toutes les lignes contenant des espaces ou tentant d'atteindre /..
? Alors une solution finale réalisable pourrait être celle-ci :
# 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.
Nous acceptons tout "sous" le dossier mais nous rejetons également tout appel au rnano
si /..
ou /.
ou sont passés, ou si le dossier est ciblé directement. (Techniquement le
/.
l'exclusion rend le /..
exclusion redondante, mais j'ai laissé les deux pour plus de clarté.)
J'ai trouvé le dossier et le /.
des exclusions étaient nécessaires car sinon l'utilisateur pourrait cibler le dossier lui-même. Maintenant, vous pourriez penser rnano
bloquerait si pointé vers un dossier, mais vous auriez tort. En fait ma version (2.2.6-1ubuntu1) démarre avec un léger avertissement et un fichier vide, puis sur <C-X>
me demande de saisir n'importe quel nom de fichier que j'aime pour enregistrer, ouvrant un nouveau vecteur d'attaque ! Eh bien, au moins, il a refusé d'écraser un fichier existant (dans le seul test que j'ai fait). Quoi qu'il en soit, puisqu'il n'y a aucun moyen de mettre les sous-dossiers sur liste noire avec sudo, nous devons conclure que cette approche est à nouveau dangereuse. Désolé les utilisateurs !
Cette découverte m'a fait douter de la rigueur de nano
mode "restreint". On dit qu'une chaîne n'est aussi solide que son maillon le plus faible. Je commence à ressentir la combinaison de sudo
liste noire magie noire et rnano
n'est peut-être pas plus sûr qu'une chaîne de marguerites.
3. Approches sûres mais limitées
Les globs sont très restreints - ils ne nous permettent pas de faire correspondre plusieurs fois une classe de personnage. Vous pourriez proposer plusieurs éditions de fichiers, si tous vos noms de fichiers ont la même longueur (dans ce cas host
suivi d'un seul chiffre) :
%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9] # SAFE
Mais si vous souhaitez autoriser l'utilisateur à modifier divers fichiers, vous devrez peut-être spécifier explicitement chaque fichier :
%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
Ne soyez pas tenté utiliser un *
à tout moment. Voir les sections 1. et 2. ci-dessus pour savoir pourquoi ! N'oubliez pas :un petit glissement peut compromettre l'ensemble du compte de superutilisateur et l'ensemble du système.
4. Écrivez votre propre vérificateur d'arguments (la sécurité est désormais votre responsabilité)
J'espère qu'ils ajouteront le support des expressions régulières à sudo
à l'avenir; il pourrait résoudre beaucoup de problèmes s'il est utilisé correctement. Mais nous pouvons également avoir besoin de la possibilité de vérifier les propriétés des arguments (pour autoriser uniquement les fichiers, uniquement les dossiers ou uniquement certains indicateurs).
Mais il existe une alternative pour créer de la flexibilité dans sudo. Passez la balle :
%staff ALL = /root/bin/staffedit *
Ensuite, écrivez votre propre staffedit
script ou exécutable pour vérifier si les arguments passés par l'utilisateur sont légaux, et n'exécutent leur demande que s'ils le sont.
Tout d'abord, ouvrez le fichier sudoers avec sudo visudo
. Ajout de user ALL=!/usr/sbin/service
va, IIRC, interdire le service
commande pour l'utilisateur user
.
Source :http://nixcraft.com/showthread.php/15132-Sudo-Exclude-Commands-And-Disable-sudo-su-Bash-Shell
J'ai trouvé la solution.
J'ai ouvert le terminal et changé en utilisateur root avec su -
puis j'ai tapé visudo
à modifier.
puis à la fin j'ai écrit des lignes comme
user ALL=!/etc/init.d/NetworkManager restart
user ALL=!/etc/init.d/network restart
Ensuite, j'ai enregistré, fermé et redémarré aussi.
Maintenant, si je tape comme service network restart
ou service NetworkManager restart
alors cela ne me permet pas et donne une erreur comme
Sorry user is not allowed to execute '/sbin/service NetowkrManager restart' as root on localhost.localdomain
et de même pour service network restart
commande aussi.