LOFTER for ipad —— 让兴趣,更有趣

点击下载 关闭
Docker安全问题

1. 磁盘资源限制问题

容器本质是一个进程,通过镜像层叠方式构建容器的文件系统,当需要改写文件时,把改写的文件复制到最顶层的读写层,其本质还是在宿主机文件系统的某一目录下存储这些信息,所有容器的rootfs最终存储在宿主机上,极有可能出现一个容器把宿主机上所有的磁盘容量耗尽的情况,届时其他容器将无法进行文件存储操作,所以有必要对容器的磁盘使用量进行限制


2. 容器逃逸问题

在全虚拟化和半虚拟化中,每一个租户都独立运行一个内核,比Docker使用操作系统虚拟化更安全

操作系统虚拟化指的是共享内核,内存,CPU以及磁盘等,所以容器的安全问题特别突出,特别是容器逃逸问题.当容器从监狱(jail)中逃出时,所有容器以及宿主机都将受到威胁

在Docker1.0版本之前采用黑名单形式来限制容器的能力,只禁止列出来的部分能力,所以会出现通过open_by_handle_at进行暴力扫描的问题,1.0版本后采用白名单的形式来限制容器的能力,除默认的能力清单外,其他均禁止


3.容器DoS攻击与流量限制问题

默认的Docker网络是网桥模式,所有容器连接到网桥上.容器通过veth pair技术创建veth pair网卡,然后将其中一端放入容器内并且命名为eth0,另外一张网卡留在宿主机网络环境中.容器内网卡发出的数据包都会发往宿主机上对应网卡,再由物理网卡进行转发.同理,物理网卡收到的数据根据地址会相应发送到不同的容器内.实际上所有容器共用一张物理网卡.

如果在同一宿主机中的某一个容器抢占了大部分带宽,将会影响其他容器的使用.如大流量的容器内下载程序会影响其他交互式应用的访问


4. 超级权限问题

Docker在0.6版本的时候给容器引入了超级权限,即在docker run 时加上--privileged参数,使容器获得超级权限.其获取过程如下:

Docker首先去检测docker run时是否指定了--privileged标志,如果指定就调用setPrivileged这个操作.setPrivileged函数完成两件事情,一是获取所有能力赋值给容器,使用函数为GetAllCapabilities,二是扫描宿主机所有设备文件挂载到容器内,使用函数为GetHostDeviceNodes

GetAllCapabilities做了什么

以一个非超级权限容器和超级权限容器进行对比

# docker run -d --name nginx1 nginx

# docker inspect --format="{{.State.Pid}}" nginx1

20175

# cat /proc/20175/status

CapInh:00000000a80425fb

CapPrm:00000000a80425fb

CapEff:00000000a80425fb

CapBnd:00000000a80425fb

以下为超级权限

# docker run -d --name nginx2 --privileged=true nginx

[root@alios ~]# docker inspect --format="{{.State.Pid}}" nginx2

19434

# cat /proc/19434/status

CapInh:0000001fffffffff

CapPrm:0000001fffffffff

CapEff:0000001fffffffff

CapBnd:0000001fffffffff

GetHostDeviceNodes做了什么

GetHostDeviceNodes将会获取宿主机目录下的所有设备文件,并将其设置到容器

查看Docker容器没有--privileged参数时,即普通权限下/dev目录下的文件

# docker exec -it nginx1 bash

  root@601936256ce6:/# ls /dev

core  fd  fullfuse  mqueue  null  ptmx  pts  random  shm  stderr  stdin  stdout  ttyurandom  zero

加了--privileged参数时,即超级权限下的/dev目录下的文件

# docker exec -it nginx2 bash

root@c267a3971fa7:/# ls /dev                                                                                                     

autofs dri       mapper   pts     tty0   tty20  tty32  tty44  tty56ttyS1 vcs5      vhci

bsg fb0       mcelog   random    tty1   tty21  tty33  tty45  tty57ttyS2 vcs6      vhost-net

btrfs-control fd       mem   raw     tty10  tty22  tty34  tty46  tty58ttyS3 vcsa      vport2p1

bus full       mqueue   rtc0      tty11  tty23  tty35  tty47  tty59uhid vcsa1      zero

core fuse       net   sg0     tty12  tty24  tty36  tty48  tty6uinput vcsa2

cpu hidraw0       network_latency   shm     tty13  tty25  tty37  tty49  tty60urandom  vcsa3

cpu_dma_latency  hpet       network_throughput  snapshot  tty14  tty26  tty38  tty5 tty61usbmon0  vcsa4

crash hwrng       null   snd     tty15  tty27  tty39  tty50  tty62usbmon1  vcsa5

dm-0 input       nvram   sr0     tty16  tty28  tty4   tty51  tty63vcs vcsa6

dm-1 kmsg       oldmem   stderr    tty17  tty29  tty40  tty52  tty7vcs1 vda

dm-2 loop-control  port   stdin     tty18  tty3   tty41  tty53  tty8vcs2 vda1

dm-3 loop0       ppp   stdout    tty19  tty30  tty42  tty54  tty9vcs3 vfio

dm-4 loop1       ptmx   tty     tty2   tty31  tty43  tty55  ttyS0vcs4 vga_arbiter

可以看到,加了特权后,宿主机所有设备文件都挂载在容器内


注意

--privileged参数给的权限太多,需要慎重使用,如果需要挂载某个特定的设备,可以如以下操作

--device=/dev/sdc:dev/xvdc:rwm

定向挂载设备到容器,而不是把宿主机全部设备挂载到容器上

此外,可以通过--add-cap和--drop-cap参数对容器的能力进行调整,以最大限度地保证容器使用的安全

推荐文章
评论(0)
分享到
转载我的主页