❄ RuntimeClass | gVisor
https://kubernetes.io/zh-cn/docs/concepts/containers/runtime-class/
该集群用 containerd 作为 CRI 运行时。
containerd 的默认运行时处理程序是 runc。
containerd 已准备好支持额外的运行时处理程序 runsc(gVisor)
使用名为
runsc
的现有运行时处理程序,创建一个名为untrusted
的 RuntimeClass更新 namespace
server
中的所有 Pod 以在 gVisor 上运行。您可以在/cks/gVisor/rc.yaml
中找到一个模版清单。# /cks/gVisor/rc.yaml apiVersion: node.k8s.io/v1 kind: RuntimeClass metadata:
创建 RuntimeClass
# gvisorRuntimeClass.yml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: untrusted
handler: runsc
kubectl create -f gvisorRuntimeClass.yaml
修改 pod 的 RuntimeClass
kubectl edit pod podname -n server
...
metadata:
namespace: server
spec:
runtimeClassName: untrusted
containers:
- name: foo
image: janedoe/awesomeapp:v1
...
验证
kubectl -n client exec podname -- dmesg | grep gVisor
❄ ServiceAccount
知识点文档:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-service-account
清单文件
/cks/sa/pod1.yaml
中指定的 Pod 由于 ServiceAccount 指定错误而无法调度。
在现有 namespace
qa
中创建一个名为backend-sa
的新 ServiceAccount,确保此 ServiceAccount 不自动挂载 API 凭据。使用
/cks/sa/pod1.yaml
中的清单文件来创建一个Pod。最后,清理 namespace
qa
中任何未使用的 ServiceAccount。# /cks/sa/pod1.yaml apiVersion: v1 kind: Pod metadata: name: backend namespace: qa spec: serviceAccountName: backend-sa containers: - image: nginx:1.9 imagePullPolicy: IfNotPresent name: backend
apiVersion: v1
kind: ServiceAccount
metadata:
name: backend-sa
namespace: qa
automountServiceAccountToken: false #不自动挂载API
---
apiVersion: v1
kind: Pod
metadata:
name: backend
namespace: qa
spec:
serviceAccountName: backend-sa #给pod配置serviceaccount
containers:
- image: nginx:1.9
imagePullPolicy: IfNotPresent
name: backend
# 查看所有sa
kubectl get sa -n qa
# 查看已经被使用的sa
kubectl get pod -n qa -o yaml | grep -i serviceaccount
# 删除不用的sa
kubectl delete sa -n qa test01
❄ TLS通信配置
知识点文档:https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kube-apiserver/
修改
apiserver
通过 TLS 加强 kube-apiserver 安全配置,要求
kube-apiserver 除了
TLS 1.3
及以上的版本可以使用,其他版本都不允许使用。密码套件(Cipher suite)为
TLS_AES_128_GCM_SHA256
修改
etcd
通过 TLS 加强 ETCD 安全配置,要求
- 密码套件(Cipher suite)为
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
# /etc/kubernetes/manifests/kube-apiserver.yaml
- --tls-cipher-suites=TLS_AES_128_GCM_SHA256
- --tls-min-version=VersionTLS13 # 如果题目要求 TLS 1.2,则就写 VersionTLS12
# /etc/kubernetes/manifests/etcd.yaml
- --cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
# 更改配置后将暂时get不到信息
# 等能get到信息即表示正常
kubectl get pod -n kube-system
❄ RBAC 授权
知识点文档:https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/
一个名为
web-pod
的现有 Pod 已在 namespacedb
中运行。编辑绑定到 Pod 的 ServiceAccount
service-account-web
的现有 Role,仅允许对services
类型的资源执行get
操作在 namespace
db
中创建一个名为role-2
,并仅允许对namespaces
类型的资源执行delete
操作的新 Role。创建一个名为
role-2-binding
的新RoleBinding,将新创建的 Role 绑定到 Pod 的 ServiceAccount注意:请勿删除现有的 RoleBindinbg
# 查找 web-pod 所绑定的 ServiceAccount
kubectl get pod -n db -o yaml | grep -i serviceaccount
# 查找对应 role
kubectl get rolebindings.rbac.authorization.k8s.io -n db -o yaml | grep -i service-account-web -C 2
修改role对应的权限
kubectl edit role -n db web-role
...
rules:
- apiGroups:
- ""
resources:
- services
verbs:
- get
...
在 namespace db
中创建 role-2
,并配置对 namespaces
类型进行 update
操作
kubectl create role role-2 --verb=update --resource=namespaces -n db
创建新的 RoleBinding role-2-binding
,将 role-2
绑定到 Pod 的 ServiceAccount
kubectl create rolebinding role-2-binding \
-n db \
--role=role-2 \
--serviceaccount=db:service-account-web
检查
kubectl describe rolebindings -n db role-2-binding
❄ 禁止匿名访问
重新配置 cluster 的 Kubernetes API 服务以确保只允许经过身份验证和授权的 REST 请求
使用授权模式
Node
,RBAC
和准入控制器NodeRestriction
删除用户
system:anonymous
的 ClusterRoleBinding 来进行清理注意:所有 kubectl 配置环境/文件也被配置为使用未经身份验证和未授权的访问。您不必更改它,但请注意,一旦完成 cluster 的安全加固,kubectl 的配置将无法工作
你可以使用位于 Cluster 的 master 节点上,cluster 原本的 kubectl 配置文
/etc/kubernetes/admin.conf
,以确保经过身份验证和授权的请求任然被允许
更改授权模式和添加 NodeRestriction 准入控制器
# /etc/kubernetes/manifests/kube-apiserver.yaml
...
- --authorization-mode=Node,RBAC # 修改这里
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --enable-admission-plugins=NodeRestriction # 修改这里
...
删除 clusterrolebinding
kubectl delete clusterrolebinding
❄ Secret
知识点文档:https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/
在 namespace
istio-system
中获取名为db1-test
的现有 secret 的内容将 username 字段存储在名为
/cks/sec/user.txt
的文件中,并将 password 字段存储在名为/cks/sec/pass.txt
的文件中。注意:你必须创建以上两个文件,他们还不存在。
注意:不要在以下步骤中使用/修改先前创建的文件,如果需要,可以创建新的临时文件。
在 namespace
istio-system
中创建一个名为db2-test
的新 secret,内容如下:
username :
production-instance
password :
KvLftKgs4aVH
最后,创建一个新的 Pod,它可以通过卷访问 secret
db2-test
:
Pod 名称
secret-pod
Namespace
istio-system
容器名
dev-container
镜像
nginx
卷名
secret-volume
挂载路径
/etc/secret
查看 namespace istio-system
中的 db1-test
的内容
kubectl get secrets -n istio-system db1-test -o yaml
...
password: aGVsbG8=
username: ZGIx
...
解密用户名和密码,并放到对应的文件中
# 解密用户名
echo -n 'ZGIx' | base64 -d > /cks/sec/user.txt
# 解密密码
echo -n 'aGVsbG8=' | base64 -d > /cks/sec/pass.txt
创建新secret
kubectl create secret generic db2-test \
--from-literal=username=production-instance \
--from-literal=password=KvLftKgs4aVH \
-n istio-system
创建pod,使用挂载
# secret-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
namespace: istio-system
spec:
containers:
- image: nginx
name: dev-container
volumeMounts:
- name: secret-volume
mountPath: /etc/secret
volumes:
- name: secret-volume
secret:
secretName: db2-test
kubectl create -f secret-pod.yaml
❄ Dockerfile 检测
分析和编辑给定的 Dockerfile
/cks/docker/Dockerfile
(基于 ubuntu:16.04 镜像),并修复在文件中拥有的突出的安全/最佳实践问题的两个指令分析和编辑给定的清单文件
/cks/docker/deployment.yaml
,并修复在文件中拥有突出的安全/最佳实践问题的两个字段注意:
请勿添加或删除配置设置;只需修改现有的配置设置让以上两个配置设置都不再有安全/最佳实践问题
如果您需要非特权用户来执行任何项目,请使用用户 ID 65535 的用户 nobody
只修改文件即可,不需要创建。
# /cks/docker/Dockerfile FROM ubuntu:latest RUN apt-get install -y wget curl gcc gcc-c++ make openssl-devel pcre-devel gd-devel \ iproute net-tools telnet && \ yum clean all && \ rm -rf /var/cache/apt/* USER root COPY sunnydale.sh . ADD nginx-1.15.5.tar.gz / RUN cd nginx-1.15.5 && \ ./configure --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_stub_status_module && \ make -j 4 && make install && \ mkdir /usr/local/nginx/conf/vhost && \ cd / && rm -rf nginx* && \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime USER root CMD ["./sunnydale.sh"] ENV PATH $PATH:/usr/local/nginx/sbin COPY nginx.conf /usr/local/nginx/conf/nginx.conf WORKDIR /usr/local/nginx EXPOSE 80 CMD ["nginx","-g","daemon off;"]
# /cks/docker/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: couchdb namespace: default labels: app: couchdb version: stable spec: replicas: 1 revisionHistoryLimit: 3 selector: matchLabels: app: couchdb version: stable template: metadata: labels: app: couchdb version: stable spec: containers: - name: couchdb image: demo:v1 imagePullPolicy: IfNotPresent livenessProbe: httpGet: path: /healthCheck port: 8080 scheme: HTTP initialDelaySeconds: 30 timeoutSeconds: 5 periodSeconds: 30 successThreshold: 1 failureThreshold: 5 readinessProbe: httpGet: path: /healthCheck port: 8080 scheme: HTTP initialDelaySeconds: 30 timeoutSeconds: 5 periodSeconds: 10 successThreshold: 1 failureThreshold: 5 ports: - name: http containerPort: 8080 protocol: TCP volumeMounts: - name: database-storage mountPath: /var/lib/database securityContext: {'capabilities': {'add': ['NET_BIND_SERVICE'], 'drop': ['all']}, 'privileged': True, 'readOnlyRootFilesystem': False, 'runAsUser': 65535} resources: limits: cpu: 300m memory: 500Mi requests: cpu: 100m memory: 100Mi volumes: - name: database-storage emptyDir: {}
Dockerfile 修改
# /cks/docker/Dockerfile
FROM ubuntu:16.04 # 镜像版本修改为16.04
...
USER nobody # 用户修改为 nobody
...
USER nobody # 用户修改为 nobody
...
deployment.yaml 修改
# /cks/docker/deployment.yaml
...
securityContext:
{'capabilities': {'add': ['NET_BIND_SERVICE'], 'drop': ['all']}, 'privileged': False, 'readOnlyRootFilesystem': True, 'runAsUser': 65535}
# 修改 privileged 为 False
# 修改 readOnlyRootFilesystem 为 True
...
❄ SecurityContext
知识点文档:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/security-context/
按照如下要求修改 namespace
sec-ns
里的 Deploymentsecdep
用 ID 为 30000 的用户启动容器(设置用户 ID 为: 30000)
不允许进程获得超出其父进程的特权(禁止
allowPrivilegeEscalation
)以只读方式加载容器的根文件系统(对根文件的只读权限)
kubectl edit deployments.apps -n sec-ns secdep
在 spec.template.containers
加入参数
注意:可能有多个容器
...
spec:
...
template:
...
spec:
containers:
- image: nginx
name: nginx
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 30000
...
containers:
- image: tomcat
name: tomcat
resources: {}
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 30000
...
...
❄ 容器安全 删除特权 Pod
查看 namespace
production
下所有 pod 是否有特权 Privileged 或者挂载 volume删除包含 Volumes 或 privileged 的 pod
kubectl get pods PODNAME -n production -o yaml | grep -i hostpath
kubectl get pods PODNAME -n production -o yaml | grep -i "privi.*: true"
kubectl delete pod PODNAME
❄ kube-bench 修复不安全项
针对 kubeadm 创建的 cluster 运行 CIS 基准测试工具时,发现了多个必须立即解决的问题
通过配置修复所有问题并重新启动受影响的组件以确保新的设置生效。
修复针对 API 服务器发现的所有以下违规行为: 1.2.7 Ensure that the --authorization-mode argument is not set to AlwaysAllow FAIL 1.2.8 Ensure that the --authorization-mode argument includes Node FAIL 1.2.9 Ensure that the --authorization-mode argument includes RBAC FAIL 1.2.18 Ensure that the --insecure-bind-address argument is not set FAIL
修复针对 kubelet 发现的所有以下违规行为: Fix all of the following violations that were found against the kubelet: 4.2.1 Ensure that the anonymous-auth argument is set to false FAIL 4.2.2 Ensure that the --authorization-mode argument is not set to AlwaysAllow FAIL 注意:尽可能使用 Webhook 身份验证/授权。
修复针对 etcd 发现的所有以下违规行为: Fix all of the following violations that were found against etcd: 2.2 Ensure that the --client-cert-auth argument is set to true FAIL
kube-apiserver
# /etc/kubernetes/manifests/kube-apiserver.yaml
...
- --authorization-mode=Node,RBAC # 修改这行
...
- --insecure-bind-address=0.0.0.0 # 注释这行 注释!!!!!!!
...
- --insecure-port=0 # 添加
...
kubelet
# /var/lib/kubelet/config.yaml
...
authentication:
anonymous:
enabled: false # 设定为 false
webhook:
...
enabled: true # 设定为 true
authorization:
mode: Webhook # 设定为 Webhook
...
etcd
# /etc/kubernetes/manifests/etcd.yaml
- --client-cert-auth=true # 设定为 true
重启服务
systemctl restart kubelet
systemctl status kubelet
❄ 日志审计
知识点文档:https://kubernetes.io/zh-cn/docs/tasks/debug/debug-cluster/audit/
在 cluster 中启用审计日志。为此,请启用日志后端,并确保:
- 日志存储在
/var/log/kubernetes/audit-logs.txt
- 日志文件能保留
10
天- 最多保留
2
个旧审计日志文件
/etc/kubernetes/logpolicy/sample-policy.yaml
提供了基本策略。它仅指定不记录
内容注意:基本策略位于 cluster 的 master 节点上。
编辑和扩展基本策略以记录:
- RequestResponse 级别的
persistentvolumes
更改- namespace
front-apps
中configmaps
更改的请求体
Metadata
级别的所有 namespace 中的ConfigMap
和Secret
的更改此外,添加一个全方位的规则以在
Metadata
级别记录所有其他请求注意:不要忘记应用修改后的策略
# /etc/kubernetes/logpolicy/sample-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
- "RequestReceived"
rules:
- level: RequestResponse
resources:
- group: ""
resources: ["persistentvolumes"]
- level: Request
resources:
- group: ""
resources: ["configmaps"]
namespaces: ["front-apps"]
- level: Metadata
resources:
- group: ""
resources: ["secrets", "configmaps"]
- level: Metadata
omitStages:
- "RequestReceived"
# /etc/kubernetes/manifests/kube-apiserver.yaml
# 添加以下配置
...
spec:
containers:
- command:
- --audit-policy-file=/etc/kubernetes/logpolicy/sample-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit-logs.txt
- --audit-log-maxage=10
- --audit-log-maxbackup=2
...
# 检查一下是否挂载这两个配置文件,如果有挂载就不用管,如果未挂载则需要手动添加
volumeMounts:
- mountPath: /etc/kubernetes/logpolicy/sample-policy.yaml
name: audit
readOnly: true
- mountPath: /var/log/kubernetes
name: audit-log
readOnly: false
...
volumes:
- hostPath:
path: /etc/kubernetes/logpolicy/sample-policy.yaml
type: File
name: audit
- hostPath:
path: /var/log/kubernetes
type: DirectoryOrCreate
name: audit-log
...
检查/var/log/kubernetes/audit/audit.log
日志文件是否有日志产生
tail -f /var/log/kubernetes/audit/audit.log
❄ NetworkPolicy
创建一个名为
pod-restriction
的 NetworkPolicy限制对在 namespace
dev-team
中运行的 Podproducts-service
的访问只允许以下 Pod 连接到 Pod
products-service
- namespace
qa
中的 Pod- 位于任何 namespace,带有标签
environment: testing
的 Pod你可以在
/cks/net/po.yaml
找到一个模板清单文件# /cks/net/po.yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default spec:
# NetworkPolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: pod-restriction
namespace: dev-team
spec:
podSelector:
matchLabels:
kubernetes.io/metadata.name: dev-team # 指定 namespace
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: qa # 指定 namespace
- from:
- namespaceSelector: {} # 表示所有 namespace
- podSelector:
matchLabels:
environment: testing
❄ NetworkPolicy DenyAll
https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/
在 namespace
testing
中创建一个名为denypolicy
NetworkPolicy,拒绝所有类型为 Ingress + Egress 的流量。
此新的 NetworkPolicy 必须拒绝 namespace
testing
中的所有的 Ingress + Egress 流量。将新创建的 NetworkPolicy 应用在 namespace
testing
中运行的所有 Pod 中。
# defaultdeny.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: denypolicy
namespace: testing
spec:
podSelector: {} # 默认匹配本命名空间
policyTypes:
- Ingress # 不指定则不允许所有
- Egress # 不指定则不允许所有
❄ trivy 检测镜像
使用 Trivy 开源容器扫描器检测 namespace
kamino
中 Pod 使用的具有严重漏洞的镜像。查找具有
High
或Critical
严重性漏洞的镜像,并删除使用这些镜像的 Pod。注意:Trivy 仅安装在 cluster 的 master 节点上
# 获取 pod image
kubectl describe pod -n kamino | grep "Image:"
# 或
kubectl get pods -n kamino -o yaml | grep "\- image:"
# 或
kubectl get pods -n kamino -o json | grep "\"image\""
# 或
kubectl get pods -n kamino -o custom-columns="NAME:.metadata.name,IMAGE:.spec.containers[*].image"
# 检测
trivy image -s HIGH,CRITICAL busybox:1.33.1
trivy image -s HIGH,CRITICAL nginx:1.14.2 #HIGH and CRITICAL
trivy image -s HIGH,CRITICAL amazonlinux:2
trivy image -s HIGH,CRITICAL amazonlinux:1
trivy image -s HIGH,CRITICAL centos:7 #HIGH and CRITICAL
删除
kubectl delete pod -n kamino PODNAME
❄ AppArmor
知识点文档:https://kubernetes.io/zh-cn/docs/tutorials/security/apparmor/
APPArmor 已在 cluster 的工作节点 node02 上被启用。一个 APPArmor 配置文件已存在,但尚未被实施。
在 cluster 的工作节点
node02
上,实施位于/etc/apparmor.d/nginx_apparmor
的现有 APPArmor 配置文件。编辑位于
/cks/KSSH00401/nginx-deploy.yaml
的现有清单文件以应用 AppArmor 配置文件。最后,应用清单文件并创建其中指定的 Pod
切换到 apparmor 的目录
cat /etc/apparmor.d/nginx_apparmor
# 其中 profile nginx-profile-3 flags=(attach_disconnected) 这一行的第二个单词 nginx-profile-3 就是这个配置文件的名字
执行 apparmor 策略模块
# 加载启用这个配置文件
apparmor_parser /etc/apparmor.d/nginx_apparmor
# 检查是否成功
apparmor_status | grep nginx-profile-3
配置 Pod 使用策略
# /cks/KSSH00401/nginx-deploy.yaml
apiVersion: v1
kind: Pod
metadata:
name: hello-apparmor
annotations:
# 告知 Kubernetes 去应用 AppArmor 配置 "k8s-apparmor-example-deny-write"。
# 请注意,如果节点上运行的 Kubernetes 不是 1.4 或更高版本,此注解将被忽略。
# Note: annotations, container and apparmor profile to be edited
# container.apparmor.security.beta.kubernetes.io/<<container name>>: localhost/<<profile name>>
container.apparmor.security.beta.kubernetes.io/hello: localhost/nginx-profile-3
spec:
containers:
- name: hello
image: busybox:1.28
command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
创建pod
kubectl apply -f /cks/KSSH00401/nginx-deploy.yaml
❄ sysdig & Falco
使用运行时检测工具来检测 Pod
redis123
单个容器中频发生成和执行的异常进程。有两种工具可供使用:
- sysdig
- falco
注: 这些工具只预装在 cluster 的工作节点 node02 上,不在 master 节点。
使用工具至少分析 30 秒 ,使用过滤器检查生成和执行的进程,将事件写到
/opt/KSR00101/incidents/summary
文件中,其中包含检测的事件, 格式如下:timestamp,uid/username,processName 01:40:19.601363716,root,init 01:40:20.606013716,nobody,bash 01:40:21.137163716,1000,tar
注: 保持工具的原始时间戳格式不变。
注: 确保事件文件存储在集群的工作节点上。
查看容器 container id
# containerd
crictl ps
# docker
docker ps
sysdig
# user.name
sysdig -M 45 -p "%evt.time,%user.name,%proc.name" container.id=46183d7281e15 >> /opt/KSR00101/incidents/summary
# user.uid
sysdig -M 45 -p "%evt.time,%user.uid,%proc.name" container.id=46183d7281e15 >> /opt/KSR00101/incidents/summary
Falco
# /home/cloud_user/monitor_rules.yaml
- rule: rule1
desc: rule1
condition: container.name = "redis123"
output: "%evt.time,%user.uid,%proc.name"
priority: WARNING
falco -M 45 -r /home/cloud_user/monitor_rules.yaml >> /opt/KSR00101/incidents/summary
❄ ImagePolicyWebhook 容器镜像扫描
cluster 上设置了容器镜像扫描器,但尚未完全集成到 cluster 的配置中。
完成后,容器镜像扫描器应扫描并拒绝易受攻击的镜像的使用。
注意:你必须在 cluster 的 master 节点上完成整个考题,所有服务和文件都已被准备好并放置在该节点上。
给定一个目录
/etc/kubernetes/epconfig
中不完整的配置,以及具有 HTTPS 端点
https://image-bouncer-webhook.default.svc:1323/image_policy
的功能性容器镜像扫描器:
启用必要的插件来创建镜像策略
校验控制配置并将其更改为隐式拒绝(implicit deny)
编辑配置以正确指向提供的 HTTPS 端点
最后,通过尝试部署易受攻击的资源
/cks/img/web1.yaml
来测试配置是否有效。
# /etc/kubernetes/epconfig/admission_configuration.json
{
"imagePolicy": {
"kubeConfigFile": "/etc/kubernetes/epconfig/kubeconfig.yaml",
"allowTTL": 50,
"denyTTL": 50,
"retryBackoff": 500,
"defaultAllow": false
}
}
# /etc/kubernetes/epconfig/kubeconfig.yaml
...
clusters:
- cluster:
server: https://image-bouncer-webhook.default.svc:1323/image_policy # 添加 webhook server 地址
name: bouncer_webhook
...
# /etc/kubernetes/manifests/kube-apiserver.yaml
...
spec:
containers:
- command:
- --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook
- --admission-control-config-file=/etc/kubernetes/epconfig/admission_configuration.json
...
volumeMounts:
- mountPath: /etc/kubernetes/epconfig
name: epconfig
...
volumes:
- name: epconfig
hostPath:
path: /etc/kubernetes/epconfig
等待 apiserver
自动重启,并恢复
创建易受攻击的资源 /cks/img/web1.yaml
来测试配置是否有效。因为模拟环境里的 image_policy 策略是镜像 tag 是 latest 的不允许创建,则验证成功。
kubectl apply -f /cks/img/web1.yaml
❄ PodSecurityPolicy
创建一个可以阻止创建特权 pod 的名为
prevent-psp-policy
的 PodSecurityPolicy。创建一个使用 PodSecurityPolicy
prevent-psp-policy
的 名为restrict-access-role
的 ClusterRole。在 namespace
development
创建一个名为pspdenial-sa
的 serviceAccount。创建一个 ClusterRole
restrict-access-role
与 serviceAccountpspdenial-sa
绑定的名为dany-access-bind
的 clusterRoleBinding。
确认策略启用
# /etc/kubernetes/manifests/kube-apiserver.yaml
- --enable-admission-plugins=NodeRestriction,PodSecurityPolicy
# prevent-psp-policy.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: prevent-psp-policy
namespace: development
spec:
privileged: false
runAsUser:
rule: "RunAsAny"
fsGroup:
rule: "RunAsAny"
seLinux:
rule: "RunAsAny"
supplementalGroups:
rule: "RunAsAny"
# restrict-access-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: restrict-access-role
rules:
- apiGroups:
- policy
resources:
- podsecuritypolicies
verbs:
- use
resourceNames:
- prevent-psp-policy
# pspdenial-sa
# kubectl create sa pspdenial-sa -n development
apiVersion: v1
kind: ServiceAccount
metadata:
name: pspdenial-sa
namespace: development
# dany-access-bind.yaml
# kubectl create clusterrolebinding dany-access-bind \
# --clusterrole=restrict-access-role \
# --serviceaccount=development:pspdenial-sa
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dany-access-bind
roleRef:
kind: ClusterRole
name: restrict-access-role
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: pspdenial-sa
namespace: development