ocp scc
SecComp
https://docs.openshift.com/container-platform/4.3/authentication/managing-security-context-constraints.html
https://docs.docker.com/engine/security/seccomp/
https://docs.openshift.com/container-platform/4.3/nodes/nodes/nodes-nodes-managing.html
https://docs.openshift.com/container-platform/3.11/admin_guide/seccomp.html
https://gardener.cloud/050-tutorials/content/howto/secure-seccomp/
video
- https://www.bilibili.com/video/BV1Sa4y1x7UP/
- https://youtu.be/gwu53N4dIws
实验证明,容器内部更改date,不影响主机。
# 在kube-system中创建特权用户
oc project kube-system
oc create serviceaccount -n kube-system demo-app
oc adm policy add-scc-to-user privileged -z demo-app
# 创建seccomp需要的security profile,我们这里创建一个只屏蔽clock set的profile
cat << EOF > demo.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: seccomp-profile
namespace: kube-system
data:
my-profile.json: |
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"name": "clock_settime",
"action": "SCMP_ACT_ERRNO"
}
]
}
EOF
oc apply -f demo.yaml
# 创建一个daemon set,把我们自定义的security profile复制到各个节点的containerd运行时配置目录中,这样containerd就可以根据需要,使用这个security profile
cat << EOF > demo.yaml
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: seccomp
namespace: kube-system
labels:
security: seccomp
spec:
selector:
matchLabels:
security: seccomp
template:
metadata:
labels:
security: seccomp
spec:
initContainers:
- name: installer
image: docker.io/library/alpine:latest
command: ["/bin/sh", "-c", "cp -r -L /seccomp/*.json /host/seccomp/"]
securityContext:
privileged: true
volumeMounts:
- name: profiles
mountPath: /seccomp
- name: hostseccomp
mountPath: /host/seccomp
readOnly: false
containers:
- name: pause
image: gcr.io/google_containers/pause-amd64:3.0
terminationGracePeriodSeconds: 5
serviceAccount: demo-app
volumes:
- name: hostseccomp
hostPath:
path: /var/lib/kubelet/seccomp
- name: profiles
configMap:
name: seccomp-profile
EOF
oc apply -f demo.yaml
# 在我们的demo project中,创建特权用户
oc project demo
oc create serviceaccount -n demo demo-app
oc adm policy add-scc-to-user privileged -z demo-app
# 在demo project中,创建应用,指定使用我们刚创建的security profile,为了展现效果,我们特别的指明,需要clock setting这个权限,后面可以看到,security profile屏蔽了这个请求。
cat << EOF > demo.yaml
---
apiVersion: v1
kind: Pod
metadata:
annotations:
seccomp.security.alpha.kubernetes.io/pod: "localhost/my-profile.json"
name: demo
spec:
nodeSelector:
kubernetes.io/hostname: 'worker-0.ocp4.redhat.ren'
restartPolicy: Always
containers:
- name: demo1
image: >-
registry.redhat.ren:5443/docker.io/wangzheng422/centos:centos7-test
env:
- name: key
value: value
command: ["/bin/bash", "-c", "--" ]
args: [ "trap : TERM INT; sleep infinity & wait" ]
imagePullPolicy: Always
securityContext:
capabilities:
add: ["CAP_SYS_TIME"]
serviceAccount: demo-app
EOF
oc apply -n demo -f demo.yaml
# 进入这个pod,运行命令能看到命令失败
# this will failed, even you add the capabilities.
date -s "1 second"
# date: cannot set date: Operation not permitted
# Tue Mar 24 02:10:49 UTC 2020
# 为了对比,我们更改刚才的security profile,所有的都放开
# try to allow
cat << EOF > demo.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: seccomp-profile
namespace: kube-system
data:
my-profile.json: |
{
"defaultAction": "SCMP_ACT_ALLOW"
}
EOF
oc apply -f demo.yaml
# 通过打标签的方法,让daemon set重启,这样就把我们更新的security profile更新到各个节点上去
# restart damonset and restart pod.
# oc annotate -n kube-system ds seccomp last-update="`date`"
oc patch -n kube-system ds seccomp -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"
oc get pod -n kube-system
# 进入demo pod,再次运行命令,可以看到命令运行成功。
# this command will ok.
date -s "1 second"
# 最好,为了防止安全风险,我们将security profile重置成拒绝所有,并重启daemon set,更新到所有节点上。
# finally, restore
cat << EOF > demo.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: seccomp-profile
namespace: kube-system
data:
my-profile.json: |
{
"defaultAction": "SCMP_ACT_ERRNO"
}
EOF
oc apply -f demo.yaml
# restart damonset and restart pod.
oc patch -n kube-system ds seccomp -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"
capabilities
video
- https://youtu.be/yLdJghw-7xs
- https://www.bilibili.com/video/BV1x64y1T7BZ/
# 创建pod,限制selinux,没有clock setting的capability.
cat << EOF > demo.yaml
---
kind: Deployment
apiVersion: apps/v1
metadata:
annotations:
name: demo
spec:
replicas: 1
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
nodeSelector:
kubernetes.io/hostname: 'infra1.hsc.redhat.ren'
restartPolicy: Always
containers:
- name: demo1
image: >-
registry.redhat.ren:5443/docker.io/wangzheng422/centos:centos7-test
env:
- name: key
value: value
command: ["/bin/bash", "-c", "--" ]
args: [ "trap : TERM INT; sleep infinity & wait" ]
imagePullPolicy: Always
securityContext:
capabilities:
drop: ["CAP_SYS_TIME"]
serviceAccount: demo-app
EOF
oc apply -n demo -f demo.yaml
# 进入pod,运行以下命令,不成功
date -s "1 second"
# 更新这个pod,赋予clock setting的capability
cat << EOF > demo.yaml
---
kind: Deployment
apiVersion: apps/v1
metadata:
annotations:
name: demo
spec:
replicas: 1
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
nodeSelector:
kubernetes.io/hostname: 'infra1.hsc.redhat.ren'
restartPolicy: Always
containers:
- name: demo1
image: >-
registry.redhat.ren:5443/docker.io/wangzheng422/centos:centos7-test
env:
- name: key
value: value
command: ["/bin/bash", "-c", "--" ]
args: [ "trap : TERM INT; sleep infinity & wait" ]
imagePullPolicy: Always
securityContext:
capabilities:
add: ["CAP_SYS_TIME"]
serviceAccount: demo-app
EOF
oc apply -n demo -f demo.yaml
# 进入pod,运行命令,可以看到命令运行成功
date -s "1 second"
# 删除演示应用
oc delete -n demo -f demo.yaml
MCS
https://access.redhat.com/documentation/en-us/openshift_container_platform/3.3/html/installation_and_configuration/configuring-persistent-storage#selinuxoptions
http://www.178linux.com/98614
https://access.redhat.com/sites/default/files/video/files/mls_-_wide_8.pdf
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/mls
https://www.cnblogs.com/charlieroro/p/10830721.html
video
- https://youtu.be/XoQ11ZXEL7Y
- https://www.bilibili.com/video/BV115411t777/
# on worker-0
# yum install selinux-policy-mls
# vi /etc/selinux/config
# # SELINUXTYPE=mls
# # SELINUXTYPE=mls
# getenforce
# fixfiles -F onboot
# cat /.autorelabel | less
# semanage login -l
# # semanage login --modify --range s0-s15:c0.c1023 root
# chcon -R -t default_t /data/mcs
# 创建测试用的目录,设置特殊的权限。
mkdir /data/mcs
chcon -R -l s0:c100 /data/mcs
chcon -R -t container_file_t /data/mcs
chown -R 1000:2000 /data/mcs
chmod -R 775 /data/mcs
# semanage fcontext -l | grep default_t
oc get project demo -o yaml
# metadata:
# annotations:
# openshift.io/description: ""
# openshift.io/display-name: ""
# openshift.io/requester: kube:admin
# openshift.io/sa.scc.mcs: s0:c23,c22
# openshift.io/sa.scc.supplemental-groups: 1000550000/10000
# openshift.io/sa.scc.uid-range: 1000550000/10000
# 创建pod,指定selinux的权限s0:c99。
cat << EOF > demo.yaml
---
apiVersion: v1
kind: Pod
metadata:
annotations:
name: demo
spec:
nodeSelector:
kubernetes.io/hostname: 'infra1.hsc.redhat.ren'
restartPolicy: Always
containers:
- name: demo1
image: >-
registry.redhat.ren:5443/docker.io/wangzheng422/centos:centos7-test
env:
- name: key
value: value
command: ["/bin/bash", "-c", "--" ]
args: [ "trap : TERM INT; sleep infinity & wait" ]
imagePullPolicy: Always
securityContext:
runAsUser: 1000
runAsGroup: 2000
seLinuxOptions:
level: 's0:c99'
volumeMounts:
- mountPath: /data
name: demo
readOnly: false
serviceAccount: demo-app
volumes:
- name: demo
hostPath:
path: /data/mcs
type: Directory
EOF
oc apply -n demo -f demo.yaml
# 进入pod检查权限,由于s0:c99 和目录的s0:c100 权限不符,以下操作失败
# below will fail
cd /data
# 修改目录权限,符合pod中的selinux声明
# after change the host path selinux flag
chcon -R -l s0:c99 /data/mcs
# system_u:object_r:default_t:s0:c99
# system_u:system_r:container_t:s0:c99
# seinfo -tcontainer_t
# seinfo -rsystem_r
# 进入pod操作,以下操作能够成功。
# then, below will ok
cd /data
ls
touch test