Docker-docker安全

黎腾
2023-12-01

1. 理解Docker安全

1.1  Docker容器的安全性,很大程度上依赖于Linux系统自身,评估Docker的安全性时,主要考虑以下几个方面:
        • Linux内核的命名空间机制提供的容器隔离安全
        • Linux控制组机制对容器资源的控制能力安全。
        • Linux内核的能力机制所带来的操作权限安全
        • Docker程序(特别是服务端)本身的抗攻击性。
        • 其他安全增强机制对容器安全性的影响。

1.2 命名空间隔离的安全
        • 当docker run启动一个容器时,Docker将在后台为容器创建一个独立的命名空间。命名空间提 供了最基础也最直接的隔离。
        • 与虚拟机方式相比,通过Linux namespace来实现的隔离不是那么彻底。
        • 容器只是运行在宿主机上的一种特殊的进程,那么多个容器之间使用的就还是同一个宿主机的操作系统内核。
        • 在 Linux 内核中,有很多资源和对象是不能被 Namespace 化的, 比如:时间。

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

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

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

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

2.  容器资源控制

2. 1 Linux Cgroups 的全称是 Linux Control Group。
     • 是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。
     • 对进程进行优先级设置、审计,以及将进程挂起和恢复等操作。

2.2  Linux Cgroups 给用户暴露出来的操作接口是文件系统。
     • 它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。
     • 执行此命令查看:mount -t cgroup

[root@lnmp0 ~]# mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)

     • 在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录,也叫子系统。

[root@lnmp0 ~]# cd /sys/fs/cgroup/
[root@lnmp0 cgroup]# ls
blkio  cpu  cpuacct  cpu,cpuacct  cpuset  devices  freezer  hugetlb  memory  net_cls  net_cls,net_prio  net_prio  perf_event  pids  systemd

     • 在每个子系统下面,为每个容器创建一个控制组(即创建一个新目录)。
     • 控制组下面的资源文件里填上什么值,就靠用户执行 docker run 时的参数指定。

2.3 CPU限额
      • docker run -it --cpu-period=100000 --cpu-quota=20000 ubuntu
      • cpu_period 和 cpu_quota 这两个参数需要组合使用,用来限制进程在长度为 cpu_period 的一段时间内,只能被分配到总量为cpu_quota 的 CPU 时间,以上设置表示20%的cpu时间。

2.3.1 没限额之前

运行容器

[root@lnmp0 docker]# docker run -it ubuntu
root@b7c9b9120961:/#  dd if=/dev/zero of=/dev/null &     ##拉取一个无限零设备,一个无限空设备,不耗磁盘,只消耗cpu
[1] 9
root@b7c9b9120961:/# 

CTRL+pq退出

查看cpu使用情况,可以看到在不做限制的情况下,cpu使用率为100%

[root@lnmp0 docker]# top
top - 06:26:59 up 21:17,  2 users,  load average: 1.80, 0.69, 0.60
Tasks: 213 total,   2 running, 211 sleeping,   0 stopped,   0 zombie
%Cpu(s): 19.3 us, 80.7 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1863220 total,   142432 free,   669968 used,  1050820 buff/cache
KiB Swap:  2097148 total,  2080424 free,    16724 used.   827160 avail Mem
 
   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
114170 root      20   0    2544    384    320 R 100.0  0.0   0:52.88 dd

在 /sys/fs/cgroup/cpu/docker/中会自动创建一个子目录,子目录名称和运行的容器id是一样的,在子目录的文件中会更加清楚的记录cpu,磁盘等等的使用情况

[root@lnmp0 ~]# docker ps
CONTAINER ID   IMAGE                                  COMMAND                  CREATED          STATUS                PORTS                       NAMES
b7c9b9120961   ubuntu                                 "bash"                   16 minutes ago   Up 16 minutes                                     flamboyant_lumiere
[root@lnmp0 ~]# cd /sys/fs/cgroup/cpu/docker/
[root@lnmp0 docker]# ls
cpuacct.usage  cpuacct.usage_percpu  cpu.cfs_period_us  cpu.cfs_quota_us  cpu.rt_period_us
cpu.rt_runtime_us   cpu.shares  cpu.stat
b7c9b912096164b695eee628b443197134e00e5e2bab35509eafba6267d0ac6f    cgroup.clone_children                                             
cgroup.event_control  notify_on_release     cgroup.procs                                         tasks   cpuacct.stat
[root@lnmp0 docker]# cd b7c9b912096164b695eee628b443197134e00e5e2bab35509eafba6267d0ac6f   ##自动创建一个子目录,子目录名称和运行的容器id是一样的,只不过docker ps看到的是缩短版的
[root@lnmp0 b7c9b912096164b695eee628b443197134e00e5e2bab35509eafba6267d0ac6f]# ls
cgroup.clone_children  cgroup.procs  cpuacct.usage         cpu.cfs_period_us  cpu.rt_period_us   cpu.shares  notify_on_release
cgroup.event_control   cpuacct.stat  cpuacct.usage_percpu  cpu.cfs_quota_us   cpu.rt_runtime_us  cpu.stat    tasks
[root@lnmp0 b7c9b912096164b695eee628b443197134e00e5e2bab35509eafba6267d0ac6f]# cat cpu.cfs_period_us
100000
[root@lnmp0 b7c9b912096164b695eee628b443197134e00e5e2bab35509eafba6267d0ac6f]# cat cpu.cfs_quota_us
-1          ##配额-1代表不做限制,百分比使用

2.3.2  限额之后

运行容器的时候,限制配额

[root@lnmp0 ~]# docker run -it --cpu-period=100000 --cpu-quota=20000 ubuntu  ##cpu_period 和 cpu_quota 这两个参数需要组合使用,用来限制进程在长度为 cpu_period 的一段时间内,只能被分配到总量为cpu_quota 的 CPU 时间,以上设置表示20%的cpu时间。
root@90e714081e0b:/# dd if=/dev/zero of=/dev/null &
[1] 9

查看cpu使用情况,可以看到在做限制之后的情况下,cpu使用率为20%

[root@lnmp0 ~]# top
top - 07:03:24 up 21:54,  2 users,  load average: 1.75, 2.06, 2.03
Tasks: 213 total,   3 running, 210 sleeping,   0 stopped,   0 zombie
%Cpu(s): 20.9 us, 79.1 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1863220 total,   151928 free,   658268 used,  1053024 buff/cache
KiB Swap:  2097148 total,  2080424 free,    16724 used.   839492 avail Mem

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
  7206 root      20   0    2544    384    320 R 20.0  0.0   0:37.99 dd

在 /sys/fs/cgroup/cpu/docker/子目录中查看限制配额后的情况

[root@lnmp0 ~]# cd  /sys/fs/cgroup/cpu/docker/
[root@lnmp0 docker]# docker ps
CONTAINER ID   IMAGE                                  COMMAND                  CREATED          STATUS                PORTS                       NAMES
90e714081e0b   ubuntu                                 "bash"                   8 minutes ago    Up 8 minutes                                      blissful_hamilton
[root@lnmp0 docker]# ls
90e714081e0b21a703e497f42292eb8965de4e6f5e1ffa164f1a11c79a8dcb38
cpuacct.usage  cpuacct.usage_percpu  cpu.cfs_period_us  cpu.cfs_quota_us  cpu.rt_period_us
cpu.rt_runtime_us   cpu.shares  cpu.stat group.clone_children                                             
cgroup.event_control  notify_on_release     cgroup.procs                                         tasks   cpuacct.stat
[root@lnmp0 docker]# cd 90e714081e0b21a703e497f42292eb8965de4e6f5e1ffa164f1a11c79a8dcb38/
[root@lnmp0 90e714081e0b21a703e497f42292eb8965de4e6f5e1ffa164f1a11c79a8dcb38]# ls
cgroup.clone_children  cgroup.procs  cpuacct.usage         cpu.cfs_period_us  cpu.rt_period_us   cpu.shares  notify_on_release
cgroup.event_control   cpuacct.stat  cpuacct.usage_percpu  cpu.cfs_quota_us   cpu.rt_runtime_us  cpu.stat    tasks
[root@lnmp0 90e714081e0b21a703e497f42292eb8965de4e6f5e1ffa164f1a11c79a8dcb38]# cat cpu.cfs_period_us
100000
[root@lnmp0 90e714081e0b21a703e497f42292eb8965de4e6f5e1ffa164f1a11c79a8dcb38]# cat cpu.cfs_quota_us
20000      ##和运行容器时做的配额限制一样
[root@lnmp0 90e714081e0b21a703e497f42292eb8965de4e6f5e1ffa164f1a11c79a8dcb38]# cat tasks
7206       ##控制哪些进程受限,7206是刚做的用top查看配额限制的id

2.4 内存限制
      • 容器可用内存包括两个部分:物理内存和swap交换分区。
      • docker run -it --memory 200M --memory-swap=200M ubuntu
      • --memory设置内存使用限额
      • --memory-swap设置swap交换分区限额

2.4.1 没做限制之前

运行容器

[root@lnmp0 ~]# docker run -d --name demo1 nginx
630ae768c5032966ab13638adde977ab4486b66143f79bee2f7a934c0fed519e
[root@lnmp0 ~]# docker ps
CONTAINER ID   IMAGE                                  COMMAND                  CREATED              STATUS                PORTS                       NAMES
630ae768c503   nginx                                  "/docker-entrypoint.…"   About a minute ago   Up About a minute     80/tcp                      demo1

在/sys/fs/cgroup/memory/docker/中会自动创建一个子目录,子目录名称和运行的容器id是一样的,在子目录的文件中会更加清楚的记录内存的使用情况

[root@lnmp0 ~]# cd /sys/fs/cgroup/memory/docker/
[root@lnmp0 docker]# ls
memory.kmem.tcp.failcnt                memory.kmem.tcp.limit_in_bytes
memory.kmem.tcp.max_usage_in_bytes     memory.kmem.tcp.usage_in_bytes
memory.kmem.usage_in_bytes             memory.limit_in_bytes
630ae768c5032966ab13638adde977ab4486b66143f79bee2f7a934c0fed519e  memory.max_usage_in_bytes              memory.memsw.failcnt
memory.memsw.limit_in_bytes            memory.memsw.max_usage_in_bytes
cgroup.clone_children                                           memory.memsw.usage_in_bytes
cgroup.event_control                                              memory.move_charge_at_immigrate
cgroup.procs                           memory.numa_stat
memory.oom_control                     memory.pressure_level
memory.soft_limit_in_bytes             memory.failcnt                        
memory.stat                            memory.force_empty                       
memory.swappiness                      memory.kmem.failcnt                    
memory.usage_in_bytes                  memory.kmem.limit_in_bytes                                        memory.use_hierarchy                   memory.kmem.max_usage_in_bytes                                    notify_on_release                      memory.kmem.slabinfo                                              tasks
[root@lnmp0 docker]# cd 630ae768c5032966ab13638adde977ab4486b66143f79bee2f7a934c0fed519e/
[root@lnmp0 630ae768c5032966ab13638adde977ab4486b66143f79bee2f7a934c0fed519e]# ls
cgroup.clone_children       memory.kmem.max_usage_in_bytes      memory.limit_in_bytes            memory.numa_stat            memory.use_hierarchy
cgroup.event_control        memory.kmem.slabinfo                memory.max_usage_in_bytes        memory.oom_control          notify_on_release
cgroup.procs                memory.kmem.tcp.failcnt             memory.memsw.failcnt             memory.pressure_level       tasks
memory.failcnt              memory.kmem.tcp.limit_in_bytes      memory.memsw.limit_in_bytes      memory.soft_limit_in_bytes
memory.force_empty          memory.kmem.tcp.max_usage_in_bytes  memory.memsw.max_usage_in_bytes  memory.stat
memory.kmem.failcnt         memory.kmem.tcp.usage_in_bytes      memory.memsw.usage_in_bytes      memory.swappiness
memory.kmem.limit_in_bytes  memory.kmem.usage_in_bytes          memory.move_charge_at_immigrate  memory.usage_in_bytes
[root@lnmp0 630ae768c5032966ab13638adde977ab4486b66143f79bee2f7a934c0fed519e]# cat memory.limit_in_bytes
9223372036854771712              ##不做限制的物理内存
[root@lnmp0 630ae768c5032966ab13638adde977ab4486b66143f79bee2f7a934c0fed519e]# cat memory.memsw.limit_in_bytes
9223372036854771712              ##不做限制的swapp分区

2.4.2 做限制之后

运行容器时对内存加以限制

[root@lnmp0 docker]# docker run -d --name demo  --memory 200M --memory-swap=200M nginx
3e397b10b8f4ac8711554a356add331e37d9ae87e3ea97f954f53c06853a82b6
[root@lnmp0 docker]# docker ps
CONTAINER ID   IMAGE                                  COMMAND                  CREATED         STATUS                PORTS                       NAMES
3e397b10b8f4   nginx                                  "/docker-entrypoint.…"   7 seconds ago   Up 6 seconds          80/tcp                      demo

在自动建立的子目录的文件中查看记录内存的使用情况

[root@lnmp0 ~]# cd /sys/fs/cgroup/memory/docker/
[root@lnmp0 docker]# ls
memory.failcnt                      memory.memsw.max_usage_in_bytes
memory.force_empty                  memory.memsw.usage_in_bytes
memory.kmem.failcnt                 memory.move_charge_at_immigrate
3e397b10b8f4ac8711554a356add331e37d9ae87e3ea97f954f53c06853a82b6  memory.kmem.limit_in_bytes          memory.numa_stat
memory.kmem.max_usage_in_bytes      memory.oom_control
memory.kmem.slabinfo                memory.pressure_level
memory.kmem.tcp.failcnt             memory.soft_limit_in_bytes
memory.kmem.tcp.limit_in_bytes      memory.stat
memory.kmem.tcp.max_usage_in_bytes  memory.swappiness
cgroup.clone_children                                             memory.kmem.tcp.usage_in_bytes      memory.usage_in_bytes
cgroup.event_control                                              memory.kmem.usage_in_bytes          memory.use_hierarchy
cgroup.procs                                                      memory.limit_in_bytes               notify_on_release
memory.max_usage_in_bytes           tasks
memory.memsw.failcnt
memory.memsw.limit_in_bytes
[root@lnmp0 docker]# cd 3e397b10b8f4ac8711554a356add331e37d9ae87e3ea97f954f53c06853a82b6/
[root@lnmp0 3e397b10b8f4ac8711554a356add331e37d9ae87e3ea97f954f53c06853a82b6]# ls
cgroup.clone_children       memory.kmem.max_usage_in_bytes      memory.limit_in_bytes            memory.numa_stat            memory.use_hierarchy
cgroup.event_control        memory.kmem.slabinfo                memory.max_usage_in_bytes        memory.oom_control          notify_on_release
cgroup.procs                memory.kmem.tcp.failcnt             memory.memsw.failcnt             memory.pressure_level       tasks
memory.failcnt              memory.kmem.tcp.limit_in_bytes      memory.memsw.limit_in_bytes      memory.soft_limit_in_bytes
memory.force_empty          memory.kmem.tcp.max_usage_in_bytes  memory.memsw.max_usage_in_bytes  memory.stat
memory.kmem.failcnt         memory.kmem.tcp.usage_in_bytes      memory.memsw.usage_in_bytes      memory.swappiness
memory.kmem.limit_in_bytes  memory.kmem.usage_in_bytes          memory.move_charge_at_immigrate  memory.usage_in_bytes
[root@lnmp0 3e397b10b8f4ac8711554a356add331e37d9ae87e3ea97f954f53c06853a82b6]# cat memory.limit_in_bytes
209715200             ##限制的是物理内存,这里出现的是字节数,换算过来和之前限制的内存使用量是一样的
[root@lnmp0 3e397b10b8f4ac8711554a356add331e37d9ae87e3ea97f954f53c06853a82b6]# cat memory.memsw.limit_in_bytes
209715200             ##这里限制的是swapp分区的使用量

2.5  Block IO限制
      • docker run -it --device-write-bps /dev/sda:30MB ubuntu
      • --device-write-bps限制写设备的bps,磁盘的IO速率
      • 目前的block IO限制只对direct IO有效。(不使用文件缓存)

没做block IO限制之前

[root@lnmp0 docker]#  docker run -it ubuntu
root@8287ed187198:/# dd if=/dev/zero of=bigfile bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.104512 s, 1.0 GB/s    ##没做限制之前拉取文件时间只需要0.104512 

做block IO限制之后

[root@lnmp0 ~]#  docker run -it --device-write-bps /dev/sda:30MB ubuntu    ##每秒30M的写入量
root@77aee0846918:/# dd if=/dev/zero of=bigfile bs=1M count=100 oflag=direct   ##正常设备数据会先写入到缓存,30s后刷新,再持久化到磁盘上,加上oflag=direct会直接写入到磁盘,不使用文件缓存,以达到限制写入速率的目的
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.34532 s, 31.3 MB/s           ##限制之后需要的时间达到了3.34532 
[root@lnmp0 docker]# docker ps
CONTAINER ID   IMAGE                                  COMMAND                  CREATED         STATUS                PORTS                       NAMES
77aee0846918   ubuntu                                 "bash"                   3 minutes ago   Up 3 minutes                                      confident_jennings

进入自动创建的目录中查看block IO限制情况,block IO限制自动创建的目在 /sys/fs/cgroup/blkio/

[root@lnmp0 ~]# cd /sys/fs/cgroup/blkio/docker/
[root@lnmp0 docker]# cd 77aee084691805b2cc88522a92e2acce9a2e1d052e1ab54c88b2642c32382aa6/
[root@lnmp0 77aee084691805b2cc88522a92e2acce9a2e1d052e1ab54c88b2642c32382aa6]# ls
blkio.io_merged                   blkio.io_serviced_recursive      blkio.reset_stats                blkio.throttle.write_bps_device   cgroup.event_control
blkio.io_merged_recursive         blkio.io_service_time            blkio.sectors                    blkio.throttle.write_iops_device  cgroup.procs
blkio.io_queued                   blkio.io_service_time_recursive  blkio.sectors_recursive          blkio.time                        notify_on_release
blkio.io_queued_recursive         blkio.io_wait_time               blkio.throttle.io_service_bytes  blkio.time_recursive              tasks
blkio.io_service_bytes            blkio.io_wait_time_recursive     blkio.throttle.io_serviced       blkio.weight
blkio.io_service_bytes_recursive  blkio.leaf_weight                blkio.throttle.read_bps_device   blkio.weight_device
blkio.io_serviced                 blkio.leaf_weight_device         blkio.throttle.read_iops_device  cgroup.clone_children
[root@lnmp0 77aee084691805b2cc88522a92e2acce9a2e1d052e1ab54c88b2642c32382aa6]# cat blkio.throttle.write_bps_device
8:0 31457280      ##此文件显示block IO限制情况,8:0代表/dev/sda的设备标识
[root@lnmp0 77aee084691805b2cc88522a92e2acce9a2e1d052e1ab54c88b2642c32382aa6]# ll -d /dev/sda
brw-rw---- 1 root disk 8, 0 Jun 29 23:18 /dev/sda   

3.  docker安全加固

3.1  利用LXCFS增强docker容器隔离性和资源可见性
       • yum install -y lxcfs-2.0.5-3.el7.centos.x86_64.rpm
       • lxcfs /var/lib/lxcfs &
       •  docker run -it --rm --memory 200M --memory-swap 200M 
         -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw 
         -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw 
         -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw 
         -v /var/lib/lxcfs/proc/stat:/proc/stat:rw 
         -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw 
         -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw 
         ubuntu

3.1.1  不做容器隔离的情况下

[root@lnmp0 ~]# docker run -it --rm --memory 200M --memory-swap=200M ubuntu
root@af636009f58b:/# free -m
              total        used        free      shared  buff/cache   available
Mem:           1819         693         134         257         991         690
Swap:          2047         139        1908
root@af636009f58b:/# exit
[root@lnmp0 ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:           1819         557         154         257        1107         711
Swap:          2047         139        1908

##可以看到在容器中显示的是我们主机的磁盘使用情况,但是运行容器的时候实际上是做了磁盘使用限制的,而且容器的磁盘使用量实际也只有我们做了限制的200M, 这样就出现了容器磁盘实际使用量与磁盘可见性不符的问题

3.1.2 容器隔离后,磁盘使用量的可见性

首先先下载容器隔离所用到的工具

[root@lnmp0 ~]# yum install -y lxcfs-2.0.5-3.el7.centos.x86_64.rpm
Loaded plugins: langpacks, product-id, search-disabled-repos, subscription-manager
This system is not registered with an entitlement server. You can use subscription-manager to register.
.....
Installed:
  lxcfs.x86_64 0:2.0.5-3.el7.centos

Complete!
[root@lnmp0 ~]# lxcfs /var/lib/lxcfs &  ##启动lxcfs,打入后台
[1] 89507
[root@lnmp0 ~]# hierarchies:
  0: fd:   5: devices
  1: fd:   6: freezer
  2: fd:   7: hugetlb
  3: fd:   8: perf_event
  4: fd:   9: cpuset
  5: fd:  10: cpuacct,cpu
  6: fd:  11: memory
  7: fd:  12: net_prio,net_cls
  8: fd:  13: blkio
  9: fd:  14: pids
 10: fd:  15: name=systemd
PID file '/run/lxcfs.pid' is already locked.

[2]+  Exit 1                  lxcfs /var/lib/lxcfs/

运行容器做磁盘限制时将lxcfs下的文件挂载到容器中

[root@lnmp0 ~]# docker run -it --rm --memory 200M --memory-swap 200M -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw  -v /var/lib/lxcfs/proc/stat:/proc/stat:rw -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw ubuntu
root@03e6178df1d6:/# free -m
              total        used        free      shared  buff/cache   available
Mem:            200           0         199         257           0         199
Swap:             0           0           0
root@03e6178df1d6:/#

##做完隔离后,运行容器时限制的磁盘是多少,进入容器查看到的就是多少

3.2   设置特权级运行的容器:--privileged=true
     • 有的时候我们需要容器具备更多的权限,比如操作内核模块,控制swap交换分区,挂载USB磁盘,修改MAC地址等。

3.2.1 不加特权进入容器

[root@lnmp0 ~]# docker run -it --rm busybox
ip: SIOCSIFFLAGS: Operation not permitted
/ # id
uid=0(root) gid=0(root) groups=10(wheel)
/ #

##可以发现,我们进入容器所持的身份虽然是root,但依然会受限制

3.2.2 设置特权级运行的容器

[root@lnmp0 ~]# docker run -it --rm --privileged=true busybox    ##设置特权运行容器
/ # ip link set down eth0
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
332: eth0@if333: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ip link set up eth0
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
332: eth0@if333: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ #

设置特权后,进入容器虽然权限会比较高,但使用一定要注意,不然可能你在容器中所做的一些操作会直接影响你的主机,三思而后行。

3.3  设置容器白名单:--cap-add
        • --privileged=true 的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限制,只提供给容器必须的权限。此时Docker 提供了权限白名单的机制,使用--cap-add添加必要的权限。
        • capabilities手册地址:http://man7.org/linux/man-pages/man7/capabilities.7.html
        • # docker run -it --cap-add=NET_ADMIN busybox

还有更多的能力机制建议参考官方文档

[root@lnmp0 ~]# docker run -it --rm --cap-add=NET_ADMIN busybox
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
334: eth0@if335: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ip addr add 10.0.0.1/24 dev eth0
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
334: eth0@if335: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.0.0.1/24 scope global eth0
       valid_lft forever preferred_lft forever
/ # ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1): 56 data bytes
64 bytes from 10.0.0.1: seq=0 ttl=64 time=0.068 ms
64 bytes from 10.0.0.1: seq=1 ttl=64 time=0.043 ms
^C
--- 10.0.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.043/0.055/0.068 ms

3.4  安全加固的思路
        • 保证镜像的安全
              • 使用安全的基础镜像
              • 删除镜像中的setuid和setgid权限
              • 启用Docker的内容信任
              • 最小安装原则
              • 对镜像进行安全漏洞扫描,镜像安全扫描器:Clair
              • 容器使用非root用户运行

3.5  docker安全的遗留问题
     • 主要的内核子系统都没有命名空间,如:
        • SELinux
        • cgroup
        • 在 /sys 下的文件系统
        • / proc/sys , /proc/sysrq-trigger, /proc/irq , /proc/bus
    • 设备没有命名空间:
        • /dev/mem
        • /dev/sd* 文件系统设备
        • 内核模块

如果你能沟通或攻击的其中之一作为特权的过程中,你可以拥有自己的系统。

4 . Docker安全的顶尖开源工具:
• Docker Bench for Security          对照安全基准审计 Docker 容器的脚本  
• Clair                                             API 驱动的静态容器安全分析工具,拥有庞大的 CVE 数据库
• Cilium                                          内核层可感知 API 的网络和安全工具
• Anchore                                      使用 CVE 数据和用户定义的策略检查容器安全的工具
• OpenSCAP Workbench              用于为各种平台创建和维护安全策略的环境
• Dagda 用于在 Docker                 容器中扫描漏洞、特洛伊木马、病毒和恶意软件的工具
• Notary                                         使用服务器加强容器安全的框架,用于以加密方式委派责任
•Sysdig Falco                                提供了行为活动监控,可深入了解容器

docker的安全现状,虽然还是有很多没有完善的地方, 但不能否认docker依然是当前最安全的容器技术。
 类似资料: