第三节:了解容器的安全机制与缺陷

admin 2024年2月1日22:42:12评论24 views字数 28817阅读96分3秒阅读模式
基础到深度
了解容器安全

容器自身在安全设计和安全防护上有充足的考虑,正如著名的Laravel框架有有成熟的SQL注入防护手段,现网应用仍旧存在大量SQL注入漏洞,设计、落地与应用之前存在巨大的鸿沟,这一点我们在域渗透也有着深刻体会。事实上,容器场景与域网络场景有些类似,同样是运维建网,同样是配置与使用不当,或许是同一拨人搞出的同一原理的隐患(滑稽脸)。

因此当我在谈论容器的安全机制与安全设计的时候,同时也要关注默认配置、逻辑缺陷等等。因此我们第三节主要探讨一下容器的安全机制与缺陷。

01
容器安全机制之Docker容器安全机制
第三节:了解容器的安全机制与缺陷

Docker安全是确保容器化应用在生产环境和云环境部署中稳定、可靠运行的关键因素。Docker通过集成一系列操作系统级别的安全机制,为用户提供了一套相对完善的安全方案

A.传输层安全(TLS)加密通信

    Docker守护进程(Docker Daemon)支持通过TCP监听,并配置TLS证书以加密客户端和服务端之间的通信,保障了控制指令和数据传输过程的安全性。

    为了防止链路劫持、会话劫持等问题导致 Docker 通信时被中间人攻击,c/s 两端应该通过加密方式通讯。实现了docker远程访问控制过程的安全性。

    首先创建CA密钥和证书:

[root@server2 ~]# mkdir /tls  #创建工作目录[root@server2 ~]# cd /tls/[root@server2 tls]# hostnamectl set-hostname master[root@server2 tls]# su[root@master tls]# vi /etc/hosts  #做映射,允许用主机名访问172.0.0.1 master#创建ca密钥,生成对称密钥[root@master tls]# openssl genrsa -aes256 -out ca-key.pem 4096   Generating RSA private key, 4096 bit long modulus............................................................................................++...........................++e is 65537 (0x10001)Enter pass phrase for ca-key.pem:   #输入生成密钥的密码,自行设置,这里我用123123Verifying - Enter pass phrase for ca-key.pem:#根据密钥,创建CA证书,证书格式为x509规范,证书有效期1000天,命名为ca.pem,-sha256哈希验证用于保证数据通信完整性[root@master tls]# openssl req -new -x509 -days 1000 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pemEnter pass phrase for ca-key.pem:  #输入123123#在当前目录下就生成了一对密钥和证书[root@master tls]# ll总用量 8-rw-r--r--. 1 root root 3326 123 14:47 ca-key.pem-rw-r--r--. 1 root root 1765 123 14:49 ca.pem

    基于CA证书,创建服务端的密钥和证书

#创建服务器私钥[root@master tls]# openssl genrsa -out server-key.pem 4096Generating RSA private key, 4096 bit long modulus.++....................++e is 65537 (0x10001)#签名私钥[root@master tls]# openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr#使用ca的证书与密钥、私钥的签名,创建服务器的证书,名为server-cert.pem,输入123123(CA的密钥)[root@master tls]# openssl x509 -req -days 1000 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pemSignature oksubject=/CN=*Getting CA Private KeyEnter pass phrase for ca-key.pem:

创建客户端密钥和证书

#生成密钥[root@master tls]# openssl genrsa -out key.pem 5096Generating RSA private key, 5096 bit long modulus....................++......++e is 65537 (0x10001)#签名密钥[root@master tls]# openssl req -subj "/CN=client" -new -key key.pem  -out client.csr#创建配置文件,表名是客户端证书[root@master tls]# echo extendedKeyUsage=clientAuth > extfile.cnf#签名客户端,CA证书,CA密钥,创建客户端证书名为cert.pem[root@master tls]# openssl x509 -req -days 1000 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnfSignature oksubject=/CN=clientGetting CA Private KeyEnter pass phrase for ca-key.pem:  #输入123123

配置docker,支持TLS加密通信

[root@master tls]# vi /lib/systemd/system/docker.service ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/tls/ca.pem --tlscert=/tls/server-cert.pem --tlskey=/tls/server-key.pem -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock   #配置TLS,配置本机服务端密钥和证书,sock文件就是用来实现通讯的文件,暴露2376端口给远程访问#重启进程,和docker服务[root@master tls]# systemctl daemon-reload [root@master tls]# systemctl restart docker.service

将 /tls/ca.pem /tls/cert.pem /tls/key.pem 三个文件复制到客户机

[root@master tls]# scp cert.pem [email protected]:/etc/docker/[email protected]'s password: cert.pem                                                     100% 1696   202.4KB/s   00:00    [root@master tls]# scp key.pem [email protected]:/etc/docker/[email protected]'s password: key.pem                                                      100% 3247   338.2KB/s   00:00 [root@master tls]# scp ca.pem [email protected]:/etc/docker/[email protected]'s password: ca.pem                                                       100% 1765   190.9KB/s   00:00  #客户端查看[root@client1 docker]# ll总用量 20-rw-r--r--. 1 root root 1765 11月 30 17:33 ca.pem-rw-r--r--. 1 root root 1696 11月 30 17:31 cert.pem-rw-r--r--. 1 root root   68 11月 30 15:26 daemon.json-rw-------. 1 root root  244 11月 30 15:22 key.json-rw-r--r--. 1 root root 3247 11月 30 17:31 key.pem

客户端添加服务端的映射,可用主机名访问

[root@client1 docker]# vi /etc/hosts192.168.247.140 master

客户机以TLS方式远程连接服务端容器

#查看version版本信息,也可跟其他命令对容器进行操作[root@client1 docker]# docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H tcp://master:2376 version  Client: Docker Engine - Community Version:           19.03.13 API version:       1.40 Go version:        go1.13.15 Git commit:        4484c46d9d Built:             Wed Sep 16 17:03:45 2020 OS/Arch:           linux/amd64 Experimental:      falseServer: Docker Engine - Community Engine:  Version:          19.03.13  API version:      1.40 (minimum version 1.12)  Go version:       go1.13.15  Git commit:       4484c46d9d  Built:            Wed Sep 16 17:02:21 2020  OS/Arch:          linux/amd64  Experimental:     false containerd:  Version:          1.3.7  GitCommit:        8fba4e9a7d01810a393d5d25a3621dc101981175 runc:  Version:          1.0.0-rc10  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd docker-init:  Version:          0.18.0  GitCommit:        fec3683

B.镜像签名与验证

第三节:了解容器的安全机制与缺陷

Docker Registry支持对镜像进行签名,当用户拉取或推送镜像时,可以验证镜像的完整性和来源,防止恶意代码被植入到基础镜像中。

使用 Docker Engine 将镜像推、拉到公共或私有仓库中,镜像签名能够保证,通过任何渠道从仓库获取到的镜像是完整的和可信任的。

Docker Content Trust(DCT)提供了对从远程 Docker 仓库上传和下载的镜像文件,使用数字签名的能力,其能够保证镜像文件的完整性和发布者的可信性。DCT 通过 Docker 标签对镜像文件是否进行签名进行区分,镜像发布者可以自行决定在哪些标签上进行签名。DCT 实现的是客户端的签名和验证,意味着由 Docker 客户端执行它们。

第三节:了解容器的安全机制与缺陷

镜像标签的信任是,通过使用签名密钥来管理的。第一次使用 DCT 来操作时,将创建密钥集,由以下类密钥组成:

  • 根密钥 - root key

    • 它用于创建和签名新的库密钥,因此应该被妥善保管

    • an offline key that is the root of DCT for an image tag

  • 库密钥 - 标签密钥 - repository key

    • 用于对需要推送到指定镜像库的打标签的镜像进行签名

    • repository or tagging keys that sign tags

  • 时间戳密钥 - timeStamp key

    • 它被保存在远程镜像库中,用于一些更加高级的使用场景以确保时效性

    • server-managed keys such as the timestamp key, which provides freshness security guarantees for your repository

使用我们自建的 notary(一个用于建立内容之间信任的平台)服务进行容器签名 。在 Docker CLI 中,我们可以使用 docker trust 命令对容器文件进行签名和推送。但是需要注意的是,必须要部署一个公证服务器(notary)才可以对容器镜像进行签名。

# Notary Server$ git clone https://github.com/theupdateframework/notary.git$ docker-compose up -d

要签名一个 Docker 镜像,需要一个密钥对,其可以使用命令在本地生成(默认情况下存储在 ~/.docker/trust/ 中),也可以由来自证书机构。

# 本地生成$ docker trust key generate point_meGenerating key for point_me...Enter passphrase for new point_me key with ID 9deed25:Repeat passphrase for new point_me key with ID 9deed25:Successfully generated and loaded private key.# 使用已有$ docker trust key load key.pem --name point_meLoading key from "key.pem"...Enter passphrase for new point_me key with ID 8ae710e:Repeat passphrase for new point_me key with ID 8ae710e:Successfully imported key from key.pem

我们将公钥添加到公证服务器上。如果是第一次执行的话,需要输入一些相关信息,才可以使用。

$ docker trust signer add --key cert.pem point_me registry.example.com/admin/demoAdding signer "point_me" to registry.example.com/admin/demo...Enter passphrase for new repository key with ID 10b5e94:

我们将使用私钥对特定镜像文件的标签进行签名,并将其推到仓库中去。

# 签名$ docker trust sign registry.example.com/admin/demo:1Signing and pushing trust data for local image registry.example.com/admin/demo:1, may overwrite remote trust dataThe push refers to repository [registry.example.com/admin/demo]7bff100f35cb: Pushed1: digest: sha256:3d2e482b82608d153a374df3357c0291589a61cc194ec4a9ca2381073a17f58e size: 528Signing and pushing trust metadataEnter passphrase for signer key with ID 8ae710e:Successfully signed registry.example.com/admin/demo:1# 启用$ export DOCKER_CONTENT_TRUST=1# 推送$ docker push registry.example.com/admin/demo:1The push refers to repository [registry.example.com/admin/demo:1]7bff100f35cb: Pushed1: digest: sha256:3d2e482b82608d153a374df3357c0291589a61cc194ec4a9ca2381073a17f58e size: 528Signing and pushing trust metadataEnter passphrase for signer key with ID 8ae710e:Successfully signed registry.example.com/admin/demo:1# 查看$ docker trust inspect --pretty registry.example.com/admin/demo:1# 删除远程服务器对该镜像的信任$ docker trust revoke registry.example.com/admin/demo:1Enter passphrase for signer key with ID 8ae710e:Successfully deleted signature for registry.example.com/admin/demo:1

Docker 客户端默认禁用镜像签名,如果希望启用,则将 DOCKER_CONTENT_TRUST 环境变量设置为 1 即可。这将阻止用户使用带有非签名的图像文件,对应对应的客户端命令,比如 pushbuildcreatepull 和 run

# 拉取失败$ docker pull registry.example.com/user/image:1Error: remote trust data does not exist for registry.example.com/user/image: registry.example.com does not have trust data for registry.example.com/user/image# 拉取成功$ docker pull registry.example.com/user/image@sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819asha256:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1: Pulling from user/imageff3a5c916c92: Pull completea59a168caba3: Pull completeDigest: sha256:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1Status: Downloaded newer image for registry.example.com/user/image@sha256:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1

下面通过一个简单的配置 DCT 的实战例子予以阐述。我们需要一个 Docker 客户端和一个用来推送镜像的库,Docker Hub 上的镜像库即可。

# 启用特性$ export DOCKER_CONTENT_TRUST# 登录hub.docker仓库$ docker login#  对镜像打标签并推送到目标镜像库$ docker image tag alpine:latest escape/dockerbook:v1# 推送打了新标签的镜像# 在签名时会创建两个密钥,根密钥和库密钥$ docker image push nigelpoulton/dockerbook:v1# 在拉取镜像时使用如下命令来覆盖DCT设置$ docker image pull --disable-content-trust nigelpoulton/dockerbook:unsigned# 尝试运行未签名的镜像容器$ docker container run -d --rm nigelpoulton/dockerbook:unsigneddocker: No trust data for unsigned.

接下来介绍通过Docker+Harbor实现对镜像进行签名

Docker 集成了Notary的客户端,Docker Hub、Harbor等镜像仓库又集成了Notary Server,Docker 通过Notary进行镜像的签名;

Notary是一个基于 TUF 项目的用于软件制品签名的开源软件;Notary同时也是一个用于建立内容之间信任的平台,在容器镜像中可以对镜像进行加密签名用来保证镜像件来源和镜像内容防篡改。

(1)Harbor初始化

#Harbor启动开启Notary./install --with-notary

harbor安装时可以添加--with-notary参数来使得harbor具有签名的功能,实际上就是会多启两个容器,分别为:goharbor/notary-server-photon:v2.0.0、goharbor/notary-signer-photon:v2.0.0

第三节:了解容器的安全机制与缺陷

Harbor创建项目:新建个test项目配置内容信任,阻止没有签名的镜像下载

第三节:了解容器的安全机制与缺陷

#未开启DCT时推送镜像docker push data01.com/test/mybox:1.0.0

此时在Harbor中看见镜像是未签名状态

第三节:了解容器的安全机制与缺陷

(2)镜像推送

#Docker 开启DCT(即开始镜像签名功能)export DOCKER_CONTENT_TRUST=1export DOCKER_CONTENT_TRUST_SERVER=https://data01.com:4443

DOCKER_CONTENT_TRUST=1:表示开启Docker内容信任模式
DOCKER_CONTENT_TRUST_SERVER:指定认证服务器,其实就是对应harbor notary服务的地址和端口
如果Harbor使用自签名证书,则需要将对应的ca证书放置到 docker所在主机的~/.docker/tls/data01.com:4443/目录,证书名为ca.crt。
data01.com:4443为你的notary节点域名(ip)和端口

原理就是使用目录下ca证书进行镜像的签发密钥和验证(当然也可以根据ca证书再给data01.com:4443签发一张二级证书)。

#继续推送镜像[root@data01 ~]# docker push data01.com/test/nginx:1.14.2The push refers to repository [data01.com/test/busybox]432b65032b94: Pushed 1.14.2: digest: sha256:74f634b1bc1bd74535d5209589734efbd44a25f4e2dc96d78784576a3eb5b335 size: 527Signing and pushing trust metadataEnter passphrase for root key with ID 0e17f94: Enter passphrase for new repository key with ID 027f454: Repeat passphrase for new repository key with ID 027f454: Finished initializing "data01.com/test/nginx"Successfully signed data01.com/test/nginx:1.14.2

    输入密码对镜像进行签名,后续镜像上传都是使用此密码进行镜像签署。
root key:在 ~/.docker/trust 目录中生成一个根密钥
repository key:在 ~/.docker/trust 目录中生成一个镜像签署密钥

推送成功后查看

第三节:了解容器的安全机制与缺陷

#查看镜像签名docker trust inspect data01.com/test/nginx:1.14.2
[root@data01 private]# docker trust inspect data01.com/test/nginx:1.14.2[    {        "Name": "data01.com/test/nginx:1.14.2",        "SignedTags": [            {                "SignedTag": "1.14.2",                "Digest": "706446e9c6667c0880d5da3f39c09a6c7d2114f5a5d6b74a2fafd24ae30d2078",                "Signers": [                    "Repo Admin"]            }        ],        "Signers": [],        "AdminstrativeKeys": [            {                "Name": "Root",                "Keys": [                    {                        "ID": "03fef8621852c225d1067b3dc85ff367725e895124f83bd62255c24e4c16e5d6"                    }                ]            },            {                "Name": "Repository",                "Keys": [                    {                        "ID": "035e330d979bddb427f6f06f4a951102bd762d1cfc082eed417e5b51695636e2"                    }                ]            }        ]    }]

(3)镜像拉取

如果节点docker开启了DCT,则执行如下:

export DOCKER_CONTENT_TRUST=1export DOCKER_CONTENT_TRUST_SERVER=https://data01.com:4443

拉取镜像需要进行证书签名比对,若harbor使用的是自签名证书,此时需要节点~/.docker/tls/上放置了CA证书。若节点没有配置docker内容信任,则拉取镜像时不需要做签名验证(也不用在~/.docker/tls/目录放证书)。

注意:当开启DCT后(即 DOCKER_CONTENT_TRUST=1),DOCKER_CONTENT_TRUST_SERVER的值配的前面的registory(data01.com)和 拉取镜像时的registory 不对应的时候会报一个错,例如当DOCKER_CONTENT_TRUST_SERVER为如上配置时,执行docker pull data06.com/test/nginx:1.14.2 时就会报这个错

docker: Error: error contacting notary server: received unexpected HTTP status: 500 Internal Server Error.
如果~/.docker/tls/ 证书没配置,则会报如下错误:
Error: error contacting notary server: x509: certificate signed by unknown authority

C.Namespace隔离技术

Linux内核提供了多种命名空间如Mount Namespace、Network Namespace等,Docker利用这些特性实现了容器间资源的逻辑隔离,使得每个容器如同运行在一个独立的环境中,避免容器之间互相干扰。

  • pid namespace:每个容器拥有独立的进程ID空间。

  • network namespace:每个容器有自己的网络栈,拥有独立的IP地址、端口等资源。

  • mount namespace:每个容器有独立的挂载点视图,可以限制容器对主机文件系统的访问。

  • ipc namespace:提供独立的进程间通信资源如信号量、消息队列和共享内存。

  • uts namespace:提供独立的主机名和域名。

  • user namespace:允许容器内部使用不同的用户和组ID映射。

从而达到如下效果,在分布式的环境下进行通信和定位,创造容器必需的独立的 IP、端口、路由等等;使用独立的主机名在网络中标识自己;进程间通信的隔离;对用户和用户组的隔离就实现了用户权限的隔离;运行在容器中的应用有肚子的 PID, 并与宿主机中的 PID 进行隔离。

D.Cgroup资源限制

    通过Linux Control Groups (Cgroups),Docker可以精确地控制容器能够使用的CPU、内存、磁盘I/O以及网络带宽等系统资源,从而防止资源滥用和DoS攻击。

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

第三节:了解容器的安全机制与缺陷

(1)CPU限额:在资源目录中修改

[root@server1 cpu]# pwd/sys/fs/cgroup/cpu[root@server1 cpu]# dd if=/dev/zero of=/dev/null &    ##此时,对CPU的利用率高达99.9%[1] 1333[root@server1 cpu]# cat cpu.shares    ##在cpu.shares文件中,可以对进程调度程序所处理的进程组设置CPU时间分配的比重。通过修改这个值,就可以在分组间调整CPU时间的比例。默认值为10241024[root@server1 cpu]# cat cpu.cfs_quota_us   ##cpu使用率的配额-1[root@server1 cpu]# mkdir x1    ##在系统cpu资源目录下建立目录x1,在该目录下进行资源限制[root@server1 cpu]# cd x1[root@server1 x1]# echo 20000 > cpu.cfs_quota_us    ##限制最大cpu使用率为20%[root@server1 x1]# echo 1333 > tasks[root@server1 x1]# top    ##查看1333进程的具体使用情况

    运行容器时制定资源限制参数

[root@server1 x1]# docker run -it --name vm1 --cpu-quota 20000 ubunturoot@e41f67c8b795:/# dd if=/dev/zero of=/dev/null &    ##此时,通过限额,cpu使用率最大只能是20%

(2) 对内存限制:在资源目录中修改

echo  314572800 > memory.limit_in_bytes   ##限制使用的最大值

(3)通过cgroup文件限制用户的资源使用

[root@server1 ~]# useradd ly[root@server1 ~]# vim /etc/cgrules.conf [root@server1 ~]# cat /etc/cgrules.conf # /etc/cgrules.conf#The format of this file is described in cgrules.conf(5)#manual page.## Example:#<user>    <controllers>  <destination>#@student  cpu,memory  usergroup/student/#peter    cpu    test1/#%    memory    test2/# End of filely       memory     x2[root@server1 x2]# systemctl start cgred[root@server1 x2]# su - ly[ly@server1 ~]$ cd /dev/shm[ly@server1 shm]$ dd if=/dev/zero of=file bs=1M count=400    ##限制成功!!Killed[ly@server1 shm]$ free -m              total        used        free      shared  buff/cache   availableMem:           1999         237         955         307         807        1291Swap:          2047           0        2047

(4)按每秒写入块设备的数据量设定上限

[root@server1 ~]# docker run -it --name vm3 --device-write-bps /dev/sda:10MB ubunturoot@9a8075c8d628:/# dd if=/dev/zero of=file bs=1M count=100 oflag=direct   # direct 模式就是把写入请求直接封装成io 指令发到磁盘# 非direct 模式,就把数据写入系统缓存,然后就认为io 成功,并由操作系统决定缓存中的数据什么时候被写入磁盘100+0 records in100+0 records out104857600 bytes (105 MB) copied, 9.95226 s, 10.5 MB/s

E.安全配置与权限控制

(1)SELinux/APPArmor策略

提供额外的强制访问控制机制,可以细粒度地控制容器进程的权限。

启用 AppArmor

AppArmor 主要的作用是设置某个可执行程序的访问控制权限,可以限制程序 读/写某个目录/文件,打开/读/写网络端口等等。

Apparmor 的配置文件保存在/etc/apparmor.d/containers/目录下

配置文件使用官方文档下的 Nginx 配置实例,见https://docs.docker.com/engine/security/apparmor/

加载一个新的配置文件:

$ sudo apparmor_parser -r -W /etc/apparmor.d/containers/docker-nginx

上传新的配置文件:

$ apparmor_parser -R /path/to/profile

在 Docker 里使用 AppArmor:

$ docker run --security-opt "apparmor=docker-nginx" -p 80:80 -d --name apparmor-nginx nginx

启用 SELinux

宿主机上启用 SELinux,Docker 守护进程启用 SELinux,默认启动容器就开启了 SELinux

[root@localhost selinux]# sestatusSELinux status: enabledSELinuxfs mount: /sys/fs/selinuxSELinux root directory: /etc/selinuxLoaded policy name: targetedCurrent mode: enforcingMode from config file: enforcingPolicy MLS status: enabledPolicy deny_unknown status: allowedMax kernel policy version: 31[root@localhost selinux]# docker info...init version: fec3683Security Options:seccompWARNING: You're not using the default seccomp profileProfile: /etc/docker/seccomp/default-no-chmod.jsonselinuxusernsKernel Version: 3.10.0-1062.12.1.el7.x86_64...

测试,挂载宿主机/目录到容器的/hacking目录

[root@localhost selinux]# docker run -it --rm -v /:/hacking centos:latest /bin/shsha256:fe8d824220415eed5477b63addf40fb06c3b049404242b31982106ac204f6700Status: Downloaded newer image for centos:latestsh-4.4# cd /sh-4.4# lsbin dev etc hacking home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr varsh-4.4# cd hacking/sh-4.4# lsbin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr varsh-4.4# cd var/logsh-4.4# lsls: cannot open directory '.': Permission denied

运行参数可以选择 SELinux 的级别,标签包含 4 个部分User:Role:Type:level,可以设置 SELinux 不同的标签设定运行级别。

docker run --security-opt label=type:spc_t replicateddocker run --interactive --tty --security-opt label=level:TopSecret centos /bin/basdocker run -it --security-opt label:disable alpine sh

(2)能力(Capabilities)管理:容器通常不需要完整的root权限,而是仅需要一部分必要的系统调用能力,通过设置合理的权限分配,降低潜在风险。   

    Linux内核中的Capabilities特性用于划分特权集,以便进程可以只分配“执行特定功能”的特权。

    在引入此特性前,如果进程需要使用网络,则必须使用root来运行,通常是sudo或者添加suid,那么普通用户在使用ping时,ping就可以运行任何特权。引入Capabilities特性后,可以通过给ping应用添加CAP_NET_RAW特权集,使其具有使用网络的特权集,而不具备其他特权集。缺省ping具有cap_net_admin和cap_net_raw特权集

# getcap /bin/ping/bin/ping = cap_net_admin,cap_net_raw+p

    在 Linux 中的 Capabilities 是通过 extended attributes 中security 命名空间实现的,selinux也是一样

# getfattr -d -m "^security\." /bin/pinggetfattr: Removing leading '/' from absolute path names# file: bin/pingsecurity.capability=0sAAAAAgAgAAAAAAAAAAAAAAAAAAA=security.selinux="system_u:object_r:ping_exec_t:s0"

可以通过查看进程/proc/xxxx/status,来检查进程的特权集,并通过capsh来解码得到具体的特权集。

# ps -ef | grep dockerd | grep -v greproot       1159      1  1 May26 ?        01:02:41 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock# cat /proc/1159/status | grep CapCapInh: 0000000000000000    #可以继承的CAP(i)CapPrm: 0000003fffffffff    #可以使用的CAP(p)CapEff: 0000003fffffffff    #使用的CAP(e)CapBnd: 0000003fffffffff    #进程特有CapAmb: 0000000000000000    #进程特有

使用capsh可以翻译出每个BIT的含义,3=0011表示2个bit,f=1111表示4个bit,一共2+4+4+4+4+4+4+4+4+4=38bit,从后先前,每个bit代表一种特权,一共38种特权集.

# capsh --decode=0000003fffffffff0x0000003fffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read

Docker中的Capabilities

Docker 也支持 Capabilities ,在运行容器的时候可以通过指定 --privileded 参数来开启容器的所有CAP,可以通过--cap-add 和 --cap-drop 这两个参数来调整.
    后台运行一个容器busybox,通过查看进程,可以发现缺省容器只有14种特权集

第三节:了解容器的安全机制与缺陷

# docker run --name test1 -td busybox  /bin/httpd -f# ps -ef | grep httpd | grep -v greproot      49478  49462  1 02:27 pts/0    00:00:00 /bin/httpd -f# cat /proc/49478/status | grep CapCapInh: 00000000a80425fbCapPrm: 00000000a80425fbCapEff: 00000000a80425fbCapBnd: 00000000a80425fbCapAmb: 0000000000000000#capsh --decode=00000000a80425fb0x00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap

由于容器缺省不支持cap_sys_nice,所以无法改变nice值

# docker exec -it test1 /bin/sh/ # renice -n -9 1renice: setpriority: Permission denied

通过--cap-add给容器增加cap_sys_nice特权集

# docker run  --name test2 -td --cap-add=cap_sys_nice  busybox  /bin/httpd -f# docker exec -it  test2  /bin/sh/ # renice -n -9 -p 1/ #在宿主机上查看nice值,发现已经修改为-9,test1的nice值还是0#  ps -eo "%p %c %n"  | grep httpd 16371 httpd             0 21056 httpd            -9

使用--privileged可以获得所有特权集

#docker run  --name test3 -td --privileged  busybox  /bin/httpd -f5b277e886f498451bae505091a05ad1d09455dd2b4824c16953e08e9bd9bb526# ps -ef | grep httpd | grep -v greproot      49032  49015  0 03:32 pts/0    00:00:00 /bin/httpd -f# cat /proc/49032/status | grep -i capCapInh: 0000003fffffffffCapPrm: 0000003fffffffffCapEff: 0000003fffffffffCapBnd: 0000003fffffffffCapAmb: 0000000000000000# docker kill test3# docker container prune

使用--cap-add=ALL也可以获得所有特权集

# docker run  --name test3 -td --cap-add=ALL  busybox  /bin/httpd -f# ps -ef | grep httpd | grep -v greproot      30041  30012  0 03:23 pts/0    00:00:00 /bin/httpd -f# cat /proc/30041/status | grep -i capCapInh: 0000003fffffffffCapPrm: 0000003fffffffffCapEff: 0000003fffffffffCapBnd: 0000003fffffffffCapAmb: 0000000000000000# docker kill test3# docker container prune

如果使用--cap-drop=ALL --cap-add=cap_net_bind_service,则只有cap_net_bind_service 特权集.--cap-drop和--cap-add是在基础的14重特权集的基础上先减后加的

# docker run  --name test3 -td --cap-drop=ALL --cap-add=cap_net_bind_service busybox  /bin/httpd -f5c033ee08b2fbb1fe1c6cf9a3d636f602959647f0bed29dbec111eb0cff6fe05# ps -ef | grep httpd | grep -v greproot      43727  43709  3 03:29 pts/0    00:00:00 /bin/httpd -f# cat /proc/43727/status | grep CapCapInh: 0000000000000400CapPrm: 0000000000000400CapEff: 0000000000000400CapBnd: 0000000000000400CapAmb: 0000000000000000 docker kill test3 docker container prune

Kubernetes中的Capabilities

在k8s中使用Capabilities,与container基本一致

apiVersion: apps/v1kind: Deploymentmetadata:  labels:    run: test1  name: test1  namespace: defaultspec:  selector:    matchLabels:      run: test1  template:    metadata:      creationTimestamp: null      labels:        run: test1    spec:      containers:      - args:        - /bin/httpd        - -f        image: busybox:latest        imagePullPolicy: IfNotPresent        name: test1        securityContext:          capabilities:            add:            - cap_net_bind_service            drop:            - all

F.Seccomp安全策略

Docker可以通过Seccomp(Secure Computing Mode)为容器设置一个白名单,仅允许执行特定的系统调用,进一步增强了容器内部的安全性。

Secommp (SECure COMPuting) 是 Linux 内核 2.6.12 版本引入的安全模块,主要是用来限制某一进程可用的系统调用 (system call)。它最初被用于 cpushare 这个项目,让人们可以出租自己空闲的 cpu cycle 来执行 untrusted code。这个 feature 本身并不是一个沙盒 (sandbox),它只是一种减少 Linux 内核暴露的机制,是构建一个安全的沙盒的重要组成部分。

Seccomp Strict Mode

Seccomp 在最初引入的时候只支持了 strict mode,意味着只有 read ,write ,_exit ,_sigreturn 四个 system call 会被允许。一旦出现其他的 system call,进程会被立刻终止 (SIGKILL)。一个简单的例子如下:

#include <stdio.h>#include <sys/prctl.h>#include <sys/socket.h>#include <linux/seccomp.h>int main(int argc, char* argv[]) {  printf("Install seccompn");  prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);  printf("Creating socketn");  int sock = socket(AF_INET, SOCK_STREAM, 0);  return 0;}

编译并执行,结果如下:

$ g++82 -o seccomp seccomp.c$ ./seccomp Install seccompCreating socketKilled$ echo $?137

上面的程序在 seccomp 被启动之后有两个系统调用:write 和 socket ,printf 这个函数本质上向 stdout 写了一些 bytes,是被允许的。然而当进程想要创建 socket 的时候,程序就被终止了。我们通过 strace 也能得到相同的结论,附上 strace 的结果:

...write(1, "Install seccompn", 16Install seccomp)       = 16prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT) = 0write(1, "Creating socketn", 16Creating socket)       = 16socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = ?+++ killed by SIGKILL +++

Seccomp Filter Mode (Seccomp-BPF)

strict mode 固然很棒,然而实用性却不高。因为一个复杂的程序根本不可能只用到四个 system call。strict mode 下进程能够完成的任务非常的有限。于是 Linux 又引入了 filter mode,也就是 BPF ( Berkley Packet Filter)。BPF 提供了更高的灵活度,赋予了开发者对于程序更细颗粒度的控制。

Linux 内核实现了一个能够执行 BPF 程序的虚拟机。对于每一次 system call,内核都会执行一遍开发者提供的 BPF 程序,用来确定是否需要过滤 system call。BPF 程序在 c 中表示为一个长度固定的指令数组,定义如下:

struct sock_fprog {    unsigned short      len;    /* Number of BPF instructions */    struct sock_filter *filter; /* Pointer to array of BPF instructions */};

内核的虚拟机会按顺序读取 BPF 指令 ( sock_filter ) ,读取完之后会解码 (decode) 指令并执行指令。指令的定义如下:

struct sock_filter {            /* Filter block */    __u16 code;                 /* Actual filter code */    __u8  jt;                   /* Jump true */    __u8  jf;                   /* Jump false */    __u32 k;                    /* Generic multiuse field */};

结合以上所有,我们来看一个具体的例子:

void configure_seccomp() {  struct sock_filter filter [] = {    ...     BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL)  };  struct sock_fprog prog = {       .len = (unsigned short)(sizeof(filter) / sizeof (filter[0])),       .filter = filter,  };  prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);  prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);}

我们之前说过,BPF 代码在 C 中表示成一个指令数组。这个例子只出现了最后一条指令:返回杀死进程,其他的都被省略了。在实际应用中,BPF 代码会更加复杂。

有一点值得注意的是我们一般会设置PR_SET_NO_NEW_PRIVS这个 bit,主要是为了防止 untrusted code 篡改已有 BPF 程序,进而导致安全隐患。

Kafel

如果你是一个硬核的程序员,当让可以直接手写 BPF 代码过滤 system call。然而对于大多数 程序员而言,这个过程可能并不轻松,稍有不慎就会引入 bug,导致一些 system call 没有被blacklist 掉。幸好,开源项目 Kafel 提供了解决方案。

Kafel 规定了一种更便于人理解的 policy file,并且提供了编译器,能把 policy file 编译成 BPF 代码。我这里直接放一个 policy file,不用我多解释,相信大家也能把这个文件的意思猜的差不多了:

#define CLONE_THREAD  0x00010000POLICY foo {  ALLOW {    brk,    clone { clone_flags & CLONE_THREAD != 0 },    exit,    exit_group,    futex,    mmap,    mprotect,    read,    write   }}USE foo DEFAULT ERRNO(1)

这个 policy 文件比较有意思的地方就clone 的规则,它规定了只允许 argument 中 CLONE_THREAD的 bit 是被开启的。这个 policy 这样设置也很好理解:fork()和 start a new thread 其实都需要用到 clone 这个 system call,只不过 argument 不同。很多时候我们任然希望被 sandbox 的进程能够多线程处理,但是我们却不希望进程 fork 出一个子进程。

通过 kafel 生成 bpf 代码:

$ dump_policy_bpf -c seccomp.policy BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, arch)),BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0xc000003eu, 1, 0),BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x39u, 0, 6),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0xcau, 0, 3),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0xe7u, 0, 1),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0xe8u, 11, 12),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0xcbu, 10, 11),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x3cu, 0, 9),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x3du, 8, 9),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0xbu, 0, 5),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0xdu, 0, 3),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x38u, 0, 5),BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, args[0])),BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, 0x10000u, 4, 3),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0xcu, 3, 2),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x2u, 0, 2),BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x9u, 1, 0),BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | 0x1u),BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),

把生成的 bpf 代码放到应用程序中:

#include <sys/prctl.h>#include <sys/socket.h>#include <linux/filter.h>#include <linux/seccomp.h>#include <thread>#include <unistd.h>#include <stdio.h>void configure_seccomp() {  struct sock_filter filter [] = {    /** 之前生成的bpf代码 此处省略了 */  };  struct sock_fprog prog = {       .len = sizeof(filter) / sizeof (filter[0]),       .filter = filter,  };  printf("Configuring seccompn");  prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);  prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);}int main(int argc, char* argv[]) {  configure_seccomp();  std::thread t([]()->void { printf("Hello from threadn");});  t.join();  pid_t ret = fork();  printf("Return code from fork %d, errno: %dn", ret, errno);  return 0;}

编译并执行:

$ g++82 -o seccomp seccomp.c -pthread$ ./seccomp Configuring seccompHello from threadReturn code from fork -1, errno: 1

从上面的例子可以看出:程序可以多线程计算,但是却不能 fork 一个子进程。fork 返回 -1 ,并且把errno 设置成了 1 ,因为在 policy 中我们规定了当 system call violation 的时候会返回EPERM 。

综合运用以上措施以及其他相关的安全最佳实践(如最小权限原则、定期更新及漏洞扫描等),Docker为用户提供了一个更加安全的应用运行平台,能够在大规模部署和复杂的云环境中有效降低安全风险。同时,持续关注并遵循官方的安全指导以及行业标准,对于维护和提升Docker的安全水平至关重要。

02
容器安全机制之K8S安全机制
第三节:了解容器的安全机制与缺陷

Kubernetes(简称K8s)作为一个强大的容器编排平台,其容器安全机制涵盖了多个层面,从API服务器的访问控制到运行时容器的安全措施都有详尽的设计和实现。以下是对Kubernetes容器安全机制的主要组成部分概述:

A.认证(Authentication)

(1)Kubernetes API Server 支持多种认证方式,包括客户端证书、bearer tokens(如JWT或服务账户令牌)、HTTP基本认证、OAuth2等。

k8s 中的认证机制,是在用户访问 APIServer 的第一步。通常是一个完整的 HTTP 请求打过来,但是这一步往往只检测请求头或客户端证书。

认证机制目前有客户端证书、bearer tokens、authenticating proxy、HTTP basic auth 这几种模式。使用方式通常有以下几种:

      • X509 Client Certs: 客户端证书模式需要在 kubectl 命令中加入 --client-ca-file=<SOMEFILE> 参数,指明证书所在位置。

      • Static Token File: --token-auth-file=<SOMEFILE> 参数指明 bearer tokens 所在位置。

      • bearer tokens: 在 HTTP 请求头中加入 Authorization:Bearer<TOKEN>。

      • Bootstrap Tokens: 与 bearer tokens 一致,但 TOKEN 格式为 [a-z0-9]{6}.[a-z0-9]{16}。该方式称为 dynamically-managed Bearer token,以 secret 的方式保存在 kube-systemnamespace 中,可以被动态的创建和管理。同时,启用这种方式还需要在 APIServer 中打开 --enable-bootstrap-token-auth ,这种方式还处于 alpha 阶段。

      • Static Password File: 以参数 --basic-auth-file=<SOMEFILE> 指明 basic auth file 的位置。这个 basic auth file 以 csv 文件的形式存在,里面至少包含三个信息:password、username、user id,同时该模式在使用时需要在请求头中加入 Authorization:BasicBASE64ENCODED(USER:PASSWORD) 。

(2)对于Pod内部的服务账户,Kubernetes会自动创建并挂载相应的ServiceAccount以及相应的Token文件,在 PodSpec 中指明 ServiceAccount 来访问 ApiServer。确保Pod与集群内部组件通信时的身份验证。

B.授权(Authorization)

(1)Kubernetes采用了Role-Based Access Control (RBAC),提供了精细的角色管理和权限分配能力。

Role-based access control (RBAC) 是基于角色的权限访问控制,通常是对于“内置用户”而言的。该模式是在 k8s v1.6 开发出来的。若要开启该模式,需要在 APIServer 启动时,设置参数 --authorization-mode=RBAC。

RBAC 所使用的 API Group 是 rbac.authorization.k8s.io/v1beta1,直到 Kubernetes v1.8 后,RBAC 模块达到稳定水平,所使用的 API Group 为 rbac.authorization.k8s.io/v1。

所谓基于角色的权限访问控制,就是对某个用户赋予某个角色,而这个角色通常决定了对哪些资源拥有怎样的权限。

(2)用户可以定义Role、ClusterRole来指定允许执行的操作集合,并通过RoleBinding、ClusterRoleBinding将这些角色绑定到用户或者ServiceAccount上,实现对集群资源的细粒度访问控制。

C.准入控制(Admission Controllers)

准入控制器是对接收到的请求在被API Server实际处理前进行额外检查和修改的插件,它们可以在创建、更新或删除对象时执行操作,比如:

  • NamespaceLifecycle 确保命名空间生命周期符合预期规则

    • NodeRestriction 限制kubelet只能管理特定节点资源

    • PodSecurityPolicy(已废弃但有替代方案Pod Security Admission)用于定义安全策略以限制哪些类型的Pod可以在集群中运行

    • ValidatingAdmissionWebhook 和 MutatingAdmissionWebhook 允许自定义准入控制逻辑

D.网络安全(Network Policies)

Kubernetes支持NetworkPolicy资源,使得管理员能够定义 Pod间的网络通信规则,例如哪些Pod可以互相访问、哪些端口开放给外部等,以增强集群内的网络隔离性。

E.容器运行时安全性(Container Runtime Security)

Kubelet调用容器运行时(如Docker、containerd或CRI-O)时,会对容器进行安全配置,包括但不限于:

  • 使用Seccomp Profile来限制容器中的系统调用行为。

  • 应用AppArmor或SELinux安全策略来实施强制访问控制(Mandatory Access Control, MAC)。

  • 设置cgroups约束,限制容器使用的CPU、内存、磁盘I/O等系统资源。

F.镜像安全(Image Security)

(1)通过集成镜像扫描工具,Kubernetes可以帮助检测镜像中存在的漏洞,避免使用含有安全隐患的镜像部署应用。

(2)鼓励使用签名镜像和信任的内容分发机制。

G.秘密管理(Secret Management)

Kubernetes提供Secret对象类型,用于存储敏感信息,如密码、密钥等,并可以通过Volume Mount的方式安全地向Pod内注入这些敏感数据。

03
Docker安全缺陷与挑战
第三节:了解容器的安全机制与缺陷

    Docker作为一种广泛使用的容器化技术,虽然为应用程序的快速部署、隔离和规模化管理提供了极大便利,但也存在一些安全缺陷和挑战:

A. 宿主机攻击面

如果恶意用户能够获得对一个容器的控制权,他们可能利用容器逃逸漏洞来攻击宿主机操作系统,尤其是当容器以root权限运行且配置不当时。

B. 镜像安全性

(1)Docker镜像可能存在已知的安全漏洞。如果构建或维护过程不严谨,可能导致包含过时软件包或带有漏洞的应用程序。

(2)非官方来源的镜像可能会含有恶意代码,使用前未经充分验证可能导致风险。

C. 网络隔离不足

默认情况下,Docker容器之间的网络隔离并不如虚拟机那样严格,这意味着在默认设置下,如果网络策略不当,容器间可能存在潜在的安全威胁。

D. 权限和访问控制

权限管理和访问控制是Docker的一个重要安全考量点。例如,需要合理分配容器的能力(capabilities)和SELinux/AppArmor安全上下文,避免过度授权。

E. 安全更新与补丁管理

由于Docker容器往往基于基础镜像构建,更新底层系统的安全补丁通常涉及到重新构建并替换所有依赖此基础镜像的容器。

F. API和远程访问

Docker守护进程通过API暴露了大量功能,如果不正确配置或保护,可能会导致未经授权的访问和操作。

G. 内核漏洞

所有Docker容器共享宿主机的内核,任何影响到内核的安全漏洞都可能导致多个容器受到攻击。

H. 容器间的数据泄露

若未妥善处理存储卷和共享文件系统,可能存在数据泄漏的风险。

应对这些安全挑战的措施包括但不限于:

    • 使用最新的Docker版本,并及时应用安全更新和补丁。

    • 合理设计容器安全策略,如限制容器使用必要的最小权限集。

    • 对镜像进行安全扫描,确保没有已知漏洞。

    • 实施严格的网络策略,如使用Network Policies或其他网络安全工具。

    • 使用安全配置管理工具和最佳实践,比如利用Kubernetes Pod Security Policy或者替代方案来限制不安全的Pod配置。

    • 监控容器行为,通过日志审计和入侵检测系统来发现异常活动。

04
K8S安全缺陷与挑战
第三节:了解容器的安全机制与缺陷

    Kubernetes(简称K8s)在提供灵活的容器编排和管理的同时,由于其复杂的架构和广泛的组件交互,也面临一系列显著的安全挑战。以下是几个关键的安全缺陷与应对策略:

A. API服务器安全
挑战:API服务器是Kubernetes的核心组件,如果不加以妥善保护,可能成为攻击者的主要入口点。默认设置可能允许过多权限访问。
    应对措施:实施严格的认证和授权机制,如RBAC(基于角色的访问控制)、服务账户限制、网络策略以及启用TLS加密通信。
B. Pod安全
 挑战:未经过充分安全配置的Pod可能会受到恶意利用,比如运行特权容器、拥有不当权限或暴露不必要的端口。
    应对措施:使用Pod Security Policies (PSP) 的替代方案,例如PodSecurity Admission控制器,以确保Pod遵从安全策略;避免非必要的特权模式运行容器;合理配置网络策略。
C. Secrets管理
挑战:存储敏感信息如密码、密钥等,存在泄露风险。
    应对措施:充分利用Kubernetes Secrets功能进行加密存储和传递;考虑采用外部秘密管理解决方案如HashiCorp Vault进一步加强安全防护。
D. 网络隔离
挑战:默认的网络模型可能不足以满足某些情况下的安全隔离需求,Pod间的网络通信可能存在漏洞。
    应对措施:实现NetworkPolicy以精细控制不同命名空间间或者Pod间的网络流量;利用网络安全插件来增强网络层安全性。
E. 供应链安全
  挑战:容器镜像及其中包含的依赖包可能含有漏洞,形成供应链安全问题。
    应对措施:实行安全的CI/CD流程,包括只拉取可信仓库的镜像,定期扫描镜像漏洞,并保持软件栈更新。
F. 容器逃逸
挑战:即使容器提供了轻量级隔离,仍有可能通过漏洞逃逸至宿主机或其他容器内。
    应对措施:及时应用操作系统和容器运行时的安全补丁;对容器运行环境进行细粒度的资源限制;利用seccomp、AppArmor或 SELinux 等技术增强容器安全边界。
G. 日志审计与监控
挑战:缺乏有效的日志记录和审计可能导致安全事件无法被及时发现和响应。
    应对措施:集成集中式日志系统,实时监控集群行为并设定警报规则;执行详细的审计跟踪以便于事后分析。

综上所述,确保Kubernetes环境的安全需要全方位的策略和工具,包括但不限于强化认证授权、制定细致的Pod安全策略、严谨管理敏感数据、完善网络隔离、加强供应链安全管理、防范容器逃逸以及健全的日志审计体系。随着新的威胁不断出现,持续关注社区的最佳实践和新特性至关重要。

    不知不觉容器安全的基本原理和“套话”都已经说完了,接下来我们将根据阿里云的云上容器ATT&CK攻防矩阵,进行体系化研究,请继续关注!

福利来啦!!!

 福利一:为感恩回馈购买东方隐侠知识大陆的老客户,我们送出年终抽奖活动,请前往东方隐侠知识大陆参加抽奖。友情提醒:非客户,不兑奖的哈~

    详情请查看链接:https://wiki.freebuf.com/societyDetail/articleDetail?society_id=44&article_id=44358

 福利二:东方隐侠在参加知识大陆官方年终活动,敬请参加:

    第三节:了解容器的安全机制与缺陷

    END
    第三节:了解容器的安全机制与缺陷
    关注东方隐侠
    让安全界刮起侠客风

    第三节:了解容器的安全机制与缺陷

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月1日22:42:12
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   第三节:了解容器的安全机制与缺陷https://cn-sec.com/archives/2401037.html

发表评论

匿名网友 填写信息