chv-cell: ns 内 setuid 修复 + 单元内 DNS(上游 resolv.conf 绑定)
- 中间进程不再先 setuid(1000) 再 unshare:真机对照实测那样 后续 unshare(CLONE_NEWNS) 得 EPERM;改为保持 root 外层身份 unshare(creator caps 在),孙进程在 ns 内 setgid/setuid(0) 切到内 0(映射到外层 chv 1000)。 - 单元内 DNS:客机 /etc/resolv.conf 是 127.0.0.53 stub,单元 独立 netns 里自己的 lo 上没有 resolver;把上游 /run/systemd/resolve/resolv.conf 绑到 /etc/resolv.conf (解析 symlink 后挂真实目标),只在单元私有 mount ns 里。 - 单测:CellResolvTest(bind 参数/symlink 解析/缺失回落) + 规约 dns_resolv_conf 字段;P2 + 阶段 2 共 73 项全过。
This commit is contained in:
1 parent
afbb7772c5
commit
4b5f2f124f
2 files changed
+104
-13
No files matched your search
@@ -111,6 +111,52 @@ class CellArgvTest(unittest.TestCase):
|
||||
self.assertNotIn("GITEA_TOKEN", real)
|
||||
|
||||
|
||||
def test_dns_resolv_conf_upstream_bind(self):
|
||||
spec = CELL.build_sandbox_spec(["true"])
|
||||
self.assertEqual(spec["dns_resolv_conf"], "upstream-bind")
|
||||
|
||||
|
||||
class CellResolvTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp = tempfile.mkdtemp(prefix="cell-resolv-")
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.tmp, ignore_errors=True)
|
||||
|
||||
def test_upstream_bind_args(self):
|
||||
upstream = os.path.join(self.tmp, "resolv.conf")
|
||||
with open(upstream, "w", encoding="utf-8") as f:
|
||||
f.write("nameserver 8.8.8.8\nnameserver 1.1.1.1\n")
|
||||
target = os.path.join(self.tmp, "target-resolv.conf")
|
||||
with open(target, "w", encoding="utf-8") as f:
|
||||
f.write("nameserver 127.0.0.53\n")
|
||||
self.assertEqual(CELL._resolv_bind(upstream, target),
|
||||
["--bind", upstream, target])
|
||||
|
||||
def test_symlink_target_resolved(self):
|
||||
upstream = os.path.join(self.tmp, "resolv.conf")
|
||||
with open(upstream, "w", encoding="utf-8") as f:
|
||||
f.write("nameserver 8.8.8.8\n")
|
||||
real = os.path.join(self.tmp, "stub-resolv.conf")
|
||||
with open(real, "w", encoding="utf-8") as f:
|
||||
f.write("nameserver 127.0.0.53\n")
|
||||
link = os.path.join(self.tmp, "resolv-link")
|
||||
os.symlink(real, link)
|
||||
self.assertEqual(CELL._resolv_bind(upstream, link),
|
||||
["--bind", upstream, real])
|
||||
|
||||
def test_missing_or_no_nameserver_returns_none(self):
|
||||
target = os.path.join(self.tmp, "target-resolv.conf")
|
||||
with open(target, "w", encoding="utf-8") as f:
|
||||
f.write("nameserver 127.0.0.53\n")
|
||||
self.assertIsNone(CELL._resolv_bind(
|
||||
os.path.join(self.tmp, "no-such-file"), target))
|
||||
empty = os.path.join(self.tmp, "empty-resolv.conf")
|
||||
with open(empty, "w", encoding="utf-8") as f:
|
||||
f.write("search .\n")
|
||||
self.assertIsNone(CELL._resolv_bind(empty, target))
|
||||
|
||||
|
||||
class CellSeccompTest(unittest.TestCase):
|
||||
def test_filter_structure(self):
|
||||
raw = CELL.build_seccomp_filter()
|
||||
|
||||
Reference in new issue
Block a user