Toon posts:

[PHP] exec met runuser werkt niet

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik probeer een exec, shell_exec, of system call te doen met het runuser command. Als ik het runuser command echo en in de terminal plak, werkt het command. als ik hem uitvoer via php dan doet ie het niet. Ik voer het script als root uit en wil hem eigenlijk als www-data uitvoeren onder de root user.

Dit gaat om een optimize script uitvoeren (als www-data) na een update (root) andere commando's werken wel, het gaat mis bij runuser.

...

PHP 7.4.28 (cli) (built: Feb 17 2022 16:17:19) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.28, Copyright (c), by Zend Technologies

PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
...

ik voer dit command uit:
PHP:
1
$command = 'runuser --user www-data -- php -f /Application/Bin/R3m.php info all > test.info';

test.info is gemaakt door user root en 0 bytes. terwijl er info in moet komen te staan.
Heb dit command met exec, shel_exec & system geprobeerd maar doen het allemaal niet.

terwijl
PHP:
1
$command = 'php -f /Application/Bin/R3m.php info all > test.info';

wel werkt en runuser in de cli wel werkt 8)7 .

Iemand enig idee ?


...

Alle reacties


Acties:
  • 0 Henk 'm!

  • Juup
  • Registratie: Februari 2000
  • Niet online
Wat zijn de rechten op die 'test.info' file?
Je wilt daar als www-data naar schrijven terwijl die door root is aangemaakt?

Welke errors krijg je bij de falende commandos?

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Juup schreef op dinsdag 28 juni 2022 @ 23:53:
Wat zijn de rechten op die 'test.info' file?
Je wilt daar als www-data naar schrijven terwijl die door root is aangemaakt?

Welke errors krijg je bij de falende commandos?
ik had verwacht dat 'test.info' de rechten van www-data zou krijgen, maar is op dit moment root
ik heb een responsecode van 127, hoe kan ik de error te voor schijn toveren want ik kan daar niets over vinden.

Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Waarom zorg je niet gewoon dat user www-data php scripts kan draaien, vervolgens laat je dat scipt uitvoeren in een cronjob of zo door www-date. Php als root draaien, die een script moet starten voor een ander, is niet echt veilig, zal ik maar zeggen.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
ik heb het al gevonden.
met
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$descriptorspec = array(
0 => array("pipe", "r"),  // stdin
1 => array("pipe", "w"),  // stdout
2 => array("pipe", "w"),  // stderr
);

$process = proc_open($command, $descriptorspec, $pipes, '/Application', null);
$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);

$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);

echo "stdout : \n";
var_dump($stdout);

echo "stderr :\n";
var_dump($stderr);


ben ik de error te weten gekomen: kan runuser niet vinden

na een zoektocht met "find . -name runuser" kon ik hem lokaliseren in /sbin. Het absolute pad uitvoeren en het werkt. mooi.

Wat is er niet veilig aan php als root draaien en dat die een script voor een ander moet starten ?

Het script draait al als root omdat het om een update script gaat die root rechten nodig heeft om uit te voeren.

[ Voor 15% gewijzigd door Verwijderd op 29-06-2022 00:27 ]


Acties:
  • +1 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Principle of least privilege.

Momenteel hoop je dat je er aan denkt als minder rechten volstaan, maar je wil juist enkel als het wel nodig is met meer rechten werken.

Het verschil zit in details waar je niet aan denkt. Met least privilege merk je dat soms omdat iets niet werkt, fix je dat, klaar. Als je te ruim in je rechten zit, tja, niemand die waarschuwt tot het te laat is. :)

NB: Algemeen antwoord, maar deze discipline geldt net zo goed buiten je PHP taken.

{signature}


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
ik werk momenteel aan een CMS systeem op mijn framework. de update button in het cms zet een job klaar voor een update. Er draait een cronjob als root elke minuut die kijkt of er een update job bestaat. de cronjob voert eventeel de update uit en onderdeel van die update is:
- cache clear
- update
- cache clear
- optimize

De update wordt als root uitgevoerd omdat het script ook alle bestanden overschrijft inclusief het bestand dat wordt uitgevoerd op dat moment. De update wordt beschermt met een JWT (json web token) die alleen als admin mag worden uitgevoerd)

De optimize geldt alleen voor www-data, sommige pagina's hebben een koude start vanwege de cache:clear en het gebruik van een template engine. Die koude starts duren dan meer dan 10 seconden. Ik dacht ik voer een optimize uit nadat er geupdate is zodat het update proces langer duurt maar je dan niet meer hoeft te wachten op de koude starts. .

@Voutloos ik ben het met je eens

[ Voor 5% gewijzigd door Verwijderd op 29-06-2022 11:52 ]


Acties:
  • +2 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Die beschrijving klinkt alsof een normale user dat allemaal moet kunnen, ik zie niet waarom root nodig is.
Misschien dat root nu wat bestandjes van je applicatie ownt, maar dat is enkel vanwege je huidige werkwijze. ;)

Context: Ervaring met een paar enorme PHP apps inc cronjobs, queue workers etc etc. Nergens root nodig. En mijn geweten, collega’s en auditors gaan vervelend worden als het anders zou gaan. :D

{signature}


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Voutloos schreef op woensdag 29 juni 2022 @ 12:42:
Die beschrijving klinkt alsof een normale user dat allemaal moet kunnen, ik zie niet waarom root nodig is.
Misschien dat root nu wat bestandjes van je applicatie ownt, maar dat is enkel vanwege je huidige werkwijze. ;)

Context: Ervaring met een paar enorme PHP apps inc cronjobs, queue workers etc etc. Nergens root nodig. En mijn geweten, collega’s en auditors gaan vervelend worden als het anders zou gaan. :D
Het is een docker container:

- Het cms installeert zich in /Application met composer die liever als www-data aangeroepen wil worden
- Ik vind dat een update alleen door user_id = 0 kan worden uitgevoerd als je remote inlogt
- daarom is de vendor directory ook door root:root aangemaakt en blijft zo vanwege remote inlog
- Zodoende kunnen er ook collega's rondlopen die remote kunnen inloggen maar niet kunnen updaten
- de cronjob service die ik gebruik wordt op dit moment als root uitgevoerd. Vanwege dat ik eerder heb geimplementeerd dan ik runuser ben tegen gekomen heb ik dat veilig gebouwd met admin privelege. In het cms systeem is het mogelijk om te updaten.
- Er wordt een .task file aangemaakt en een .token file. Die token file bevat de admin uuid en zijn rollen uuids.
- indien het token file goed is bevonden wordt de .task file uitgevoerd.
- indien er 1 minuut is verstreken en de task file nog niet is uitgevoerd wordt wel de .token vast verwijderd.
- de task bestaat uit meerdere commando's om te updaten.
Bash:
1
2
3
4
5
composer update --quiet &&
funda cache:clear &&
funda system update ...(token) &&
funda cache:clear  &&
funda system optimize

- zoals je ziet heb je om te updaten een geldig JWT token nodig.
- voor cache clear zijn root privileges nodig (Kan ik nog bijbouwen dat die zonder niet alle cache kan clearen, maar die van www-data)
- en daar is system optimize bijgekomen en wat ik dan wil gaan doen is multithreaded optimalizeren (voorverwarmen van template gegenereerde opcache
Bash:
1
/sbin/runuser --user www-data -- php /Application/Bin/R3m.php parse compile ' . $optimization->template . ' ' . $optimization->data

- waarbij optimization->template een url is naar een .tpl bestand
- waarbij optimization->data een url is naar een .json bestand die geparsed wordt op functies.

DIt zit er momenteel in het json bestand:
JSON:
1
2
3
4
{
  "host": "{{Execute:Cms:host()}}",
  "controller" : "{{Execute:Cms:controller('Settings')}}"
}

Moet nog iets bij, content type en request.
- host is host initialisatie
- controller is controller initialisatie en execute is een trait. De parser die van de template een class maakt is in php en die embed traits, functies, modifiers. Deze gaat de opcache in. met data vullen gaat redelijk vlot.

Maarja houdt je van de straat :+

[ Voor 3% gewijzigd door Verwijderd op 29-06-2022 22:42 ]


Acties:
  • 0 Henk 'm!

  • DaFeliX
  • Registratie: December 2002
  • Laatst online: 02-10 13:41

DaFeliX

Tnet Devver
Verwijderd schreef op woensdag 29 juni 2022 @ 22:19:
[...]


Het is een docker container:

[...]
https://stackoverflow.com/a/19056603

The key point is that as root, you can exercise more kernel code; if there is a vulnerability in that code, you can trigger it as root, but not as a regular user.

Additionally, if someone finds a way to break out of a container, if you break out as root, you can do much more damage than as a regular user, obviously.
Verwijderd schreef op woensdag 29 juni 2022 @ 22:19:
[...]

- Zodoende kunnen er ook collega's rondlopen die remote kunnen inloggen maar niet kunnen updaten

[...]
Maar dat kan ook zonder root, namelijk een derde unprivlieged user maken. Misschien zou je in dit geval zelfs beter kunnen werken met een groep, zodat alle gebruikers die in die groep zitten updates kunnen uitvoeren.

Einstein: Mijn vrouw begrijpt me niet


Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Verwijderd schreef op woensdag 29 juni 2022 @ 00:23:
na een zoektocht met "find . -name runuser" kon ik hem lokaliseren in /sbin. Het absolute pad uitvoeren en het werkt. mooi.
Je kunt ook which <command> gebruiken, dan zie je meteen of het geïnstalleerd is en zo ja, welk pad het heeft. find gaat de hele disk af zoeken (en door te zoeken vanaf . zoek je in de huidige map en dieper, maar andere mappen niet, als je dus in de verkeerde map zit, krijg je geen resultaten) en kan dus lang duren, terwijl dat dus niet hoeft. Ik denk daarnaast ook dat een cursus Linux niet verkeerd is. Dan weet je beter de commando's te gebruiken (en ben je minder afhankelijk van 'het internet', die zo te zien dus niet altijd de beste opties/oplossingen geeft) en leer je de werking van Linux, slechter kun je er allerminst van worden. ;) Ook kan mono meer resultaten teruggeven. Wat nu als 'runuser' twee keer op het systeem staat? ;)

[ Voor 11% gewijzigd door CH4OS op 30-06-2022 07:49 ]


Acties:
  • 0 Henk 'm!

  • Raynman
  • Registratie: Augustus 2004
  • Laatst online: 00:48
offtopic:
Als runuser niet via $PATH te vinden was, gaat which ook niet helpen, maar de environment kan natuurlijk verschillen tussen cron/PHP-script en de shell waarin TS aan het experimenteren is. En wat maakt het uit als find meerdere resultaten geeft; TS kiest er gewoon een om met volledig pad in het script te zetten.

[ Voor 23% gewijzigd door Raynman op 30-06-2022 10:11 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Tsja, en wat als ik apt update && apt upgrade wil toevoegen aan de update ? Ik dacht dat dat alleen door root kan worden uitgevoerd.

Acties:
  • +1 Henk 'm!

  • kutagh
  • Registratie: Augustus 2009
  • Laatst online: 22:17
Daar heb je sudo / doas etc voor. Waarbij je o.a. bij sudo ook kan instellen bij welke commands de user niet opnieuw diens wachtwoord hoeft te invoeren.

Zo hebben wij dus Jenkins die dus bepaalde commands kan uitvoeren die onder de Jenkins user niet mogelijk zijn.

Acties:
  • +2 Henk 'm!

  • TommieW
  • Registratie: December 2010
  • Laatst online: 01-10 13:12

TommieW

Numa numa.

Verwijderd schreef op donderdag 30 juni 2022 @ 12:31:
Tsja, en wat als ik apt update && apt upgrade wil toevoegen aan de update ? Ik dacht dat dat alleen door root kan worden uitgevoerd.
Waarom zou je dat in een container willen doen? Dat gaat compleet het idee van een container tegen. Als je een update wil doen (van je applicatie of het OS in de container), dan bak je een nieuwe container die in de build root is en dat soort dingen mag en daarna terugschaalt naar een minder privileged gebruiker.

1700X@3,9GHZ - Asus Crosshair VI Hero - 32GB Corsair LPX - GTX 1070Ti
iPhone 13 Pro Max - Macbook Pro 16" M1 Pro


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
TommieW schreef op donderdag 30 juni 2022 @ 12:47:
[...]

Waarom zou je dat in een container willen doen? Dat gaat compleet het idee van een container tegen. Als je een update wil doen (van je applicatie of het OS in de container), dan bak je een nieuwe container die in de build root is en dat soort dingen mag en daarna terugschaalt naar een minder privileged gebruiker.
Ik hoef niet telkens een nieuwe container live te hebben in het cms. wat ik wel wil hebben is een knop, update & upgrade van het os die ik via een cronjob kan instellen zodat ie altijd up to date is. waarom zou je dan ook nog extra (je moet dat command runnen om te weten te komen of er updates zijn.) een nieuwe docker image gaan maken, kan wel als backup dienen maar dan draai je toch docker in docker ?

Dit is de data geworden:
JSON:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
  "contentType" : "{{config('contentType.json')}}",
  "execute" : "{{autoload.prefix.add('Execute', config('project.dir.execute'))}}",
  "host": "{{Execute:Cms:host()}}",
  "controller" : "{{Execute:Cms:controller('Settings')}}",
  "request" : {
    "count" : 0,
    "limit": 10,
    "page" : 1,
    "max": 1,
    "filter" : {
      "type" : "All",
      "extension" : ""
    },
    "nodeList" : []
  },
  "session" : {
    "test" : true
  }
}

[ Voor 23% gewijzigd door Verwijderd op 30-06-2022 17:26 ]


Acties:
  • +1 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Verwijderd schreef op donderdag 30 juni 2022 @ 17:16:
Ik hoef niet telkens een nieuwe container live te hebben in het cms. wat ik wel wil hebben is een knop, update & upgrade van het os die ik via een cronjob kan instellen zodat ie altijd up to date is. waarom zou je dan ook nog extra (je moet dat command runnen om te weten te komen of er updates zijn.) een nieuwe docker image gaan maken, kan wel als backup dienen maar dan draai je toch docker in docker ?

Dit is de data geworden:
JSON:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
  "contentType" : "{{config('contentType.json')}}",
  "execute" : "{{autoload.prefix.add('Execute', config('project.dir.execute'))}}",
  "host": "{{Execute:Cms:host()}}",
  "controller" : "{{Execute:Cms:controller('Settings')}}",
  "request" : {
    "count" : 0,
    "limit": 10,
    "page" : 1,
    "max": 1,
    "filter" : {
      "type" : "All",
      "extension" : ""
    },
    "nodeList" : []
  },
  "session" : {
    "test" : true
  }
}
Updates aan bijvoorbeeld het OS wil je in het image hebben zitten. Bij een herstart van de container (en dat gebeurt vaker dan je denkt!) zijn de updates die je hebt gedaan ná het maken van het image/de container weer weg en is dat dus een veiligheidsrisico. Natuurlijk kun je ze opnieuw installeren, maar zo blijf je bezig en zolang jij die updates niet doet kan je dus een risico vormen die gemakkelijk te vermijden is. Daarnaast is het builden van een image GEEN backup!

[ Voor 6% gewijzigd door CH4OS op 02-07-2022 09:36 ]


Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 22:27
CH4OS schreef op zaterdag 2 juli 2022 @ 09:33:
[...]
Updates aan bijvoorbeeld het OS wil je in het image hebben zitten. Bij een herstart van de container (en dat gebeurt vaker dan je denkt!) zijn de updates die je hebt gedaan ná het maken van het image/de container weer weg en is dat dus een veiligheidsrisico. Natuurlijk kun je ze opnieuw installeren, maar zo blijf je bezig en zolang jij die updates niet doet kan je dus een risico vormen die gemakkelijk te vermijden is. Daarnaast is het builden van een image GEEN backup!
Bij het herstarten van een container zitten je wijzigingen er nog gewoon in hoor. Alleen bij het opnieuw aanmaken van een container raak je ze kwijt omdat ze niet in de image zaten meeverpakt.

Er zit een wezenlijk verschil tussen een nieuwe container aanmaken om de oude te vervangen of gewoon "docker restart {containername}" runnen.

[ Voor 8% gewijzigd door Merethil op 02-07-2022 09:53 ]


Acties:
  • 0 Henk 'm!

  • DataGhost
  • Registratie: Augustus 2003
  • Laatst online: 01:10

DataGhost

iPL dev

Merethil schreef op zaterdag 2 juli 2022 @ 09:52:
[...]


Bij het herstarten van een container zitten je wijzigingen er nog gewoon in hoor. Alleen bij het opnieuw aanmaken van een container raak je ze kwijt omdat ze niet in de image zaten meeverpakt.

Er zit een wezenlijk verschil tussen een nieuwe container aanmaken om de oude te vervangen of gewoon "docker restart {containername}" runnen.
Het idee is volgens mij altijd zo geweest dat je ervan uit moet gaan dat je container op elk moment kan ophouden met bestaan. Persistent data hoort in volumes. Verder hoor je niks in de container te wijzigen wat niet automatisch door het entrypoint-script gedaan wordt. Dus ook geen updates, helemaal niet "random" alle OS-updates binnenhalen want dan is je code opeens niet meer getest met wat er binnenkomt, nog aangenomen dat al die updates direct goed gaan. Dus een normale workflow, die alsnog volledig geautomatiseerd kan, is zoiets als: bouw nieuwe container met alle updates die je gedaan wilt hebben -> run testsuite -> vervang de draaiende container door de nieuwe.

Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 22:27
DataGhost schreef op zaterdag 2 juli 2022 @ 10:08:
[...]

Het idee is volgens mij altijd zo geweest dat je ervan uit moet gaan dat je container op elk moment kan ophouden met bestaan. Persistent data hoort in volumes. Verder hoor je niks in de container te wijzigen wat niet automatisch door het entrypoint-script gedaan wordt. Dus ook geen updates, helemaal niet "random" alle OS-updates binnenhalen want dan is je code opeens niet meer getest met wat er binnenkomt, nog aangenomen dat al die updates direct goed gaan. Dus een normale workflow, die alsnog volledig geautomatiseerd kan, is zoiets als: bouw nieuwe container met alle updates die je gedaan wilt hebben -> run testsuite -> vervang de draaiende container door de nieuwe.
Mijn opmerking was dan ook geen advies, alleen een verduidelijking dat dingen die je in de container doet over het algemeen persistent zijn met een restart.
Ik ben het er volledig mee eens dat je een nieuwe image in je O-omgeving maakt met de nieuwste wijzigingen (OS of applicatie of beide), die volledig test in een T- of A-omgeving en dan pas deployed naar productie.
Pagina: 1