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

J'ai une configuration de réseau très sensible et je ne veux vraiment pas l'immerger. Mon réseau consiste en un tas d'utilisateurs qui possèdent un privilège sudo.

Je veux les empêcher de courir

service NetworkManager restart service network restart 

Commandes.

Y a-t-il une façon d'y parvenir?

À l'aide de CmndAlias ALL ne sera jamais en sécurité

Il existe 1000 façons d'exécuter le service network restart sans 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 la commande ALL , puis essayez de créer une liste noire, ils seront toujours en mesure de trouver un moyen de le contourner. Blacklist bash, et ils utiliseront Python. Blacklist python, et ils utiliseront Perl. Blacklist Perl, et ils utiliseront PHP. Personne ne le veut!

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 de choses qu'ils sont autorisés à faire.


Configuration d'une liste blanche avec une exception

Un exemple d'une petite liste blanche avec une exclusion peut être trouvé près du bas des 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 à partir de la page de manuel est dangereux et peut être exploité pour changer le mot de passe de la racine! Consultez les commentaires ci-dessous pour savoir comment).

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

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

(L' ALL dans cette position se réfère à Host_Alias, et non à Cmnd_Alias ​​- confus 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 créer une liste blanche d'autres commandes d'administration pour vos utilisateurs si vous faites attention. Soyez précis!

Remarque: J'ai ajouté le * avant le mot network ci-dessus, au cas où un drapeau inoffensif serait ajouté à l'outil de service à l'avenir. Imaginons qu'un --verbose drapeau a été ajouté à l'avenir, alors les utilisateurs pourraient exécuter ce qui suit:

 $ sudo service --verbose network restart 

Nous avons donc besoin de * pour consommer des drapeaux avant le nom du service. L'un des inconvénients est que cela pourrait bloquer d'autres services que vous n'êtes pas réellement affectés par les utilisateurs, par exemple, un service appelé safe-network ou network-monitor serait également rejeté.


Laissez les utilisateurs modifier un fichier en utilisant les autorisations de groupe

Vous trouverez ci-dessous plusieurs tentatives en utilisant rnano via sudo pour permettre aux utilisateurs de modifier un fichier ou des fichiers. Mais ils sont vraiment plus complexes et plus dangereux qu'ils ne le devraient.

Une solution beaucoup plus simple et sûre est de modifier les autorisations de groupe sur les fichiers spécifiques dont vous souhaitez ouvrir les droits d'édition. 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 tous les membres du personnel), vous pouvez créer un nouveau groupe à l'aide de la commande addgroup , et n'en ajouter que quelques utilisateurs.


Laissez les utilisateurs modifier un fichier via sudo

Le reste de cette réponse est devenu une enquête sur la facilité avec laquelle il faut laisser des trous dans votre configuration de sudo lorsque vous tentez d'offrir une flexibilité à vos utilisateurs. Je ne recommanderais pas l'une des choses suivantes.

Si vous souhaitez accorder à vos utilisateurs l'accès à l'édition d'un fichier spécifique, vous pouvez essayer d'utiliser rnano :

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

rnano ne leur permettra que de modifier le fichier spécifié. Il est important d'empêcher un utilisateur malveillant d'éditer un autre service de démarrage (par exemple /etc/init.d/urandom ) et d'ajouter une ligne qui entraînerait le service network restart .

Malheureusement, je n'ai pas trouvé un moyen de restreindre suffisamment les rvim (l'utilisateur peut encore ouvrir un fichier en utilisant :e ), donc nous sommes bloqués avec nano .

Malheureusement, les utilisateurs peuvent modifier plusieurs fichiers est beaucoup plus difficile …


Laissez les utilisateurs modifier plusieurs fichiers (beaucoup plus difficiles qu'il ne le devrait)

1. Approches dangereuses

Faites attention aux caractères génériques! Si vous offrez trop de flexibilité (ou toute flexibilité), elle peut être exploitée:

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

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

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

(Sudo empêche effectivement . Et .. expansion sur la commande, mais malheureusement pas sur les arguments.)

J'espérais que quelque chose comme ça pourrait fonctionner, mais il est encore incertain:

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

Comme sudo n'offre actuellement que des modèles globaux , cela * correspondra à n'importe quoi – ce n'est pas un regexp!

(Editer: j'ai considéré si vous pouviez sortir avec ce qui précède dans votre situation, car il n'y a pas de sous-dossiers sous les sites-available . Nous avons exigé un char être 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. Et de toute façon en général, cela resterait dangereux sur un dossier rnano des sous-dossiers!)

Même si nous n'avons pas de sous-dossiers, et nous excluons les lignes contenant /../ , la règle offrant un * glob pourrait encore être exploitée, car rnano accepte plusieurs arguments (en cours de cyclisme sur <CX> , et l'espace est heureusement accepté par Le * glob.

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

2. Pousser l'enveloppe (également en fin de compte)

Alors, que faire si nous rejetons les lignes contenant des espaces ou essayons d'atteindre /.. ? Ensuite, une dernière solution réalisable 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 "sous" le dossier, mais nous rejetons tout appel à rnano si /.. ou /. ou Sont passés, ou si le dossier est directement ciblé. (Techniquement, l'exclusion permet l'exclusion /.. exclusif, 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 que rnano bloquerait si pointé vers un dossier, mais vous auriez tort. En fait, ma version (2.2.6-1ubuntu1) démarre avec un avertissement doux et un fichier vide, puis sur <CX> me demande d'entrer n'importe quel nom de fichier que j'aimerais sauvegarder, ouvrant un nouveau vecteur d'attaque! Bien au moins, il a refusé d'écraser un fichier existant (dans le test que j'ai fait). Quoi qu'il en soit, car il n'y a aucun moyen de créer des sous-dossiers avec sudo, nous devons conclure que cette approche est de 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 seulement aussi forte que son maillon le plus faible. Je commence à ressentir la combinaison de la liste noire de sudo black-magic et rnano peut ne plus être sécurisé qu'une chaîne de marguerites.

3. Approches sûres mais limitées

Les globes sont très restreints: ils ne nous permettent pas de faire correspondre une classe de personnage plusieurs fois. Vous pouvez proposer plusieurs modifications 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 donner accès à l'utilisateur pour modifier différents fichiers, vous devrez peut-être spécifier tous les fichiers explicitement:

 %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 pourquoi! Rappelez-vous: un petit glissement peut compromettre l'ensemble du compte super-utilisateur et l'ensemble du système.

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

J'espère qu'ils ajouteront le soutien de regexp à sudo dans le futur; Il pourrait résoudre beaucoup de problèmes s'il est utilisé correctement. Mais nous pouvons également avoir besoin de vérifier les propriétés des arguments (pour autoriser uniquement les fichiers, les dossiers ou seulement certains drapeaux).

Mais il existe une alternative pour créer de la flexibilité dans sudo. Passez le buck:

 %staff ALL = /root/bin/staffedit * 

Ensuite, écrivez votre propre script staffedit ou exécutable pour vérifier si les arguments passés par l'utilisateur sont légaux et ne font que leur demande s'ils le sont.

Tout d'abord, ouvrez le fichier sudoers avec sudo visudo . L'ajout de l' user ALL=!/usr/sbin/service , IIRC, interdit la commande de service pour l'utilisateur user .

Sources: 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 je me suis transformé en utilisateur root avec su - alors j'ai tapé visudo pour éditer.

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é et fermé et redémarré aussi.

Maintenant, si je tape en tant que service network restart ou service network restart service NetworkManager restart alors il 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 de service network restart .

La véritable réponse à cela est que vous ne pouvez pas vraiment empêcher cela. Vous pourriez empêcher quelqu'un de manière non intentionnelle d'exécuter accidentellement cette commande via les méthodes décrites dans les autres réponses, mais si quelqu'un veut vraiment l'exécuter et se trouve sur la liste des sudoers, ils peuvent 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

Longue histoire courte, si vous pouvez sudo et qu'il ne se limite pas à l'exécution de commandes particulières, vous pouvez faire tout ce que vous voulez. Même si vous les restreignez à un ensemble donné de commandes, vous devriez vous assurer qu'il n'est pas possible pour l'utilisateur de copier une autre commande qu'ils souhaitaient exécuter sur le même nom que celui qu'ils avaient l'autorisation d'exécuter ( Par exemple en écrasant la commande qu'ils ont la permission de s'exécuter.)

Utilisez Firejail pour restreindre les utilisateurs avec les bacs à sable.

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

Définissez firejail comme shell au lieu de bash dans / etc / passwd, pour chaque utilisateur que vous souhaitez restreindre. Il est très facile à utiliser et dispose d'une bonne documentation.

Exemple:

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