目录

一、Docker安全

二、Docker容器资源控制 

1.memory限制

2.cpu限制

3.Block IO限制

三、Docker安全加固

1.利用LXCFS增强docker容器隔离性和资源可见性

2.设置特权级运行的容器 

3.设置容器白名单

4.安全加固思路


一、Docker安全

Docker容器的安全性,很大程度上依赖于Linux系统自身,评估Docker的安全性时,主要考虑以下几个方面:

  • Linux内核的命名空间机制提供的容器隔离安全
  • Linux控制组机制对容器资源的控制能力安全
  • Linux内核的能力机制所带来的操作权限安全
  • Docker程序(特别是服务端)本身的抗攻击性
  • 其他安全增强机制对容器安全性的影响

命名空间隔离的安全:
当docker run启动一个容器时,Docker将在后台为容器创建一个独立的命名空间。命名空间提供了最基础也最直接的隔离。与虚拟机方式相比,通过Linux namespace来实现的隔离不是那么彻底。在 Linux 内核中,有很多资源和对象是不能被 Namespace 化的,比如:时间。

控制组资源控制的安全:

  • 当docker run启动一个容器时,Docker将在后台为容器创建一个独立的控制组策略集合。
  • Linux Cgroups提供了很多有用的特性,确保各容器可以公平地分享主机的内存、CPU、磁盘IO等资源。
  • 确保当发生在容器内的资源压力不会影响到本地主机系统和其他容器,它在防止拒绝服务攻击(DDoS)方面必不可少。

内核能力机制:

  • 能力机制(Capability)是Linux内核一个强大的特性,可以提供细粒度的权限访问控制。
  • 大部分情况下,容器并不需要“真正的”root权限,容器只需要少数的能力即可。
  • 默认情况下,Docker采用“白名单”机制,禁用“必需功能”之外的其他权限。

Docker服务端防护:

  • 使用Docker容器的核心是Docker服务端,确保只有可信的用户才能访问到Docker服务。
  • 将容器的root用户映射到本地主机上的非root用户,减轻容器和主机之间因权限提升而引起的安全问题。
  • 允许Docker 服务端在非root权限下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程只允许在特定范围内进行操作。

其他安全特性:

  • 在内核中启用GRSEC和PAX,这将增加更多的编译和运行时的安全检查;并且通过地址随机化机制来避免恶意探测等。启用该特性不需要Docker进行任何配置。
  • 使用一些有增强安全特性的容器模板。
  • 用户可以自定义更加严格的访问控制机制来定制安全策略。
  • 在文件系统挂载到容器内部时,可以通过配置只读模式来避免容器内的应用通过文件系统破坏外部环境,特别是一些系统运行状态相关的目录。

二、Docker容器资源控制 

  • Linux Cgroups 的全称是 Linux Control Group。
        是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。
        对进程进行优先级设置、审计,以及将进程挂起和恢复等操作。
  • Linux Cgroups 给用户暴露出来的操作接口是文件系统。
        它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。
        执行此命令查看:mount -t cgroup
  • 在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录,也叫子系统。
  • 在每个子系统下面,为每个容器创建一个控制组(即创建一个新目录)。
  • 控制组下面的资源文件里填上什么值,就靠用户执行 docker run 时的参数指定。

启动一个demo容器,查看pid为3919

docker加密保护js docker 安全设置_容器

进入到进程3919目录下的ns文件夹下

docker加密保护js docker 安全设置_docker加密保护js_02

在/sys/fs/cgroup中有许多的子目录,分别控制每个资源,我们进入到memory文件夹下,看到docker目录

docker加密保护js docker 安全设置_docker加密保护js_03

在docker目录下看到如图所示目录,进入该目录

docker加密保护js docker 安全设置_docker_04

 

docker加密保护js docker 安全设置_Docker_05

 查看该容器内存限制文件和主机内存最大限制

docker加密保护js docker 安全设置_Docker_06

1.memory限制

容器可用内存包括两个部分:物理内存和swap交换分区。

docker run -it --memory 200M --memory-swap=200M ubuntu

        --memory设置内存使用限额

        --memory-swap设置swap交换分区限额

(1)重新创建一个demo容器,指定内存是200M

docker加密保护js docker 安全设置_docker_07

(2)再次查看内存限制文件,可以看到变成了200M

docker加密保护js docker 安全设置_容器_08

测试控制memory:

(1)/dev/shm/是一个在内存中的目录,在此目录/dev/shm/中创建文件会占用内存

docker加密保护js docker 安全设置_Docker_09

(2)创建新的项目x1的限制目录,会自动继承主机的限制文件 

docker加密保护js docker 安全设置_Docker_10

(3)修改x1内存最大值为200M

docker加密保护js docker 安全设置_docker_11

(4)安装libcgroup-tools工具

docker加密保护js docker 安全设置_linux_12

(5)切换到/dev/shm/目录下,向里面拷贝一个300M大小的文件 

docker加密保护js docker 安全设置_docker_13

发现没有出错,是因为还开启着swap分区,其中有100M使用的是swap分区的空间

(6)删除测试文件,关闭swap分区并再次拷贝一个300M大小的文件进行测试

docker加密保护js docker 安全设置_docker_14

发现无法使用超过200M的空间

(7)直接关闭swap分区可能会影响到别的需要swap分区的容器,故重新启动swap分区,将内存和swap分区的总量设置成200M

docker加密保护js docker 安全设置_linux_15

(8)再次进入到/dev/shm目录下进行测试

docker加密保护js docker 安全设置_Docker_16

2.cpu限制

以下方法作为测试,docker中实现cpu限额的命令为

docker run -it --cpu-period=100000 --cpu-quota=20000 ubuntu
docker run -it --cpu-shares 100 busybox

 方法一:

(1)进入cpu限制目录创建新的项目x2

docker加密保护js docker 安全设置_docker加密保护js_17

(2)查看进程优先级,重新给定优先级,需要将进程加入tasks才生效

docker加密保护js docker 安全设置_docker加密保护js_18

(3)创建两个进程并用top查看进程,将进程4406加入task

docker加密保护js docker 安全设置_容器_19

 发现还是100%使用cpu,这是因为虚拟机有两个cpu,目前还没有发生资源争抢,关闭cpu1(注意cpu0是无法关闭的)

(4)关闭cpu1

docker加密保护js docker 安全设置_容器_20

此时4406进程为另个进程cpu使用率的10%左右。

(5)重启cpu1

docker加密保护js docker 安全设置_docker_21

(6)恢复进程优先级

docker加密保护js docker 安全设置_容器_22

方法二:

(1)显示x2进程分配的cpu,默认-1表示任意

docker加密保护js docker 安全设置_容器_23

(2)显示进程cpu总配额

docker加密保护js docker 安全设置_Docker_24

(3)给定4406进程1/5的配额(4406进程写在tasks内)

docker加密保护js docker 安全设置_docker加密保护js_25

可以看到4406进程是4407进程的1/5

(4)测试结束关闭后台进程(fg 打开后台的进程,ctrl+c 结束进程)

docker加密保护js docker 安全设置_容器_26

3.Block IO限制

使用ubuntu镜像拉起容器,并向其中写入数据
–device-write-bps /dev/vda:30MB:限制写设备的bps速度为30M。
oflag=direct:表示不通过内存到io设备,直接接入io设备。
可以看到直接接入io设备的情况下传输用了6.6秒,速度很慢;
当没有加上oflag=direct参数时,速度很快。、

docker加密保护js docker 安全设置_Docker_27

三、Docker安全加固

1.利用LXCFS增强docker容器隔离性和资源可见性

(1)安装LXCFS

docker加密保护js docker 安全设置_docker_28

(2)运行LXCFS

docker加密保护js docker 安全设置_docker_29

(3)创建一个容器,限制其内存为200M,可以看到内存被限制 

docker加密保护js docker 安全设置_linux_30

2.设置特权级运行的容器 

(1)运行一个容器,尝试关闭其eth0接口,显示操作不被允许

docker加密保护js docker 安全设置_容器_31

(2)重新运行该容器,启动时添加参数--privileged=true 

docker加密保护js docker 安全设置_docker_32

现在关闭eth0接口,可以看到操作成功

3.设置容器白名单

由于添加参数--privileged=true后权限过大,所以可以通过容器权限白名单来限制权限
如图,--cap-add=NET_ADMIN表示将网络操作的权限放入白名单,用户只可以进行网络操作

docker加密保护js docker 安全设置_容器_33

可以看到不能进行fdisk -l 操作 

4.安全加固思路

  • 保证镜像的安全
    使用安全的基础镜像
    删除镜像中的setuid和setgid权限
    启用Docker的内容信任
    最小安装原则
    对镜像进行安全漏洞扫描,镜像安全扫描器:Clair
    容器使用非root用户运行
  • 保证容器的安全
    对docker宿主机进行安全加固
    限制容器之间的网络流量
    配置Docker守护程序的TLS身份验证
    启用用户命名空间支持(userns-remap)
    限制容器的内存使用量
    适当设置容器CPU优先级