kubestronautへの道 ~CKS編 その28 killer coda「Static Manual Analysis K8s」~

tech article

今日覚えて帰ること

securityContext

マニフェストファイルのセキュリティが気になるときはsecurityContextをチェックする

Static Manual Analysis K8s

Analyse K8s Pod YAML

Perform a manual static analysis on files /root/apps/app1-* considering security.

Move the less secure file to /root/insecure

前回と同じですね。
2つあるファイルのうち、セキュリティの観点から優れているファイルを選択していきます。
前回はDockerfileでしたが、今回はマニフェストファイルです。

それでは早速見ていきましょう。

controlplane $ cd /root/apps/
controlplane $ ll
total 32
drwxr-xr-x  2 root root 4096 Sep 16 11:55 ./
drwx------ 14 root root 4096 Sep 16 11:55 ../
-rwxr-xr-x  1 root root  243 Sep 16 11:55 app1-30b5eba5.yaml*
-rwxr-xr-x  1 root root  275 Sep 16 11:55 app1-510d6362.yaml*
-rwxr-xr-x  1 root root  547 Sep 16 11:55 app2-b917e60e.yaml*
-rwxr-xr-x  1 root root  416 Sep 16 11:55 app2-f720cbb4.yaml*
-rwxr-xr-x  1 root root 1483 Sep 16 11:55 app3-819f4686.yaml*
-rwxr-xr-x  1 root root 1296 Sep 16 11:55 app3-905fe637.yaml*
controlplane $ 

controlplane $ cat app1-30b5eba5.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod
spec:
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      readOnlyRootFilesystem: true
  dnsPolicy: ClusterFirst
  restartPolicy: Alwayscontrolplane $ 
controlplane $ 

controlplane $ cat app1-510d6362.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod
spec:
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "999999"]
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5
controlplane $ 

フェイクでlivenessProbeがありますが、こちらはpodの可用性にかかわる設定でセキュリティ的には特に意味はありません。

セキュリティ的に優れているのはsecurityContextでreadOnlyRootFilesystemをtrueに設定している
app1-30b5eba5.yamlの方です。

Analyse K8s Deployment YAML

controlplane $ cat app2-b917e60e.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  labels:
    app: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        securityContext:
          capabilities:
            drop: []
          allowPrivilegeEscalation: true
        image: httpd
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 5
          periodSeconds: 5


controlplane $ cat app2-f720cbb4.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:
      securityContext:
        runAsNonRoot: true
        runAsUser: 10001
      containers:
      - name: nginx
        image: nginx:1.21.6
        ports:
        - containerPort: 80
controlplane $ 

allowPrivilegeEscalationがtrueになっているのは流石にセキュリティ的によくないですよね。
securityContextのrunAsNonRootがtrueになっているapp2-f720cbb4.yamlがセキュリティ的に優れています。
簡単ですね。

Analyse K8s StatefulSet YAML

controlplane $ cat app3-905fe637.yaml 
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql-set
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: "mysql"
  replicas: 3
  template:
    metadata:
      labels:
        app: mysql
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: mysql
        image: mysql:5.7
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-store
          mountPath: /var/lib/mysql
        securityContext:
          privileged: false
        env:
          - name: MYSQL_ROOT_PASSWORD
            valueFrom:
              secretKeyRef:
                name: mysql-password
                key: MYSQL_ROOT_PASSWORD
        readinessProbe:
          tcpSocket:
            port: 3306
          initialDelaySeconds: 10
          periodSeconds: 5
        startupProbe:
          tcpSocket:
            port: 3306
          initialDelaySeconds: 10
          periodSeconds: 5
        livenessProbe:
          tcpSocket:
            port: 3306
          initialDelaySeconds: 10
          periodSeconds: 5
  volumeClaimTemplates:
  - metadata:
      name: mysql-store
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "linode-block-storage-retain"
      resources:
        requests:
          storage: 5Gi

controlplane $ cat app3-819f4686.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 3
  minReadySeconds: 10
  template:
    metadata:
      labels:
        app: nginx
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: registry.k8s.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
        readinessProbe:
          httpGet:
            scheme: HTTPS
            path: /index.html
            port: 8443
          initialDelaySeconds: 10
          periodSeconds: 5
        startupProbe:
          httpGet:
            scheme: HTTPS
            path: /index.html
            port: 8443
          initialDelaySeconds: 10
          periodSeconds: 5
        securityContext:
          privileged: true
        livenessProbe:
          httpGet:
            scheme: HTTPS
            path: /index.html
            port: 8443
          initialDelaySeconds: 10
          periodSeconds: 5
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi
controlplane $ 

これも簡単すぎますね。
securityContextのprivilegedがfalseとなっているapp3-905fe637.yamlがセキュリティ的に優れています。

タイトルとURLをコピーしました