# Docker 环境探测识别
若我们连当前环境是否为 docker 都不知道,自然也不会想到逃逸这一步了,因此我们需要知道当前环境是否为容器。
# 文件系统
# 检查 cgroup 文件
原理:进程 1 为 systemd,是系统进程,而 cgroup 为 control group, 是 linux 的组件,cgroup 往往用于 docker 容器的资源管理
其中的数字就是容器的 id。也是 hostname
cat /proc/1/cgroup
# 检查 /.dockerenv 文件是否存在
.dockerenv 在 Docker 从发布之始激烈的迭代后依然存在着主目录 / 下
# 有无真实网卡(无法区分是什么模式)
(虚拟机在桥接模式我们通过这个办法是无法区分的,但是容器无论什么模式都是不存在真实网卡的)
docker 是不存在真实网卡的,因此我们可以查看当前机子有无真实网卡就可确定是否为物理机。
通过 /sys/class/net 下的软连接文件,我们可以看到,当前的网卡信息,其中如果存在真实网卡的话,其软连接地址不会是 /sys/devices/virtual 这个目录。
因此通过这个就能快速识别其是否为容器。
cd /sys/class/net
ls -al
# 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:可以看到是什么云服务器
物理: 看到是什么厂商
# 通过内核路径判断
$(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)}'
# pid
容器内的程序 pid 一般都很小,而且通常都会存在一个前台进程(pid 为 1 的进程)。
胆子大点,kill 掉这个进程,容器直接退出。
如果 kill 不掉的话,可以去看这个脚本内容,kill 掉它的子进程。
参考:https://www.jianshu.com/p/e829b99b36ba
# 网络信息(主要用于判断当前网络是什么模式)
前面讲过 docker 中的网络,而通常情况下,这些网络是存在特征的。
这里虽然也是能用来判断是否在容器中的,但是这种方法比起上面的来说比较费劲。因此这里主要是辅助我们判断当前的 docker 网络模式。
# 所以模式都通用方法
ip addr 查看是否形如 eth0@ifxxx 的设备,这种情况下一般都是 docker 网络的默认网卡名称,host 情况就可能不会这样。
并且除了 host 和 none 模式以外,必能访问到这个宿主机的 ip xxx.xxx.xxx.1
# bridge 模式
因为容器不设置网卡的话默认是 bridge 模式,也就是 172.17-20.0.1/16 段
同时能够访问 172.16-20.0.1(宿主机)
但是这只能用来判断是不是容器,不能说根据这个就能判断是什么网络模式。
通常情况下这种模式只存在两张网卡,一张环回网卡 lo,一张就是 bridge 的网卡 ifxxx 了。
(与 overlay 可以用这个来判断,overlay 其他和这种模式看起来是一模一样的,但是 overlay 必存在 3 张网卡)
# host 模式
因为这里输出的是宿主机的网卡信息,所以我们首当其冲的是能看到 docker0 这个网卡。
其次文件系统又是隔离的,所以如果目标是宿主机,那么必存在 docker 这个命令。如果不存在,那么必是容器。
# overlay 模式
其中 lo 是环回网卡、剩下两张一张是 overlay 网络的网卡,一张是 docker_gwbridge 的网卡(docker swarm 自动生成,宿主机也在这个网卡上,可以尝试去访问宿主机)