Executer un script shell depuis un script .php
Bonjour,
Etant débutant dans ce domaine, je me permets de poster ici car je souhaiterais que l'on m'explique comment exécuter un script shell grâce a un script php
Je suis sous raspbian
Mon script.sh est fonctionnel lorsque fait
Au niveau des droits j'ai fait un
Voici mon script sh:
Et monscript.php:
Lorsque je fais un script.php avec du texte et que je l'appelle avec un autre ordinateur, la page s'ouvre bien et le texte s'affiche correctement.
Je vous remercie d'avance pour votre aide
Etant débutant dans ce domaine, je me permets de poster ici car je souhaiterais que l'on m'explique comment exécuter un script shell grâce a un script php
Je suis sous raspbian
Mon script.sh est fonctionnel lorsque fait
bash monscript.sh
Au niveau des droits j'ai fait un
chmod 777 monscript.sh monscript.phppour avoir ponctuellement tous les droits et ne pas être bloqué de ce coté.
Voici mon script sh:
#!/bin/bash etherwake -i eth0 00:11:22:33:44:55
Et monscript.php:
<?php shell_exec ('/home/monscript.sh'); ?>
Lorsque je fais un script.php avec du texte et que je l'appelle avec un autre ordinateur, la page s'ouvre bien et le texte s'affiche correctement.
Je vous remercie d'avance pour votre aide
4 réponses
-
Inutile de faire un
chmod 777 monscript.php
: ce fichier est lu par l'utilisateur qui lance le serveur web (typiquement l'utilisateurwww-data
), il suffit donc que ce fichier appartienne au groupe en question et ait les droits en lecture :
cd /var/www/monsite/
chmod 640 monscript.php
chown root:www-data monscript.php
Note que si tu peux attribuer ce fichier à n'importe quel utilisateur autre que root si tu préfères du moment que ce n'est pas www-data et que cet utilisateur peut légitimement écrire dans ce fichier. Si par exemple ton profil utilisateur est toto, tu peux donc l'attribuer à toto.
Idem pour monscript.sh
si tu explicites l'interpréteur (icibash
) : dans ce cas le fichier n'est pas exécuté (c'estbash
qui l'est), etbash
ne fait que lire le fichierscript.sh
. Commebash
est exécuté par ton serveur web, c'est donc toujours le même utilisateurwww-data
qui est en jeu, et donc il est suffisant de lui mettre les mêmes droits :
chmod 640 script.sh
chown root:www-data script.sh
Ok maintenant il faut que quand les commandes shell mise en jeu (donc/bin/bash
et/usr/sbin/etherwake
), leur répertoire soit dans la variable d'environnement PATH de l'utilisateur qui lance ces commandes (donc toujours www-data), ou que tu donnes leur chemin absolu. Pour voir le PATH de www-data tu peux regarder ce que donne :
su - www-data
echo $PATH
... mais personnellement, je te conseille de plutôt utiliser des chemins absolus. Du coup ton script shell deviendra :
#!/bin/bash
/usr/sbin/etherwake -i eth0 00:11:22:33:44:55
.... et ton script php :
<?php shell_exec ('/home/monscript.sh'); ?>
Note que pour que cette commande shell_exec soit correcte, il faut s'assurer que cette fonction peut effectivement sortir du DocumentRoot de ton VirtualHost. Typiquement si c'est /var/www/monsite, tu ne pourrais pas accéder à un fichier en dehors de /var/www/mon/site. Assure toi que ce n'est pas bloquant dans ce cas.
Bonne chance -
Bonsoir,
Dans un primer tempo, j'ai essayé votre méthode en renseignant les chemins absolus
a savoir
Pour le sh:
#!/bin/bash
/usr/sbin/etherwake -i eth0 00:11:22:33:44:55
Pour le .php :
<?php shell_exec ('/var/www/monscript.sh'); ?>
J'ai donc placé mon .sh dans le même dossier que mon .php pour essayer de contourner le problème d'accès des fichier
j'espère avoir compris la logique..
Mais cela ne fonctionne pas. -
Vérifie que les chemins sont corrects. Je suppose qu'etherwake requiert des droits root pour être exécuté avec succès, souviens-toi qu'a priori c'est l'utilisateur www-data qui va l'exécuter. Du coup il faudrait que www-data soit sudoer sur cette commande (voir
sudo
).
https://www.atrixnet.com/allow-an-unprivileged-user-to-run-a-certain-command-with-sudo/
Bonne chance-
-
Pour voir si le problème vient d'etherwake ou non j'ai créé un petit script.sh qui contient :
#!/bin/bash
touch test.txt
Je l'ai rendu exécutable et je lui ai donné tous les droits avec chmod 777 test.sh
Lorsque je fais : bash test.sh cela fonctionne parfaitement
J'ai fais de même en créant un test.php
<?php shell_exec ('/var/www/test.sh'); ?>
Donc normalement si j'appel mon test.php,
il devrait exécuter mon test.sh
et mon test.sh devrait créer mon fichier test.txt
Et déjà là, cela ne le créé pas.Donc le problème ne vient pas des droits d'etherwake. -
J'ai encore avancé un peu...(on fait ce qu'on peux comme on peux ^^)
j'ai voulu m'assurer que mon test.php fonctionné bien .
Du coup j'ai trouvé la commande suivante :
php -f test.php
et là ;-) mon fichier test.txt est bien généré !
le problème vient bien de mon appel depuis l'extérieur ...
c'est peu mais ça avance... -
2 ème bonne nouvelle, j'ai ouvert les droits des dossiers var et de www
Du coup lorsque j'appel mon fichier test.php depuis un autre post, celui-ci génère bien le fichier test.txt ;-)
Du coup, sur le meme principer, j'ai ouvert les droits des dossiers sur et sbin pour accéder a etherwake...mais ceci ne fonctionne pas
Encor un petit pas en avant ;-) -
J'ai visiblement trouvé la solution a mon problème ;-)
J'ai commencer par restreindre les droit de www-data seulement pour etherwake
sudo visudo
www-data ALL=(ALL) NOPASSWD: /usr/sbin/etherwake
ensuite dans mon fichier won.sh j'ai just rajouté sudo avant l'arborescence:
#!/bin/bash
sudo /usr/sbin/etherwake -i eth0 00:11:22:33:44:55
voila j'ai fait plusieurs essais d'allumer le pc avec un navigateur web et...ça marche !!!
Encore merci a vous pour m'avoir aidé !
-
-
Félicitations :-)
Je vois au travers de cette progression que tu as compris petit à petit où je voulais en venir avec mon message précédent. La démarche pour comprendre le problème que tu as suivie est effectivement la bonne pour déduire que c'est un problème de droits (par rapport à celui qui existe le script, en l'occurrence www-data).
Passons à la minute culture :-)
En fait pour résoudre ton problème, il y a plusieurs écoles. Je t'ai fait suivre celle qui me paraissait la meilleure :
1) on aurait pu utiliser un bit set-uid sur script.sh, mais c'est très dangereux d'un point de vue sécurité. En outre ça peut permettre à d'autres utilisateurs d'exécuter ce script et doncetherwake
alors qu'ils ne sont pas sensés en avoir le droit, et donc il aurait fallu dans ce script faire un contrôle fin et s'assurer que le script est sans faille. C'est l'approche utilisée par exemple par les commandes commepasswd
(voirls -l $(which passwd)
). Comme c'est dangereux c'est une méthode que je déconseille autant que possible.
https://fr.wikipedia.org/wiki/Setuid
2) sietherwake
appartient à groupe particulier qui permet d'exécuter cette commande. C'est assez contextuel (ça dépend de la commande), rien ne garantit qu'un tel groupe ait ces droits et en général ce n'est pas le cas. Son côté généralement inapplicable me l'a fait écarter d'entrée.
3) changer les droits de l'exécutable etherwake revient à relâcher les droits correspondants, et donc à plus de gens de l'exécuter (la pire manière étant le hélas bien trop connu chmod 777 qui est le meilleur moyen d'ouvrir un trou de sécurité). C'est donc à proscrire absolument.
4) la méthode sudo (que je t'ai proposée) présente l'avantage d'être propre, claire, et de centraliser (cf visudo) les permissions spéciales qu'on a pu allouer à certains utilisateurs. Soyons clairs : c'est fait pour. Le seul inconvénient c'est que ça force à installersudo
, mais on va dire que c'est régulièrement installé. Je ne rentre pas dans les détails puisque tu l'as déjà décrite.
https://doc.ubuntu-fr.org/sudo
5) une autre possibilité, spécifique à apache, aurait été d'utiliser suexec. Mais elle peut également être dangereuse et revient à installer une variante desudo
. Ça ne change à mon sens pas forcément grand chose, car il faudra de toute façon l'installer, la configurer etc... L'intérêt de la méthodesudo
est qu'elle est plus générale, pas forcément limité au cas de figure apache.
https://httpd.apache.org/docs/trunk/fr/suexec.html
Bonne continuation :-)