Day29-保护鲸鱼人人有责(四)

前言

前几天不管是讲怎麽把 Dockerfile 写好、还是做弱点扫描,基本上都是在确保 Docker image 本身的安全性。而今天要讲的则是在启动一个 image 时,要加上哪些参数或设定才可以让安全性再往上提高一个层次

不要在 container 中使用 root user

只要用过一阵子 Docker 应该就会知道,预设情况下我们在跑 docker run image 时 Docker Daemon 会用 root user 帮我们把 container 跑起来,而且在 container 中也是以 root 的身份执行程序

那这样有什麽问题呢?因为底层的 Docker Daemon 或是 Linux kernel 可能会有漏洞,所以攻击者可以藉由应用程序的漏洞,先取得在 container 内的 root 权限,再藉着 Linux kernel 的漏洞成功得到你机器上的 root 权限也就可以在你的机器上做任何想做的事

因为被取得 root 权限实在是太严重了,所以其中一个解决方法就是在启动 container 时指定随意一个 user ID,这样即便骇客成功进入 container 也没办法拿到 root 权限

docker run --user 3000 <image>

而如果你是用 docker-compose 来启动的话,也是直接在设定里面加上 user 属性就好了,轻轻松松就提高了安全性

services:
  api-server:
    restart: always
    image: server
    user: "3000"
    ports:
      - "4000:4000"

限制 container 能做的事

为了方便管理权限,Linux kernel 从 2.1 开始引入了 capability 的概念,他把 root 的特殊权限细分为非常多类,譬如说 CAP_CHOWN 是允许改变档案的所有权、CAP_KILL 是可以对任意 process 发送 signal、CAP_NET_ADMIN 是可以管理防火墙跟路由等等网路设定

而 Docker daemon 预设在启动 container 时也会给他其中一些权限,虽然说有权限好办事,但 container 有了那些权限之後如果没有好好管理反而会提高风险,因此如果只是一个普通的 API Server 没有特别的需求的话,我会建议在启动 container 时就直接加上 --cap-drop ALL 来取消所有特权,除非你的 server 哪天真的需要管理防火墙(几乎没有这种需求吧),那可以再用 --cap-add CAP_NET_ADMIN <image> 单独把网路管理的权限开起来

docker run --cap-drop ALL <image> # 关掉所有权限
docker run --cap-drop ALL --cap-add CAP_NET_ADMIN <image> # 只给网管权限

而 docker-compose 的话也很简单,只要设定一下 cap-addcap-drop 属性就好了~

services:
  api-server:
    image: server
    ports:
      - "4000:4000"
    cap_drop:
      - ALL
    cap_add:
      - NET_ADMIN
      - SYS_ADMIN

用 read only 模式把 container 跑起来

如果你的 API server 跑起来之後不会需要修改或新增档案(大多数 API server 应该都是这样),那可以直接加上 --read-only 用唯读模式把 container 跑起来,如此一来即便你的 container 被入侵了,那骇客也没办法在里面修改任何档案、程序码,所以就可以降低损害(有很多攻击都是透过修改 production 程序码或是 nginx 设定达成的)

docker run --read-only <image>

如下图,如果你成功入侵一个 read-only 的 container,并且尝试要新增一个叫做 newFile 的档案,就会马上喷出 Read-only file system 错误,你能做的就只有看看 container 里面有哪些东西

而 docker-compose 设定起来也很简单,只要加上一个 read_only 属性就好了哦~

services:
  api-server:
    image: server
    ports:
      - "4000:4000"
    read_only: true

虽然 read only 听起来好像限制了很多功能,但其实很适合现在大多数的 API Server。尤其现在为了方便水平扩展,上传头贴、照片这类的功能基本上都是传到 s3,资料库很多也是用 RDS 之类的服务,完全不会需要在 container 内写入档案,所以除非有什麽困难,不然真的很推荐把 read only 模式开起来

小结

今天讲了几个要把 image 跑起来时可以设定的小地方,因为用 docker run 要加上一堆参数很冗长、一不小心还可能忘记,所以在 production 上建议至少都要用 docker-compose 来启动(当然 Swarm 或 K8s 也可以),这样一来只要把以上那些设定加进去 yaml 里面,container 跑起来就超安全的哦

关於 Docker 的内容就讲到今天,如果对於这几天 Docker 相关的内容有什麽疑问欢迎在下方留言,都没问题的话明天就是总结了~谢谢大家~


<<:  【Day 29】函式(下)

>>:  Day29-TypeScript(TS)的模组(Modules) Part1

Day27 go-elasticsearch(一)

今日我们将要介绍ES官方提供go-elasticsearch客户端的基本操作。 go-elastic...

Day 28 Explore monitoring and reporting

Compare authentication and authorization Authentic...

#21 JS: Object - Constructors

About Constructors “The way to create an 'object t...

[Day8] 关於人脸侦测(Face Detection)的二三事

本篇文没有引言,不罗嗦。 本文开始 人脸侦测是物体侦测(Object Detection)的一种;...

[DAY-15] 认知科学中的成功之路

一半拉! 加油! YA~ 心理学的研究 其实可以协助大家思考职涯 BUT 很少人接触这方面的讯息 ...