# Docker 环境探测识别

若我们连当前环境是否为 docker 都不知道,自然也不会想到逃逸这一步了,因此我们需要知道当前环境是否为容器。

# 文件系统

# 检查 cgroup 文件

原理:进程 1 为 systemd,是系统进程,而 cgroup 为 control group, 是 linux 的组件,cgroup 往往用于 docker 容器的资源管理

其中的数字就是容器的 id。也是 hostname

cat /proc/1/cgroup

464e40e5-26a0-48b2-8df5-b8d2861b4f59-image.png

# 检查 /.dockerenv 文件是否存在

.dockerenv 在 Docker 从发布之始激烈的迭代后依然存在着主目录 / 下
23d8bb3e-08bc-414e-b4d9-a1a6ae12f02c-image.png

# 有无真实网卡(无法区分是什么模式)

(虚拟机在桥接模式我们通过这个办法是无法区分的,但是容器无论什么模式都是不存在真实网卡的)

docker 是不存在真实网卡的,因此我们可以查看当前机子有无真实网卡就可确定是否为物理机。

通过 /sys/class/net 下的软连接文件,我们可以看到,当前的网卡信息,其中如果存在真实网卡的话,其软连接地址不会是 /sys/devices/virtual 这个目录。

因此通过这个就能快速识别其是否为容器。

cd /sys/class/net
ls -al

image-20220411145521423

image-20220411145526639

image-20220411145530539

# CPU 与内核信息

# systemd-detect-virt 命令

systemd-detect-virt

这个命令会返回目标机器的虚拟机情况,有些虚拟机可能没有

docker:docker

Vmware:vmware

CVM:kvm (云服务器是这种)

物理:none

# cpu 信息查找

sudo dmidecode -t system 

docker:/dev/mem: No such file or directory 或没这个命令

vmware:可以看到是 vmware 字样

CVM:可以看到是什么云服务器

image-20220411142635576

物理: 看到是什么厂商

image-20220411142233393

# 通过内核路径判断

$(cat /proc/cmdline | tr ' ' '\n' | awk -F '=' '/BOOT_IMAGE/{print $2}') | test -e

原理:/proc/cmdline 文件是内核启动时的参数信息,而 /proc/153/cmdline 时存在程序启动时的参数 / BOOT_IMAGE 中存在指定内核程序,将其执行便可以判断是否为 docker

docker:No such file or directory

CVM:cannot execute binary file/permission denied

物理:cannot execute binary file/permission denied

# Other 信息

# hostname

默认情况下,docker 容器的 hostname 是由 12 个字符组成的。

hostname | awk '{print length($0)}'

image-20220411145902015

# pid

容器内的程序 pid 一般都很小,而且通常都会存在一个前台进程(pid 为 1 的进程)。
胆子大点,kill 掉这个进程,容器直接退出。
如果 kill 不掉的话,可以去看这个脚本内容,kill 掉它的子进程。
参考:https://www.jianshu.com/p/e829b99b36ba

image-20220411145906503

# 网络信息(主要用于判断当前网络是什么模式)

前面讲过 docker 中的网络,而通常情况下,这些网络是存在特征的。

这里虽然也是能用来判断是否在容器中的,但是这种方法比起上面的来说比较费劲。因此这里主要是辅助我们判断当前的 docker 网络模式。

# 所以模式都通用方法

ip addr 查看是否形如 eth0@ifxxx 的设备,这种情况下一般都是 docker 网络的默认网卡名称,host 情况就可能不会这样。

并且除了 host 和 none 模式以外,必能访问到这个宿主机的 ip xxx.xxx.xxx.1

image-20220411145448896

# bridge 模式

因为容器不设置网卡的话默认是 bridge 模式,也就是 172.17-20.0.1/16 段
同时能够访问 172.16-20.0.1(宿主机)
但是这只能用来判断是不是容器,不能说根据这个就能判断是什么网络模式。
通常情况下这种模式只存在两张网卡,一张环回网卡 lo,一张就是 bridge 的网卡 ifxxx 了。
(与 overlay 可以用这个来判断,overlay 其他和这种模式看起来是一模一样的,但是 overlay 必存在 3 张网卡)

# host 模式

因为这里输出的是宿主机的网卡信息,所以我们首当其冲的是能看到 docker0 这个网卡。
其次文件系统又是隔离的,所以如果目标是宿主机,那么必存在 docker 这个命令。如果不存在,那么必是容器。

image-20220411145737351

# overlay 模式

其中 lo 是环回网卡、剩下两张一张是 overlay 网络的网卡,一张是 docker_gwbridge 的网卡(docker swarm 自动生成,宿主机也在这个网卡上,可以尝试去访问宿主机)

image-20220411145758197

更新于 阅读次数