Signatur
Beschreibung
pcntl_unshare() ermöglicht es einem Prozess, Teile seines Ausführungskontexts – wie Namespaces – von anderen Prozessen zu isolieren, die diese zuvor geteilt haben. Die Funktion ist ein direktes PHP-Interface zum Linux-Systemaufruf unshare(2) und steht nur auf Linux-Systemen zur Verfügung.
Typische Anwendungsfälle sind Container-artige Isolierung, bei der ein Kindprozess eigene Namespaces für Benutzer, Prozess-IDs, Mount-Punkte oder Netzwerkinterfaces erhalten soll, ohne dass dies den Elternprozess beeinflusst. Dies ist besonders nützlich für Sandbox-Umgebungen oder Prozesse, die erhöhte Sicherheitsanforderungen haben.
Als $flags werden Konstanten verwendet, die mit CLONE_* beginnen, z. B. CLONE_NEWNS (neuer Mount-Namespace), CLONE_NEWUTS (neuer UTS-Namespace), CLONE_NEWIPC, CLONE_NEWUSER, CLONE_NEWPID oder CLONE_NEWNET. Mehrere Flags können mit dem bitweisen ODER-Operator (|) kombiniert werden.
Die Funktion ist nur auf Linux verfügbar und setzt voraus, dass das PHP mit aktivierter PCNTL-Extension kompiliert wurde. Bestimmte CLONE_NEW*-Flags benötigen Root-Rechte oder spezielle Linux-Capabilities (CAP_SYS_ADMIN), um erfolgreich ausgeführt zu werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $flags Pflicht | int | Bitmask aus CLONE_*-Konstanten, die bestimmen, welche Teile des Ausführungskontexts abgetrennt werden sollen. Mehrere Flags werden mit dem bitweisen ODER-Operator (|) kombiniert. Gültige Konstanten sind z. B. CLONE_NEWNS, CLONE_NEWUTS, CLONE_NEWIPC, CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET. |
Rückgabewert
true zurück, wenn der Namespace erfolgreich abgetrennt wurde. Bei einem Fehler (z. B. fehlende Rechte oder nicht unterstützte Flags) wird false zurückgegeben und ein entsprechender Fehler ausgegeben.Beispiele
Abtrennung eines Benutzer-Namespaces im Kindprozess
<?php
if (!function_exists('pcntl_unshare')) {
die('pcntl_unshare ist auf diesem System nicht verfügbar.');
}
$pid = pcntl_fork();
if ($pid === -1) {
die('Fork fehlgeschlagen.');
} elseif ($pid === 0) {
// Kindprozess: neuen Benutzer-Namespace erstellen
$result = pcntl_unshare(CLONE_NEWUSER);
if ($result) {
echo "Kindprozess: Benutzer-Namespace erfolgreich abgetrennt." . PHP_EOL;
} else {
echo "Kindprozess: Abtrennung fehlgeschlagen." . PHP_EOL;
}
exit(0);
} else {
// Elternprozess wartet auf Kind
pcntl_waitpid($pid, $status);
echo "Elternprozess: Kindprozess beendet." . PHP_EOL;
}
Kombination mehrerer Namespace-Flags
<?php
// Mehrere Namespaces gleichzeitig abtrennen (erfordert Root-Rechte)
$flags = CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC;
$result = pcntl_unshare($flags);
if ($result) {
echo "Mount-, UTS- und IPC-Namespace erfolgreich abgetrennt." . PHP_EOL;
// Ab hier kann der aktuelle Prozess z. B. eigene Mount-Punkte erstellen,
// den Hostnamen unabhängig setzen etc.
} else {
echo "Abtrennung fehlgeschlagen – prüfe Root-Rechte." . PHP_EOL;
}
// Wichtig · Fallstricke
Plattform-Einschränkung: pcntl_unshare() ist ausschließlich auf Linux verfügbar. Auf anderen Betriebssystemen (macOS, Windows, BSD) existiert die Funktion nicht.
Berechtigungen: Die meisten CLONE_NEW*-Flags (außer CLONE_NEWUSER unter bestimmten Kernel-Konfigurationen) erfordern Root-Rechte oder die Linux-Capability CAP_SYS_ADMIN. Ein Aufruf ohne ausreichende Rechte schlägt fehl.
Sicherheitshinweis: Das Abtrennen von Namespaces kann unerwartete Seiteneffekte auf laufende Prozesse haben, wenn es im Haupt- statt im Kindprozess aufgerufen wird. Es empfiehlt sich, pcntl_unshare() immer nach einem pcntl_fork() im Kindprozess aufzurufen.
Kernel-Konfiguration: Einige Namespaces (z. B. Benutzer-Namespaces) können in bestimmten Linux-Distributionen aus Sicherheitsgründen durch Kernel-Parameter wie kernel.unprivileged_userns_clone deaktiviert sein.