web-dev-qa-db-fra.com

Comment empêcher les utilisateurs de Sudo d'exécuter des commandes spécifiques?

J'ai une configuration réseau très sensible et je ne veux vraiment pas gâcher avec. Mon réseau est constitué d'un groupe d'utilisateurs disposant du privilège Sudo.

Je veux les empêcher de courir

service NetworkManager restart
service network restart

commandes.

Y at-il un moyen que je puisse y parvenir?

29
shekhar

Utiliser CmndAlias ​​ALL ne sera jamais en sécurité

Il y a 1000 façons d'exécuter service network restart sans utiliser Sudo service network restart. Voici un exemple de ce qu'un utilisateur méchant pourrait essayer:

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

Si vous fournissez aux utilisateurs l'alias de commande ALL et tentez de créer une liste noire, ils pourront toujours trouver un moyen de contourner le problème. Blacklist bash, et ils utiliseront python. Python Blacklist, et ils vont utiliser 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 ce que Thomas a dit et créer une liste blanche des choses qu'il est autorisé à faire.


Mise en place d'une liste blanche avec une exception

Vous trouverez un exemple de petite liste blanche avec une exclusion au 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 est dangereux et peut être exploité pour changer le mot de passe de root! Voir les commentaires ci-dessous pour savoir comment.)

Nous pouvons essayer d'adapter cela à votre cas, d'offrir toutes les commandes service au groupe de personnel, mais exclureles commandes service network qui vous concernent:

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

(La ALL dans cette position fait référence à Host_Alias, pas à Cmnd_Alias ​​- ce qui est 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. Si vous faites attention, vous pouvez ajouter à la liste blanche plus de commandes d'administrateur pour vos utilisateurs. Soyez juste spécifique!

Remarque: j'ai ajouté le * avant le mot network ci-dessus, juste au cas où un indicateur inoffensif serait ajouté à l'outil service à l'avenir. Imaginons qu'un indicateur --verbose ait été ajouté à l'avenir, les utilisateurs pourront alors exécuter les opérations suivantes:

$ Sudo service --verbose network restart

Nous avons donc besoin du * pour consommer tous les drapeaux avant le nom du service. L’un des inconvénients est que cela pourrait bloquer d’autres services auxquels vous ne dérangez pas les utilisateurs, par exemple un service appelé safe-network ou network-monitor serait également rejeté.


Permettre aux utilisateurs de modifier un fichier à l'aide d'autorisations de groupe

Vous trouverez ci-dessous diverses tentatives d'utilisation de rnano à Sudo pour permettre aux utilisateurs de modifier un fichier ou des fichiers. Mais, en réalité, ils sont plus complexes et plus dangereux qu’ils ne le devraient.

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 des 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 fin (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 de la commande addgroup et y ajouter quelques utilisateurs.


Permettre aux utilisateurs de modifier un fichier avec Sudo

Le reste de cette réponse est devenu une enquête sur la facilité avec laquelle il est facile de laisser des trous dans votre configuration Sudo lorsque vous essayez d'offrir de la flexibilité à vos utilisateurs. Je ne recommanderais aucune des mesures 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 leur permettra uniquement de modifier le fichier spécifié. Cela est important pour empêcher un utilisateur malveillant d’éditer un autre service de démarrage (par exemple, /etc/init.d/urandom) et d’y ajouter une ligne qui exécuterait service network restart.

Malheureusement, je n'ai pas trouvé le moyen de restreindre suffisamment rvim (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 éditer plusieurs fichiers (bien 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 toute flexibilité), vous pouvez l'exploiter:

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

Dans ce cas, un utilisateur malveillant pourrait éditer n'importe quel autre script de service upstart, puis l'exécuter:

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

(Sudo empêche effectivement le développement de . et .. sur la commande, mais malheureusement pas sur les arguments.)

J'espérais que quelque chose comme cela pourrait fonctionner, mais c'est toujours pas sûr:

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

Étant donné que Sudo ne propose actuellement que des modèles globaux , que * correspond à tout/ - ce n'est pas une expression rationnelle !

(Edit: j’ai envisagé si vous pourriezvous échapper avec ce qui précède dans votre situation, car il n’existe aucun sous-dossier sous sites-available. Nous avons demandé qu’un caractère soit apparié 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. De toute façon, ce serait toujours dangereux sur un dossier contenant des sous-dossiers!)

Même si nous n’avons pas de sous-dossiers et que nous excluons les lignes contenant /../, la règle offrant un * glob peut toujours être exploitée, car rnano accepte plusieurs arguments (en les passant sur <C-X>, et l’espace est accepté avec joie par le * glob.

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

2. Pousser l'enveloppe (aussi finalement dangereux)

Alors que se passe-t-il si nous rejetons les lignes contenant des espaces ou essayons d’atteindre /..? Ensuite, une solution réalisable finale pourrait être la suivante:

# 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 ce qui est "sous" le dossier, mais nous refusons également tout appel à rnano si /.. ou /. ou sont passés, ou si le dossier est directement ciblé. (Techniquement, l’exclusion /. rend l’exclusion /.. redondante, mais j’ai laissé les deux pour plus de clarté.)

J'ai trouvé le dossier et les exclusions /. étaient nécessaires, sinon l'utilisateur pourrait cibler le dossier lui-même. Maintenant, vous pourriez penser que rnano bloquerait s'il était dirigé 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 <C-X> me demande de saisir le nom de fichier que je préfère pour enregistrer dans un nouveau vecteur d’attaque! Eh bien au moins, il a refusé d'écraser un fichier existant (dans le test que j'ai fait). Quoi qu’il en soit, comme il n’ya aucun moyen de mettre en liste noire les sous-dossiers avec Sudo, nous devons en conclure que cette approche est à nouveau dangereuse. Désolé les utilisateurs!

Cette découverte m'a fait douter de la minutie du mode "restreint" de nano. Ils disent qu'une chaîne est aussi forte que son maillon le plus faible. Je commence à sentir que la combinaison de Sudo blacklist black-magic et de rnano n'est peut-être pas plus sûre qu'une chaîne de marguerites.

3. Approches sûres mais limitées

Les Globs sont très limités - ils ne nous permettent pas de faire correspondre une classe de personnage plusieurs fois. Vous pourriezproposer plusieurs modifications de fichier si tous vos noms de fichier 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 voulez donner à l'utilisateur le droit de modifier différents 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é d'utiliser un * à tout moment. Voir les sections 1. et 2. ci-dessus pour savoir pourquoi! N'oubliez pas qu'un seul petit feuillet peut compromettre l'intégralité du compte superutilisateur et du système.

4. Écrivez votre propre correcteur d'arguments (la sécurité est maintenant de votre responsabilité)

J'espère qu'ils ajouteront un support d'expression régulière à Sudo dans le futur; cela pourrait résoudre beaucoup de problèmes si utilisé correctement. Mais nous pouvons aussi avoir besoin de pouvoir vérifier les propriétés des arguments (pour n’autoriser que les fichiers, que les dossiers ou seulement certains drapeaux).

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 script ou exécutable staffedit pour vérifier si les arguments passés par l'utilisateur sont légaux et exécutez uniquement leur requête, le cas échéant.

46
joeytwiddle

Commencez par ouvrir le fichier sudoers avec Sudo visudo. L'ajout de user ALL=!/usr/sbin/service will, IIRC, interdit la commande service pour l'utilisateur user.

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

5
Zeb McCorkle

J'ai trouvé la solution.

J'ai ouvert le terminal et je passe en utilisateur root avec su - puis j'ai saisi visudo pour le 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 sauvegardé & fermé et redémarré aussi.

Maintenant, si je tape en tant que service network restart ou service NetworkManager restart, sa 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 la commande service network restart également.

5
shekhar

La vraie réponse à cela est que vous ne pouvez pas vraiment empêcher cela. Vous pouvez empêcher une personne mal intentionnée d'exécuter cette commande par accident via les méthodes décrites dans les autres réponses, mais si quelqu'un souhaite réellement l'exécuter et qu'il figure dans la liste des sudoers, il peut l'exécuter. Par exemple, ils pourraient faire ce qui suit:

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

Ou une autre commande amusante qu'ils pourraient utiliser pour contourner vos restrictions dans le fichier sudoers:

Sudo visudo

En bref, si vous savez utiliser Sudo et que cela ne se limite pas à exécuter des commandes particulières, vous pouvez faire à peu près tout ce que vous voulez. Même si vous les limitez à un ensemble de commandes donné, vous devez vous assurer qu'il n'est pas possible à l'utilisateur de copier une autre commande qu'il souhaite exécuter sous le même nom que celui pour lequel il disposait de l'autorisation ( comme en écrasant la commande qu’ils ont la permission d’exécuter.)

3
reirab

Utilisez firejail pour restreindre les utilisateurs avec des sandbox.

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

Définissez firejail comme Shell au lieu de bash dans/etc/passwd, pour chaque utilisateur à restreindre. Il est très facile à utiliser et possède une bonne documentation.

Exemple:

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