儘管持有能力 CAP_NET_BIND_SERVICE,Apache 容器無法綁定到已知埠
當嘗試在啟動的 systemd 容器中執行 Apache 時
systemd-nspawn --private-users=pick ...
(與--private-users=false
此解決方案不同),我遇到此錯誤:Permission denied: AH00072: make_sock: could not bind to address ...:999
令我困惑的是容器已被授予能力
CAP_NET_BIND_SERVICE
(getpcaps 1
容器內部也證實了這一點),--capability=help
表明該能力受支持,並且netcat -l 999 -s ...
(也在容器內部)顯然可以在同一個埠上監听就好了。我錯過了什麼?該功能是否應該允許容器內的程序打開主機上的知名埠,無論它們的 PID 是什麼?
更新我在呼叫
netcat
. 正確的命令行是netcat -vl -p 999 -s ...
,現在這會產生“無法抓取 …:999 with bind : Permission denied”。所以事實上 Apache 和 netcat 都不能在這一點上綁定,這不是 Apache 特定的。關於配置的另外兩個事實:容器正在執行root
(映射到主機上的非根 pid),iptables
主機上是空的。更新所以也許能力
CAP_NET_BIND_SERVICE
根本無法超越使用者命名空間。
我得出的結論是,
CAP_NET_BIND_SERVICE
特定的能力和一般的能力不能超越使用者命名空間。來自user_namespaces(7)
:使用者命名空間隔離了與安全相關的標識符和屬性,特別是使用者 ID 和組 ID(參見憑據 (7))、根目錄、密鑰(參見密鑰環 (7))和能力(參見能力 (7))。
…
由 clone(2) 創建的帶有 CLONE_NEWUSER 標誌的子程序以新使用者命名空間中的一組完整功能開始。同樣,使用 unshare(2) 創建新使用者命名空間或使用 setns(2) 加入現有使用者命名空間的程序在該命名空間中獲得了完整的功能集。另一方面,即使創建了新的命名空間,該程序在父(在 clone(2) 的情況下)或前一個(在 unshare(2) 和 setns(2) 的情況下)使用者命名空間中也沒有能力或由 root 使用者加入(即 root 命名空間中使用者 ID 為 0 的程序)。
…
在使用者命名空間內擁有能力允許程序僅在由該命名空間管理的資源上執行操作(需要特權)。換句話說,在使用者命名空間中具有能力允許程序對由與使用者命名空間相關聯的(非使用者)命名空間管理的資源執行特權操作(參見下一小節)。
來自
network_namespaces(7)
:一個物理網路設備可以存在於一個網路命名空間中。
由於我的案例涉及綁定到主機的主 IP 地址,因此相關的物理網路設備可能必須由核心的根網路名稱空間管理。我的容器的使用者命名空間中的功能
CAP_NET_BIND_SERVICE
可能與那裡無關,因為根網路命名空間不與該使用者命名空間相關聯,而是與核心的根使用者命名空間相關聯。所以我(大概)在這裡不走運。