Docker (4) docker安全与容器资源控制及安全优化

Docker安全

docker 容器的安全很大程度上依赖 linux 本身,因为是共享宿主机内核。

docker 安全评估主要考虑以下几个方面:

  • linux 内核的命名空间(namespace)机制提供的容器隔离安全
  • linux 控制组(cgroup)对容器资源的控制能力安全
  • linux 内核的能力机制所带来的操作系统安全
  • docker 程序(主要是服务器端)本身的抗攻击能力
  • 其他安全增强机制的影响
命名空间隔离安全

docker run 启动一个容器时,后台会为容器创建一个独立的命名空间:
这是最基础的隔离,让容器作为一个独立的个体存在

[root@server1 ~]# docker run -it --name vm1 busyboxplus
/ # [root@server1 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
92842335e0c1        busyboxplus         "/bin/sh"           10 seconds ago      Up 8 seconds                            vm1
[root@server1 ~]# docker inspect ^C
[root@server1 ~]# docker inspect vm1 | grep Pid
            "Pid": 5044,
            "PidMode": "",
            "PidsLimit": null,
[root@server1 ~]# ps ax | grep 5044
 5044 pts/0    Ss+    0:00 /bin/sh
 5211 pts/0    S+     0:00 grep --color=auto 5044
[root@server1 ~]# cd /proc/5044/ns/  ## 这是5044的命名空间namespace
[root@server1 ns]# ls
ipc  mnt  net  pid  user  uts

缺点: 在 linux 内核中,有些资源和对象不能被 namespace 化,如:时间,这样就 不能保证完全隔离了

控制组资源控制安全

docker run 启动一个容器时,后台会为容器创建一个独立的控制组策略集合

[root@server1 ~]# 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/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
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/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
[root@server1 ~]# cd /sys/fs/cgroup/
[root@server1 cgroup]# ls
blkio  cpu  cpuacct  cpu,cpuacct  cpuset  devices  freezer  hugetlb  memory  net_cls  net_cls,net_prio  net_prio  perf_event  pids  systemd   
[root@server1 cgroup]# cd cpu/docker/
[root@server1 docker]# ls
92842335e0c16565d469d3fd1b1441c2b6958cde8c44fd1f7e9274c21fb8b828  cgroup.event_control  cpuacct.stat   cpuacct.usage_percpu  cpu.cfs_quota_us  cpu.rt_runtime_us  cpu.stat           tasks
cgroup.clone_children                                             cgroup.procs          cpuacct.usage  cpu.cfs_period_us     cpu.rt_period_us  cpu.shares         notify_on_release
[root@server1 docker]# cd 92842335e0c16565d469d3fd1b1441c2b6958cde8c44fd1f7e9274c21fb8b828/
[root@server1 92842335e0c16565d469d3fd1b1441c2b6958cde8c44fd1f7e9274c21fb8b828]# 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

linux cgroup 保证了不会因为某个容器占用资源过多而影响到其他容器

内核能力机制

linux 内核的一个强大特性,可提供细粒度的权限访问控制
大部分情况下,容器并不需要真正的 root 权限,只要少数能力即可

[root@server1 ~]# docker attach vm1
/ # id
uid=0(root) gid=0(root) groups=10(wheel)
/ # ip a
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
6: eth0@if7: <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 link set down eth0
ip: SIOCSIFFLAGS: Operation not permitted

即使是root 用户也不能关闭网卡

docker 服务端的防护

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

其他安全特性

使用有增强安全特性的容器模板;用户可以定义更加严格的访问控制机制等
(比如文件系统挂载到容器内部时,设置只读)

容器资源控制

操作系统层面控制
yum install libcgroup-tools.x86_64 -y ### 安装cgroup控制工具

启动一个dd进程 只消耗cpu

dd if=/dev/zero of=/dev/null &

在这里插入图片描述
在/sys/fs/cgroup/cpu新建目录a1

[root@server1 a1]# pwd
/sys/fs/cgroup/cpu/a1
[root@server1 a1]# echo 20000 > cpu.cfs_quota_us

让进程id和tasks关联 (3686为dd进程Pid)

[root@server1 a1]# echo 3686 > tasks 

在这里插入图片描述

容器层面控制

限制容器使用内存:
docker run --help

-m,   --memory bytes                   Memory limit
      --memory-reservation bytes       Memory soft limit
      --memory-swap bytes              Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --memory-swappiness int          Tune container memory swappiness (0 to 100) (default -1)
[root@server1 ~]# docker run -it --name test --memory 50M --memory-swap 50M busybox
/ # cd /dev/shm/
/dev/shm # touch bigfile
/dev/shm # free -m
              total        used        free      shared  buff/cache   available
Mem:            990         195         428           0         367         654
Swap:          2047           0        2047
/dev/shm # dd if=/dev/zero of=bigfile bs=1M count=50
Killed
/dev/shm # dd if=/dev/zero of=bigfile bs=1M count=40
40+0 records in
40+0 records out
41943040 bytes (40.0MB) copied, 0.100185 seconds, 399.3MB/s

当超出设定容器限额内存时 直接被kill
启动一个内存限制为50M的nginx

docker run -d --name web --memory 50M --memory-swap 50M nginx

在这里插入图片描述
在这里插入图片描述
实际上docker run 加的参数 也是利用cgroup实现的 在运行一个容器后 会在cgroup生产对应的限制目录 并将tasks和Pid相关联
docker run 启动一个容器时,后台会为容器创建一个独立的控制组策略集合

docker安全加固

在对容器做内存限制时 虽然实际上只能使用50M 但是看到的总内存和容器外一样,没有做到完全的隔离,需要进行安全加固。

[root@server1 ~]# docker run -it --rm --memory 50M --memory-swap 50M busybox 
/ # free -m
              total        used        free      shared  buff/cache   available
Mem:            990         195         507           0         288         654
Swap:          2047           0        2047
/ #
lxcfs
  • 安装
yum install -y lxcfs-2.0.5-3.el7.centos.x86_64.rpm

启动lxcfs

[root@server1 ~]# lxcfs /var/lib/lxcfs/ &
[1] 4349
[root@server1 ~]# hierarchies:
  0: fd:   5: cpuset
  1: fd:   6: memory
  2: fd:   7: blkio
  3: fd:   8: pids
  4: fd:   9: devices
  5: fd:  10: net_prio,net_cls
  6: fd:  11: freezer
  7: fd:  12: perf_event
  8: fd:  13: hugetlb
  9: fd:  14: cpuacct,cpu
 10: fd:  15: name=systemd

[root@server1 ~]# cd /var/lib/lxcfs/
[root@server1 lxcfs]# ls
cgroup  proc
[root@server1 lxcfs]# cd proc/
[root@server1 proc]# ls
cpuinfo  diskstats  meminfo  stat  swaps  uptime

不再使用宿主机的proc而是用/var/lib/lxcfs/proc代替

[root@server1 ~]# docker run -it --rm --memory 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@24f409e6a98b:/# free -m
              total        used        free      shared  buff/cache   available
Mem:            200           8         191           6           0         191
Swap:           200           0         200
设置特权级运行的容器
 --privileged=true 
[root@server1 ~]# docker run -it --rm busyboxplus 
/ # ip a
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
10: eth0@if11: <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 172.17.0.3/16 dev eth0
ip: RTNETLINK answers: Operation not permitted
/ # [root@server1 ~]# 
[root@server1 ~]# docker run -it --rm --privileged=true busyboxplus 
/ # ip addr add 172.17.0.3/16 dev eth0
/ # ip a
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
12: eth0@if13: <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 172.17.0.3/16 scope global secondary eth0
       valid_lft forever preferred_lft forever

默认情况下这个权限比较大,基本上接近宿主机的权限,为了防止用户的权限滥用, 需要增加机制,只提供给容器必要的权限,相当于做 sudo的用户权力下放

容器白名单
http://man7.org/linux/man-pages/man7/capabilities.7.html

在这里插入图片描述

[root@server1 ~]# docker run -it --rm --cap-add 
ALL              DAC_READ_SEARCH  LEASE            MAC_OVERRIDE     SYS_ADMIN        SYS_MODULE       SYS_PTRACE       SYS_TIME         
AUDIT_CONTROL    IPC_LOCK         LINUX_IMMUTABLE  NET_ADMIN        SYS_BOOT         SYS_NICE         SYS_RAWIO        SYS_TTY_CONFIG   
BLOCK_SUSPEND    IPC_OWNER        MAC_ADMIN        NET_BROADCAST    SYSLOG           SYS_PACCT        SYS_RESOURCE     WAKE_ALARM 
[root@server1 ~]# docker run -it --rm --cap-add=NET_ADMIN  busyboxplus 
/ # ip a
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
14: eth0@if15: <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 172.17.0.4/16 dev eth0
/ # ip a
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
14: eth0@if15: <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 172.17.0.4/16 scope global secondary eth0
       valid_lft forever preferred_lft forever
Docker安全加固思路
镜像安全
  • 使用安全的基础镜像(比如看不到构建历史的不用)
  • 删除镜像中的 setuid 和 setgid 权限(suid、sgid)
  • 启用 docker 内容信任(证书认证);最小安装原则
  • 对镜像进行安全漏洞扫描,镜像安全扫描 器(Clair)
  • 容器使用非 root 运行
容器安全
  • 对 docker 宿主机进行安全加固
  • 限制容器之间的网络流量(某个容器流量升高,会对其他容器或主机有影响)
  • 配置 docker 守护程序的 TLS 身份验证
  • 启用用户命名空间支持(userns-remap )
  • 限制容器内存使用量;
  • 适当设置容器 CPU 优先级
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值