Ubuntu

為什麼 UTS 命名空間隔離不起作用?

  • April 19, 2021

1. 在單獨的子 UTS 命名空間下啟動 shell 程序

sudo unshare -f --mount-proc -u /bin/bash

2.在這個過程中更改主機名

hostnamectl set-hostname newhostname

3. 從不同的 shell 監控變化

$ hostname
newhostname

預期結果

父命名空間中的程序保留其舊主機名。

結果得到

更改新 UTS 命名空間中的主機名也會更改父命名空間中的主機名。


為什麼會這樣?我使用的是 Ubuntu 20.04,核心版本 5.10.23-xanmod1 ( uname -r)。

hostnamectlsystemd環境而來,它不執行sethostname(2)系統呼叫。它通過套接字要求systemd執行此操作。/run/dbus/system_bus_socket由於systemd沒有更改命名空間,它在初始命名空間中執行此操作,將舊 UTS 命名空間的名稱(它正在執行的初始名稱)更改為提供的新名稱,並使新的 UTS 命名空間保持不變的名稱(與 OP 的相反聲明):舊主機名。還會有其他副作用,例如文件/etc/hostname被更改。

這可以使用strace. 沒有sethostname(2)內部,但有可見的 systemd 相關元素:

newfstatat(AT_FDCWD, "/run/systemd/system/", {st_mode=S_IFDIR|0755, st_size=40, ...}, AT_SYMLINK_NOFOLLOW) = 0

如果一個人阻止上面的呼叫成功(通過使用然後用 aunshare -f -u -m /bin/bash覆蓋它),一個人得到:/run``mount -t tmpfs tmpfs /run

System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

該對話框稍後通過打開的套接字完成,如下所示:

connect(3, {sa_family=AF_UNIX, sun_path="/run/dbus/system_bus_socket"}, 30) = 0

hostname在這種環境中,應該使用用於讀取更改主機名的低級“遺留”命令。它確實直接呼叫sethostname(2)系統呼叫:它將更改新的 UTS 命名空間的名稱並保持舊的(初始)UTS 命名空間不變:

hostname newhostname

為了hostnamectl影響新的 UTS 命名空間(就像使用 LXC 啟動的完整容器),這需要的不僅僅是一個unshare命令:一個全新的systemd生態系統實例必須存在於新環境中,可能需要幾個其他命名空間輸入/取消共享和許多額外的樣板。

引用自:https://unix.stackexchange.com/questions/639168