rulați comanda shell ca alt utilizator apelat de PHP (Administrarea sistemului, Apache 2.2, Php, Debian, Shell, Execuție)

powtac a intrebat.
a intrebat.

Am un script PHP care este apelat prin HTTP și nu ca script de linie de comandă. Acest script ar trebui să apeleze o comandă shell ca un alt utilizator decât utilizatorul curent al serverului web www-data.

Exemplu:

<?php
echo shell_exec('sudo -u myusername -S /usr/bin/whoami'); // returns nothing :(
echo shell_exec('whoami'); // returns www-data

Când se apelează aceste 2 comenzi sudo -u myusername -S /usr/bin/whoami și whoami direct în linia de comandă, acestea returnează

myusername
www-data 

De asemenea, nici un rezultat la acest lucru:

<?php
echo shell_exec('echo "mypass" | sudo -u myusername -S /usr/bin/whoami');

Pentru mine se pare că sudo nu funcționează deloc împreună cu shell_exec() din PHP.

Comentarii

  • Ce spune fișierul dvs. sudoers despre www-data? –  > Por MadHatter.
  • Se referă la utilizarea php sau doar la comanda din interiorul ghilimelelor? „Când se apelează aceste 2 comenzi direct în linia de comandă, ele returnează” –  > Por Dennis Williamson.
  • @MadHatter, nu există nimic despre www-data în fișierul sodoers, @Dennis: am schimbat descrierea pentru a fi clar. –  > Por powtac.
  • Hmm, nu știu cum PHP curăță PATH, așa că poate ar trebui să dați numele complet al căii de acces la sudo, comanda. –  > Por Luka Marinko.
  • Folosesc deja numele de drum absolut. –  > Por powtac.
3 răspunsuri
MadHatter

În primul rând, nu înțeleg comanda sudo pe care o rulezi. sudo -u username ar trebui să-ți permită ca tu, ca utilizator unu, să sudo o comandă ca utilizator doi, spunând (ca utilizator unu, în acest exemplu, să rulezi comanda ls):

sudo -u usertwo ls

Îmi cer scuze dacă ați încercat să vă curățați comenzile de mai sus înlocuind comanda cu username pentru numele de utilizator real, dar nu pot fi sigur că ați făcut-o, așa că trebuie să ridic mai întâi această problemă.

În al doilea rând, sudo trebuie să fie configurat pentru a permite unui utilizator să execute o serie de comenzi ca un alt utilizator. Să începem prin a permite www-data să sudo comanda ls ca utilizator fribble; ați putea testa acest lucru punând

www-data        ALL = (fribble) NOPASSWD: ls

în fișierul sudoers (înlocuind fribble cu un utilizator real). Apoi încercați să faceți, să zicem, ls -la /tmp din interiorul scriptului dvs. PHP și vedeți dacă obțineți o listă de directoare.

Sunt de acord cu James Lawrie că nu este o idee bună să permiteți utilizatorului www-data să sudo comenzi arbitrare, ca utilizator arbitrar, fără parolă, dar dacă clarificați ce comenzi încercați să faceți ca www-data să ruleze, aceasta ar putea fi o modalitate sensibilă de a face acest lucru.

Editați:

ați încercat cu ls în fișierul sudoers și sudo -u user2 ls -al /tmp în scriptul PHP, și obțineți o listă de directoare, ceea ce sugerează cu tărie că sudo funcționează bine cu PHP.

Pentru a fi siguri, ați putea permite /bin/touch în fișierul sudoers, puneți sudo -u user2 touch /tmp/TESTFILE în scriptul PHP, apoi executați-l? În cazul în care un fișier /tmp/TESTFILE apare, deținut de user2, putem fi siguri că sudo și PHP funcționează bine împreună.

Trebuie să mărturisesc că, dacă aș fi știut că încercați să sudo java, nu v-aș fi răspuns niciodată la întrebarea inițială, pentru că eu cred că java este un sac de rahat uriaș și imprevizibil, care se comportă ca un copil complet dacă nu primește mediul de care are nevoie (iar sudo igienizează destul de riguros mediul). Dar cel puțin testul de mai sus ar trebui să vă ajute să fiți sigur că, oricare ar fi problema de aici, aceasta este nu este o problemă cu PHP și sudo care nu se joacă frumos împreună.

Comentarii

  • Mulțumesc pentru răspuns, voi încerca, am schimbat numele de utilizator în exemplul de mai sus. Era menit să fie numele de utilizator real pe care vreau să-l folosesc. –  > Por powtac.
  • Nu funcționează, am adăugat www-data și numele celorlalți utilizatori și comanda. –  > Por powtac.
  • Ați putea să puneți intrarea sudoers în întrebarea de mai sus? –  > Por MadHatter.
  • www-data ALL = (myusername) NOPASSWD: /usr/bin/java –  > Por powtac.
  • Nu am sugerat să încercăm cu java, ci cu ls. ls este o comandă ceva mai ușoară, cu o ieșire mai previzibilă, care sperăm că ne va da o idee dacă sudo este apelat sau nu. Bineînțeles că nu aveți nicio obligație să încercați nimic din ceea ce se sugerează aici, dar probabil că nu este util să spuneți că încercați când de fapt încercați ceva diferit. –  > Por MadHatter.
James L

Nu permiteți utilizatorului serverului web accesul sudo, nu faceți decât să căutați probleme. În schimb, căutați mai degrabă setuid bit:
chmod u+s some_file_that_needs_executing_as_another_user.pl
Ori de câte ori este executat acel fișier, acesta va fi executat efectiv de către utilizatorul care l-a creat.
În altă ordine de idei, sunt destul de sigur că nu puteți introduce o parolă în sudo sau passwd.

Comentarii

  • Am deja comanda care trebuie executată, iar aceasta este creată dinamic, deci nu o pot plasa înainte de execuție într-un alt fișier. –  > Por powtac.
Khaled

Dacă doriți să acordați permisiuni speciale procesului serverului web care rulează ca utilizator www-data, puteți face una dintre următoarele:

1- Adăugați www-data la fișierul sudoers, astfel încât acesta să poată executa comanda/scriptul necesar fără a cere o parolă.

2- Activați modulul apache suexec. Acest lucru vă permite să schimbați utilizatorul de la www-data la un alt utilizator privilegiat pentru fiecare gazdă virutală. Astfel, nu este nevoie să schimbați utilizatorul pentru întregul server.

Comentarii

  • Nu vreau să ruleze întregul utilizator www-data cu drepturi extinse, ci doar atunci când execută această singură comandă. –  > Por powtac.
  • În același mod în care permiteți utilizatorilor să execute comenzi cu sudo, puteți restricționa comenzile pe care un utilizator sudoing le poate executa, de exemplu www-data ALL=(ALL) /usr/bin/whoami –  > Por James Yale.