Vím, že linuxové jmenné prostory, kromě mnoha jiných věcí, lze využít k bezpečnému zpracování omezování a uvěznění podřízených procesů bez jakékoli šance, že budou zombie zničeny a vyhozeny na init
. Ale nemám jasno v podrobnostech implementace. Jak mohu použít nástroje poskytované util-linux
například mount
a nsenter
sledovat, monitorovat a zajistit, že všechny spuštěné procesy jsou přímými potomky jmenného prostoru jiného procesu?
Přijatá odpověď:
Vytvořte jmenný prostor PID
Správný příkaz, který zde můžete použít, je unshare
. Upozorňujeme, že potřebné možnosti k tomu jsou dostupné pouze od util-linux 2.23
. Cílem je vytvořit nový jmenný prostor PID pro program, který spouštíte, tak, aby v tomto jmenném prostoru byly vytvořeny také všechny jeho potomky. Příkaz v novém jmenném prostoru PID můžete spustit jednoduše takto:
sudo unshare -fp some_command
Chcete-li spustit shell, jednoduše vynechejte příkaz. Tím se vytvoří proces, který bude mít spolu s libovolným ze svých potomků PID jako obvykle v nadřazeném (systémovém) jmenném prostoru. V rámci nového jmenného prostoru však bude mít PID 1
spolu s některými speciálními vlastnostmi init
proces. Snad nejrelevantnější charakteristikou z hlediska monitorování je to, že pokud některý z jeho potomků osiře, bude přeměněn na tento proces, nikoli na skutečný init
proces.
Pro většinu případů monitorování může stačit pouhé provedení tohoto postupu. Jak již bylo zmíněno, všechny procesy v rámci jmenného prostoru mají PID v nadřazeném jmenném prostoru, takže ke sledování jejich aktivity lze použít běžné příkazy. Jsme také ujištěni, že pokud jakýkoli proces ve jmenném prostoru osiře, nevypadne z větví stromu procesů pod PID programu nejvyšší úrovně, což znamená, že jej lze stále snadno sledovat.
Kombinovat s jmenným prostorem připojení
Co však nemůžeme udělat, je sledovat proces s ohledem na PID, které si myslí to je má. K tomu, a zejména mít možnost používat ps
příkaz v novém jmenném prostoru, musíte připojit samostatný procfs
souborový systém pro jmenný prostor. To zase vede k dalšímu problému, protože jediné umístění je ps
přijímá pro procfs
je /proc
. Jedním z řešení by bylo vytvořit chroot
vězení a připojit nový procfs
tam. Ale to je těžkopádný přístup, protože bychom minimálně museli zkopírovat (nebo alespoň napevno propojit) všechny binární soubory, které hodláme použít spolu s knihovnami, na kterých závisí, do nového kořenového adresáře.
Řešením je také použít nový připojit jmenný prostor . V rámci toho můžeme připojit nový procfs
způsobem, který používá skutečný kořen /proc
adresář, může být použit v rámci jmenného prostoru PID a nezasahuje do ničeho jiného. Aby byl tento proces velmi jednoduchý, unshare
příkaz poskytuje --mount-proc
možnost:
sudo unshare -fp --mount-proc some_command
Nyní běží ps
v rámci kombinovaných jmenných prostorů zobrazí pouze procesy s jmenným prostorem PID a proces nejvyšší úrovně ukáže, že má PID 1
.
A co nsenter
?
Jak název napovídá, nsenter
lze použít k zadání jmenného prostoru, který již byl vytvořen pomocí unshare
. To je užitečné, pokud chceme získat informace dostupné pouze zevnitř jmenného prostoru z jinak nesouvisejícího skriptu. Nejjednodušší způsob je zadat PID libovolného programu běžícího v rámci jmenného prostoru. Aby bylo jasno, musí to být PID cílového programu v rámci jmenného prostoru, ze kterého nsenter
je spuštěn (protože jmenné prostory mohou být vnořené, je možné, že jeden proces bude mít mnoho PID). Chcete-li spustit shell v cílovém jmenném prostoru PID/připojení, jednoduše proveďte:
sudo nsenter -t $PID -m -p
Pokud je tento jmenný prostor nastaven výše uvedeným způsobem, ps
nyní vypíše pouze procesy v tomto jmenném prostoru.