(can be solved in any kubectl context)

The Release Engineering Team has shared some YAML manifests and Dockerfiles with you to review. The files are located under /opt/course/22/files.

As a container security expert, you are asked to perform a manual static analysis and find out possible security issues with respect to unwanted credential exposure. Running processes as root is of no concern in this task.

Write the filenames which have issues into /opt/course/22/security-issues.

NOTE: In the Dockerfile and YAML manifests, assume that the referred files, folders, secrets and volume mounts are present. Disregard syntax or logic errors.


译文:

(可以在任何kubectl环境下解决)

发布工程团队已经分享了一些YAML清单和Dockerfiles,供你查阅。这些文件位于/opt/course/22/files下。

作为一名容器安全专家,你被要求进行手动静态分析,并找出可能存在的与不需要的凭证暴露有关的安全问题。在这项任务中,以root身份运行进程是不需要担心的。

把有问题的文件名写进/opt/course/22/security-issues

注意:在Dockerfile和YAML清单中,假设所指的文件、文件夹、机密和卷挂载都存在。不考虑语法或逻辑错误。


参考

https://docs.docker.com/develop/develop-images/dockerfile_best-practices

https://kubernetes.io/docs/concepts/configuration/overview

解答

查看文件, 供三个dockerfile 7个 k8s yaml

ls -la /opt/course/22/files

file

1 Dockerfile-mysql

Dockerfile-mysql文件在第一眼看上去可能是无辜的。它复制了一个文件的秘密令牌,使用它并在之后将其删除。但由于Docker的工作方式,每一个RUN、COPY和ADD命令都会创建一个新的层,并且每一个层都会在镜像中被持久化。

这意味着即使文件密令在Z层被删除,它仍然包括在X层和Y层的镜像中。在这种情况下,最好使用示例变量递给Docker。

# /opt/course/22/files/Dockerfile-mysql
FROM ubuntu

# Add MySQL configuration
COPY my.cnf /etc/mysql/conf.d/my.cnf
COPY mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf

RUN apt-get update && \
    apt-get -yq install mysql-server-5.6 &&

# Add MySQL scripts
COPY import_sql.sh /import_sql.sh
COPY run.sh /run.sh

# Configure credentials
COPY secret-token .                                       # LAYER X
RUN /etc/register.sh ./secret-token                       # LAYER Y
RUN rm ./secret-token # delete secret token again         # LATER Z

EXPOSE 3306
CMD ["/run.sh"]

存在问题,所以写文件名到 文件

echo Dockerfile-mysql >> /opt/course/22/security-issues
2 deployment-redis.yaml

文件 deployment-redis.yaml 正在从一个名为mysecretSecret中获取证书,并将这些证书写入 环境变量 中。到目前为止还不错,但在容器的命令中,这些日志可以被任何有访问权限的用户直接读取。

# /opt/course/22/files/deployment-redis.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: mycontainer
        image: redis
        command: ["/bin/sh"]
        args:
        - "-c"
        - "echo $SECRET_USERNAME && echo $SECRET_PASSWORD && docker-entrypoint.sh" # NOT GOOD
        env:
        - name: SECRET_USERNAME
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: username
        - name: SECRET_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: password

日志中记录凭证是不对的

echo deployment-redis.yaml >> /opt/course/22/security-issues
3 statefulset-nginx.yaml

密码直接暴露在容器的环境变量定义中。

# /opt/course/22/files/statefulset-nginx.yaml
...
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        env:
        - name: Username
          value: Administrator
        - name: Password
          value: MyDiReCtP@sSw0rd               # NOT GOOD
        ports:
        - containerPort: 80
          name: web
echo statefulset-nginx.yaml >> /opt/course/22/security-issues
# /opt/course/22/security-issues
Dockerfile-mysql
deployment-redis.yaml
statefulset-nginx.yaml