网络命名空间和 chroot - GUI 应用程序无法启动

Network namespace and chroot - GUI applications don't start

提问人:user2141238 提问时间:9/16/2023 更新时间:9/16/2023 访问量:25

问:

我创建了小型 SUID 应用程序,它应该将 Chromium 与主系统(Arch Linux)隔离开来:

unshare(CLONE_NEWNS|CLONE_NEWCGROUP|CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWPID);
mount("none", "/", NULL, MS_PRIVATE|MS_REC, NULL);
chroot("/path/to/new/root");
chdir("/");
mount("proc", "/proc", "proc", MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL);
setresuid(1000, 1000, 1000);

我可以通过以下方式连接到 Xorg 并启动 GUI 应用程序,但是当我尝试隔离网络时:xauth add "$DISPLAY" MIT-MAGIC-COOKIE-1 <hex key>

int namespace_fd = open("/var/run/netns/chromium_netns", O_RDONLY|O_CLOEXEC);
setns(namespace_fd, CLONE_NEWNET);

Chromium 抛出错误:

[2:2:0915/194118.898349:ERROR:ozone_platform_x11.cc(240)] Missing X server or $DISPLAY
[2:2:0915/194118.898364:ERROR:env.cc(255)] The platform failed to initialize.  Exiting.

strace:

connect(29, {sa_family=AF_UNIX, sun_path=@"/tmp/.X11-unix/X0"}, 20) = -1 ECONNREFUSED (Connection refused)
connect(29, {sa_family=AF_INET6, sin6_port=htons(6000), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_scope_id=0}, 28) = -1 ECONNREFUSED (Connection refused)
connect(29, {sa_family=AF_INET, sin_port=htons(6000), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 ECONNREFUSED (Connection refused)

我创建网络命名空间并设置 iptables,如下所示:

ip netns add chromium_netns
ip link add veth0 type veth peer name veth1
ip link set veth1 netns chromium_netns
ip addr add 192.168.0.2/24 dev veth0
ip link set dev veth0 up
ip netns exec chromium_netns ip addr add 192.168.0.1/24 dev veth1
ip netns exec chromium_netns ip link set dev veth1 up
ip netns exec chromium_netns ip link set dev lo up
ip netns exec chromium_netns ip route add default via 192.168.0.2
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
iptables -A FORWARD -i ens33 -o veth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i veth0 -o ens33 -j ACCEPT

Curl 连接到命名空间内部的网络,但 GUI 应用程序无法连接到 Xorg。我的程序的整个源代码(我删除了错误检查):

#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sys/wait.h>

using namespace std;

int main()
{
    unshare(CLONE_NEWNS|CLONE_NEWCGROUP|CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWPID);
    int namespace_fd = open("/var/run/netns/chromium_netns", O_RDONLY|O_CLOEXEC);
    setns(namespace_fd, CLONE_NEWNET);
    close(namespace_fd);

    int pid = fork();
    if (pid != 0) {
        setresuid(1000, 1000, 1000);
        int status;
        waitpid(-1, &status, 0);
        return status;
    }

    mount("none", "/", NULL, MS_PRIVATE|MS_REC, NULL);
    chroot("/path/to/new/root/");
    chdir("/");
    mount("proc", "/proc", "proc", MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL);
    setresuid(1000, 1000, 1000);

    execlp("/bin/bash", "/bin/bash", NULL);

    return 0;
}

Linux 网络 命名空间 xorg chroot

评论


答: 暂无答案