Impossible de définir l'UID sur les scripts shell

14

Quelqu'un peut-il m'aider à savoir ce qui se passe ici? J'ai des règles configurées pour suivre le nombre de paquets. Lorsque j'exécute le script suivant en tant que root:

#!/bin/bash
iptables -t mangle -xnvL

J'obtiens la sortie que j'attends:

//snip
233203 199929802 MARK  //blah blah blah
//snip

Cependant, je veux l'exécuter dans le cadre de cactus, qui fonctionne comme apache. Maintenant, apache ne peut pas exécuter iptables, c'est pourquoi j'ai le script. Je l'ai configuré en tant que racine SUID :

-rwsr-sr-x 1 root root   37 May 14 23:06 iptables_packet_report.sh

Mais alors j'obtiens cette sortie:

server # sudo -u apache ./iptables_packet_report.sh
iptables v1.4.2: can't initialize iptables table `mangle': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.

Évidemment, mon noyau va bien, et le fait que je l'exécute en tant que non root gâche quelque chose, mais je ne comprends pas pourquoi. J'ai vérifié le SUID avec [la démonstration] ( http://en.wikipedia.org/wiki/Setuid#Demonstration et confirmé qu'il fonctionnait.

server # sudo -u apache ./printid
Real UID  = 81
Effective UID = 0
Real GID  = 81
Effective GID = 0

Mon objectif final est d'obtenir la sortie de iptables -t mangle -xnvL tout en fonctionnant en tant qu'apache afin que je puisse utiliser des cactus pour bien représenter tout cela.

Tom Ritter
la source

Réponses:

16

Vous ne pouvez pas utiliser la racine SUID pour les scripts shell. Seuls les vrais programmes peuvent être root SUID, les scripts shell commencent par "#!" et l'interprète devrait exécuter SUID et cela ne fonctionne pas pour une raison que je ne savais pas

Jetez un œil à sudo et installez-le! Modifiez / etc / sudoerrs, ajoutez une ligne comme celle-ci:

www-data        ALL=NOPASSWD: /usr/local/sbin/iptables_packet_report.sh

Ensuite, lancez

sudo /usr/local/sbin/iptables_packet_report.sh

à partir de votre code.

Il ne doit alors pas demander le mot de passe, mais évaluer le processus automatiquement.

Je suis sûr que vos messages d'erreur se produiront également si vous suez manuellement dans www-data et l'exécutez manuellement

Christian
la source
13

Comme Christian l'a indiqué, mon problème était que j'essayais de SUID sur un script shell. Comme expliqué ici, définir SUID sur un script shell est une très mauvaise idée:

l'exécution d'un script shell sous UNIX implique un processus en deux étapes: lorsque le noyau détermine qu'un script shell est sur le point d'être exécuté, il démarre d'abord une copie SUID de l'interpréteur shell, puis l'interpréteur shell commence à exécuter le script shell. Étant donné que ces deux opérations sont effectuées en deux étapes distinctes, vous pouvez interrompre le noyau après la première étape et basculer le fichier que l'interpréteur de shell est sur le point d'exécuter. De cette façon, un attaquant pourrait demander à l'ordinateur d'exécuter n'importe quel script shell de son choix.

Pour cette raison, de nombreuses distributions Linux modernes ignorent les scripts shell SUID, y compris gentoo que j'utilisais. J'ai pu modifier le fichier sudoers et le faire fonctionner.

Tom Ritter
la source
Une réponse fantastique!
Dave Cheney
quelqu'un sait si cela est vrai pour Solaris 10?
Eric Johnson
2

Je pense que la solution de christian est la meilleure, mais si vous le vouliez vraiment, vous pouvez compiler le script en utilisant shc puis setuid root sur le programme compilé.

Kyle Brandt
la source