$ oc new-project nginx-deploy
创建和管理 SELinux 配置文件并将它们绑定到工作负载。
安全配置文件操作符仅支持 Red Hat Enterprise Linux CoreOS (RHCOS) 工作节点。不支持 Red Hat Enterprise Linux (RHEL) 节点。 |
使用SelinuxProfile
对象创建配置文件。
SelinuxProfile
对象具有多个功能,可以实现更好的安全加固和可读性。
将配置文件继承限制为当前命名空间或系统范围的配置文件。由于系统中通常安装了许多配置文件,但集群工作负载仅应使用其中一部分,因此可继承的系统配置文件列在spod
实例的spec.selinuxOptions.allowedSystemProfiles
中。
执行权限、类和标签的基本验证。
添加一个新的关键字@self
,用于描述使用该策略的进程。这允许在工作负载和命名空间之间轻松重用策略,因为策略的使用基于名称和命名空间。
与直接使用 SELinux CIL 语言编写配置文件相比,它增加了更好的安全加固和可读性功能。
运行以下命令创建项目:
$ oc new-project nginx-deploy
通过创建以下SelinuxProfile
对象,创建一个可与非特权工作负载一起使用的策略:
apiVersion: security-profiles-operator.x-k8s.io/v1alpha2
kind: SelinuxProfile
metadata:
name: nginx-secure
namespace: nginx-deploy
spec:
allow:
'@self':
tcp_socket:
- listen
http_cache_port_t:
tcp_socket:
- name_bind
node_t:
tcp_socket:
- node_bind
inherit:
- kind: System
name: container
运行以下命令等待selinuxd
安装策略:
$ oc wait --for=condition=ready -n nginx-deploy selinuxprofile nginx-secure
selinuxprofile.security-profiles-operator.x-k8s.io/nginx-secure condition met
策略被放置到安全配置文件操作符拥有的容器中的emptyDir
中。策略以通用中间语言 (CIL) 格式保存在/etc/selinux.d/
中。
运行以下命令访问 Pod:
$ oc -n openshift-security-profiles rsh -c selinuxd ds/spod
运行以下命令使用cat
查看文件内容:
$ cat /etc/selinux.d/nginx-secure_nginx-deploy.cil
(block nginx-secure_nginx-deploy
(blockinherit container)
(allow process nginx-secure_nginx-deploy.process ( tcp_socket ( listen )))
(allow process http_cache_port_t ( tcp_socket ( name_bind )))
(allow process node_t ( tcp_socket ( node_bind )))
)
运行以下命令验证策略是否已安装:
$ semodule -l | grep nginx-secure
nginx-secure_nginx-deploy
创建一个 Pod 来应用已创建的配置文件之一。
对于 SELinux 配置文件,必须标记命名空间以允许特权工作负载。
运行以下命令将scc.podSecurityLabelSync=false
标签应用于nginx-deploy
命名空间:
$ oc label ns nginx-deploy security.openshift.io/scc.podSecurityLabelSync=false
运行以下命令将privileged
标签应用于nginx-deploy
命名空间:
$ oc label ns nginx-deploy --overwrite=true pod-security.kubernetes.io/enforce=privileged
运行以下命令获取 SELinux 配置文件使用字符串:
$ oc get selinuxprofile.security-profiles-operator.x-k8s.io/nginx-secure -n nginx-deploy -ojsonpath='{.status.usage}'
nginx-secure_nginx-deploy.process
在工作负载清单的.spec.containers[].securityContext.seLinuxOptions
属性中应用输出字符串。
apiVersion: v1
kind: Pod
metadata:
name: nginx-secure
namespace: nginx-deploy
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- image: nginxinc/nginx-unprivileged:1.21
name: nginx
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
seLinuxOptions:
# NOTE: This uses an appropriate SELinux type
type: nginx-secure_nginx-deploy.process
在创建工作负载之前,必须存在 SELinux |
要记录策略违规或 AVC 拒绝,请将SElinuxProfile
配置文件设置为permissive
。
此步骤定义日志策略。它不设置强制策略。 |
向SElinuxProfile
添加permissive: true
。
apiVersion: security-profiles-operator.x-k8s.io/v1alpha2
kind: SelinuxProfile
metadata:
name: nginx-secure
namespace: nginx-deploy
spec:
permissive: true
可以使用ProfileBinding
资源将安全配置文件绑定到容器的SecurityContext
。
要将使用quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
镜像的 Pod 绑定到示例SelinuxProfile
配置文件,请在与 Pod 和SelinuxProfile
对象相同的命名空间中创建一个ProfileBinding
对象。
apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
kind: ProfileBinding
metadata:
namespace: my-namespace
name: nginx-binding
spec:
profileRef:
kind: SelinuxProfile (1)
name: profile (2)
image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21 (3)
1 | kind: 变量指的是配置文件的种类。 |
2 | name: 变量指的是配置文件的名称。 |
3 | 可以使用通配符在镜像属性中启用默认安全配置文件:image: "*" 。 |
使用 |
运行以下命令使用enable-binding=true
标记命名空间:
$ oc label ns my-namespace spo.x-k8s.io/enable-binding=true
定义一个名为test-pod.yaml
的 Pod:
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: test-container
image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
创建 Pod:
$ oc create -f test-pod.yaml
如果 Pod 已经存在,则必须重新创建 Pod 才能使绑定正常工作。 |
运行以下命令确认 Pod 是否继承了ProfileBinding
:
$ oc get pod test-pod -o jsonpath='{.spec.containers[*].securityContext.seLinuxOptions.type}'
profile_nginx-binding.process
在部署用于复制控制器(例如部署或守护程序集)的 SELinux 策略时,请注意由控制器生成的Pod
对象并非以创建工作负载的用户身份运行。除非选择了ServiceAccount
,否则 Pod 可能会恢复为使用受限的SecurityContextConstraints
(SCC),这不允许使用自定义安全策略。
运行以下命令创建项目:
$ oc new-project nginx-secure
创建以下RoleBinding
对象以允许在nginx-secure
命名空间中使用 SELinux 策略:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: spo-nginx
namespace: nginx-secure
subjects:
- kind: ServiceAccount
name: spo-deploy-test
roleRef:
kind: Role
name: spo-nginx
apiGroup: rbac.authorization.k8s.io
创建Role
对象:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: spo-nginx
namespace: nginx-secure
rules:
- apiGroups:
- security.openshift.io
resources:
- securitycontextconstraints
resourceNames:
- privileged
verbs:
- use
创建ServiceAccount
对象:
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: null
name: spo-deploy-test
namespace: nginx-secure
创建Deployment
对象:
apiVersion: apps/v1
kind: Deployment
metadata:
name: selinux-test
namespace: nginx-secure
metadata:
labels:
app: selinux-test
spec:
replicas: 3
selector:
matchLabels:
app: selinux-test
template:
metadata:
labels:
app: selinux-test
spec:
serviceAccountName: spo-deploy-test
securityContext:
seLinuxOptions:
type: nginx-secure_nginx-secure.process (1)
containers:
- name: nginx-unpriv
image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
ports:
- containerPort: 8080
1 | 在创建 Deployment 之前,必须存在.seLinuxOptions.type 。 |
SELinux 类型未在工作负载中指定,由 SCC 处理。当 Pod 由部署和 |
确保您的 SCC 只能被正确的服务帐户使用。有关更多信息,请参阅“其他资源”。
安全配置文件操作符可以使用ProfileRecording
对象记录系统调用,从而更容易为应用程序创建基线配置文件。
使用日志丰富器记录 SELinux 配置文件时,请验证日志丰富器功能是否已启用。有关更多信息,请参阅“其他资源”。
具有 |
运行以下命令创建项目:
$ oc new-project my-namespace
运行以下命令使用enable-recording=true
标记命名空间:
$ oc label ns my-namespace spo.x-k8s.io/enable-recording=true
创建一个包含recorder: logs
变量的ProfileRecording
对象。
apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
kind: ProfileRecording
metadata:
namespace: my-namespace
name: test-recording
spec:
kind: SelinuxProfile
recorder: logs
podSelector:
matchLabels:
app: my-app
创建一个要记录的工作负载。
apiVersion: v1
kind: Pod
metadata:
namespace: my-namespace
name: my-pod
labels:
app: my-app
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: nginx
image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
ports:
- containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
- name: redis
image: quay.io/security-profiles-operator/redis:6.2.1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
通过输入以下命令确认Pod处于运行中
状态。
$ oc -n my-namespace get pods
NAME READY STATUS RESTARTS AGE
my-pod 2/2 Running 0 18s
确认增强器指示它接收这些容器的审计日志。
$ oc -n openshift-security-profiles logs --since=1m --selector name=spod -c log-enricher
I0517 13:55:36.383187 348295 enricher.go:376] log-enricher "msg"="audit" "container"="redis" "namespace"="my-namespace" "node"="ip-10-0-189-53.us-east-2.compute.internal" "perm"="name_bind" "pod"="my-pod" "profile"="test-recording_redis_6kmrb_1684331729" "scontext"="system_u:system_r:selinuxrecording.process:s0:c4,c27" "tclass"="tcp_socket" "tcontext"="system_u:object_r:redis_port_t:s0" "timestamp"="1684331735.105:273965" "type"="selinux"
删除Pod。
$ oc -n my-namepace delete pod my-pod
确认安全配置文件操作符协调了两个SELinux配置文件。
$ oc get selinuxprofiles -lspo.x-k8s.io/recording-id=test-recording -n my-namespace
NAME USAGE STATE
test-recording-nginx test-recording-nginx_my-namespace.process Installed
test-recording-redis test-recording-redis_my-namespace.process Installed
默认情况下,每个容器实例都记录到单独的配置文件中。安全配置文件操作符可以将每个容器的配置文件合并到单个配置文件中。当使用ReplicaSet
或Deployment
对象部署应用程序时,合并配置文件非常有用。
编辑ProfileRecording
对象以包含mergeStrategy: containers
变量。
apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
kind: ProfileRecording
metadata:
# The name of the Recording is the same as the resulting SelinuxProfile CRD
# after reconciliation.
name: test-recording
namespace: my-namespace
spec:
kind: SelinuxProfile
recorder: logs
mergeStrategy: containers
podSelector:
matchLabels:
app: sp-record
运行以下命令为命名空间添加标签。
$ oc label ns my-namespace security.openshift.io/scc.podSecurityLabelSync=false pod-security.kubernetes.io/enforce=privileged pod-security.kubernetes.io/audit=privileged pod-security.kubernetes.io/warn=privileged --overwrite=true
使用以下YAML创建工作负载。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: my-namespace
spec:
replicas: 3
selector:
matchLabels:
app: sp-record
template:
metadata:
labels:
app: sp-record
spec:
serviceAccountName: spo-record-sa
containers:
- name: nginx-record
image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
ports:
- containerPort: 8080
要记录单个配置文件,请运行以下命令删除部署。
$ oc delete deployment nginx-deploy -n my-namespace
要合并配置文件,请运行以下命令删除配置文件记录。
$ oc delete profilerecording test-recording -n my-namespace
要启动合并操作并生成结果配置文件,请运行以下命令。
$ oc get selinuxprofiles -lspo.x-k8s.io/recording-id=test-recording -n my-namespace
NAME USAGE STATE
test-recording-nginx-record test-recording-nginx-record_my-namespace.process Installed
要查看任何容器使用的权限,请运行以下命令。
$ oc get selinuxprofiles test-recording-nginx-record -o yaml
SELinux策略的记录是通过一个Webhook实现的,该Webhook将特殊的SELinux类型注入到正在记录的Pod中。SELinux类型使Pod以宽松
模式运行,并将所有AVC拒绝记录到audit.log
中。默认情况下,工作负载不允许使用自定义SELinux策略运行,而是使用自动生成的类型。
要记录工作负载,工作负载必须使用具有权限的服务帐户来使用SCC,该SCC允许Webhook注入宽松的SELinux类型。privileged
SCC包含seLinuxContext: RunAsAny
。
此外,如果您的集群启用了Pod安全准入,则命名空间必须用pod-security.kubernetes.io/enforce: privileged
标记,因为只有privileged
Pod安全标准允许使用自定义SELinux策略。