User Namespaces 是 Linux 内核提供的一种隔离机制,可以将容器内的用户 ID 映射到宿主机的用户 ID,从而实现用户层面的隔离。 但是,这个 User Namespaces 不是默认开启的,需要在 Docker 的配置文件中进行设置。 也就是说,默认情况下,Docker 里的 root 跟宿主机的 root 就是一回事,被面试官忽悠了,绷。
以下文提到的挂载 procfs 逃逸为例,没开 User Namespaces 的情况下,宿主机的 root 直接就被拿下了。
Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type /dev/fd0p1 90 656,144,16 656,144,16 2425393296 555819295 2425393296 1156G 90 Unknown Partition 1 has different physical/logical start (non-Linux?): phys=(656,144,16) logical=(1045428,21,1) Partition 1 has different physical/logical end: phys=(656,144,16) logical=(239577,40,16) /dev/fd0p2 90 656,144,16 656,144,16 2425393296 555819295 2425393296 1156G 90 Unknown Partition 2 has different physical/logical start (non-Linux?): phys=(656,144,16) logical=(1045428,21,1) Partition 2 has different physical/logical end: phys=(656,144,16) logical=(239577,40,16) /dev/fd0p3 90 656,144,16 656,144,16 2425393296 555819295 2425393296 1156G 90 Unknown Partition 3 has different physical/logical start (non-Linux?): phys=(656,144,16) logical=(1045428,21,1) Partition 3 has different physical/logical end: phys=(656,144,16) logical=(239577,40,16) /dev/fd0p4 90 656,144,16 656,144,16 2425393296 555819295 2425393296 1156G 90 Unknown Partition 4 has different physical/logical start (non-Linux?): phys=(656,144,16) logical=(1045428,21,1) Partition 4 has different physical/logical end: phys=(656,144,16) logical=(239577,40,16) Found valid GPT with protective MBR; using GPT
Disk /dev/sda: 41943040 sectors, 0 Logical sector size: 512 Disk identifier (GUID): 247954d6-7c12-4470-9429-09ba67b1bfc5 Partition table holds up to 128 entries First usable sector is 34, last usable sector is 41943006
Number Start (sector) End (sector) Size Name 1 2048 4095 1024K 2 4096 1054719 513M EFI System Partition 3 1054720 41940991 19.4G
sudo dockerd -H unix:///var/run/docker.sock -H 0.0.0.0:2375 INFO[2025-04-22T10:39:23.909818793+08:00] Starting up failed to start daemon, ensure docker is not running or delete /var/run/docker.pid: process with PID 1319 is still running
sudo dockerd -H unix:///var/run/docker.sock -H 0.0.0.0:2375 INFO[2025-04-22T10:40:38.151876920+08:00] Starting up WARN[2025-04-22T10:40:38.152530906+08:00] Binding to IP address without --tlsverify is insecure and gives root access on this machine to everyone who has access to your network. host="tcp://0.0.0.0:2375" WARN[2025-04-22T10:40:38.152554700+08:00] Binding to an IP address, even on localhost, can also give access to scripts run in a browser. Be safe out there! host="tcp://0.0.0.0:2375" WARN[2025-04-22T10:40:38.152609238+08:00] [DEPRECATION NOTICE] In future versions this will be a hard failure preventing the daemon from starting! Learn more at: https://docs.docker.com/go/api-security/ host="tcp://0.0.0.0:2375" WARN[2025-04-22T10:40:39.154871410+08:00] Binding to an IP address without --tlsverify is deprecated. Startup is intentionally being slowed down to show this message host="tcp://0.0.0.0:2375" WARN[2025-04-22T10:40:39.154978953+08:00] Please consider generating tls certificates with client validation to prevent exposing unauthenticated root access to your network host="tcp://0.0.0.0:2375" WARN[2025-04-22T10:40:39.155023761+08:00] You can override this by explicitly specifying '--tls=false' or '--tlsverify=false' host="tcp://0.0.0.0:2375" WARN[2025-04-22T10:40:39.155038038+08:00] Support for listening on TCP without authentication or explicit intent to run without authentication will be removed in the next release host="tcp://0.0.0.0:2375" INFO[2025-04-22T10:40:54.210520545+08:00] detected 127.0.0.53 nameserver, assuming systemd-resolved, so using resolv.conf: /run/systemd/resolve/resolv.conf INFO[2025-04-22T10:40:54.447847216+08:00] [graphdriver] using prior storage driver: overlay2 INFO[2025-04-22T10:40:54.463550314+08:00] Loading containers: start. INFO[2025-04-22T10:40:54.986964216+08:00] Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address INFO[2025-04-22T10:40:55.090980115+08:00] Loading containers: done. WARN[2025-04-22T10:40:55.145707727+08:00] [DEPRECATION NOTICE]: API is accessible on http://0.0.0.0:2375 without encryption. Access to the remote API is equivalent to root access on the host. Refer to the 'Docker daemon attack surface' section in the documentation for more information: https://docs.docker.com/go/attack-surface/ In future versions this will be a hard failure preventing the daemon from starting! Learn more at: https://docs.docker.com/go/api-security/ INFO[2025-04-22T10:40:55.145782627+08:00] Docker daemon commit="26.1.3-0ubuntu1~22.04.1" containerd-snapshotter=false storage-driver=overlay2 version=26.1.3 INFO[2025-04-22T10:40:55.145947337+08:00] Daemon has completed initialization INFO[2025-04-22T10:40:55.236241515+08:00] API listen on /var/run/doc