SCCs influence whether or not a pod is given a default user ID, fsGroup
ID,
supplemental group ID, and SELinux label. They also influence whether or not IDs
supplied in the pod definition (or in the image) will be validated against a
range of allowable IDs. If validation is required and fails, then the pod will
also fail.
SCCs define strategies, such as runAsUser
, supplementalGroups
, and
fsGroup
. These strategies help decide whether the pod is authorized.
Strategy values set to RunAsAny are essentially stating that the pod can do
what it wants regarding that strategy. Authorization is skipped for that
strategy and no OpenShift Container Platform default is produced based on that strategy.
Therefore, IDs and SELinux labels in the resulting container are based on
container defaults instead of OpenShift Container Platform policies.
For a quick summary of RunAsAny:
-
Any ID defined in the pod definition (or image) is allowed.
-
Absence of an ID in the pod definition (and in the image) results in the
container assigning an ID, which is root (0) for Docker.
-
No SELinux labels are defined, so Docker will assign a unique label.
For these reasons, SCCs with RunAsAny for ID-related strategies should be
protected so that ordinary developers do not have access to the SCC. On the
other hand, SCC strategies set to MustRunAs or MustRunAsRange trigger ID
validation (for ID-related strategies), and cause default values to be supplied
by OpenShift Container Platform to the container when those values are not supplied directly
in the pod definition or image.
|
Allowing access to SCCs with a RunAsAny FSGroup strategy can also prevent
users from accessing their block devices. Pods need to specify an fsGroup in
order to take over their block devices. Normally, this is done when
the SCC FSGroup strategy is set to MustRunAs. If a user’s pod is assigned
an SCC with a RunAsAny FSGroup strategy, then the user may face permission
denied errors until they discover that they need to specify an fsGroup
themselves.
|
SCCs may define the range of allowed IDs (user or groups). If range checking is
required (for example, using MustRunAs) and the allowable range is not defined
in the SCC, then the project determines the ID range. Therefore, projects
support ranges of allowable ID. However, unlike SCCs, projects do not define
strategies, such as runAsUser
.
Allowable ranges are helpful not only because they define the boundaries for
container IDs, but also because the minimum value in the range becomes the
default value for the ID in question. For example, if the SCC ID strategy value
is MustRunAs, the minimum value of an ID range is 100, and the ID is absent
from the pod definition, then 100 is provided as the default for this ID.
As part of pod admission, the SCCs available to a pod are examined (roughly, in
priority order followed by most restrictive) to best match the requests of the
pod. Setting a SCC’s strategy type to RunAsAny is less restrictive, whereas a
type of MustRunAs is more restrictive. All of these strategies are evaluated.
To see which SCC was assigned to a pod, use the oc get pod
command:
# oc get pod <pod_name> -o yaml
...
metadata:
annotations:
openshift.io/scc: nfs-scc (1)
name: nfs-pod1 (2)
namespace: default (3)
...
1 |
Name of the SCC that the pod used (in this case, a custom SCC). |
2 |
Name of the pod. |
3 |
Name of the project. "Namespace" is interchangeable with "project" in
OpenShift Container Platform. See
Projects
and Users for details. |
It may not be immediately obvious which SCC was matched by a pod, so the command
above can be very useful in understanding the UID, supplemental groups, and
SELinux relabeling in a live container.
Any SCC with a strategy set to RunAsAny allows specific values for that
strategy to be defined in the pod definition (and/or image). When this applies
to the user ID (runAsUser
) it is prudent to restrict access to the SCC to
prevent a container from being able to run as root.
Because pods often match the restricted SCC, it is worth knowing the security
this entails. The restricted SCC has the following characteristics:
-
User IDs are constrained due to the runAsUser
strategy being set to
MustRunAsRange. This forces user ID validation.
-
Because a range of allowable user IDs is not defined in the SCC (see oc export
scc restricted
for more details), the project’s
openshift.io/sa.scc.uid-range
range will be used for range checking and for
a default ID, if needed.
-
A default user ID is produced when a user ID is not specified in the pod
definition and the matching SCC’s runAsUser
is set to MustRunAsRange.
-
An SELinux label is required (seLinuxContext
set to MustRunAs), which uses
the project’s default MCS label.
-
fsGroup
IDs are constrained to a single value due to the FSGroup
strategy
being set to MustRunAs, which dictates that the value to use is the minimum
value of the first range specified.
-
Because a range of allowable fsGroup
IDs is not defined in the SCC, the
minimum value of the project’s openshift.io/sa.scc.supplemental-groups
range (or the same range used for user IDs) will be used for
validation and for a default ID, if needed.
-
A default fsGroup
ID is produced when a fsGroup
ID is not specified in
the pod and the matching SCC’s FSGroup
is set to MustRunAs.
-
Arbitrary supplemental group IDs are allowed because no range checking is
required. This is a result of the supplementalGroups
strategy being set to
RunAsAny.
-
Default supplemental groups are not produced for the running pod due to
RunAsAny for the two group strategies above. Therefore, if no groups are
defined in the pod definition (or in the image), the container(s) will have no
supplemental groups predefined.
The following shows the default project and a custom SCC (my-custom-scc),
which summarizes the interactions of the SCC and the project:
$ oc get project default -o yaml (1)
...
metadata:
annotations: (2)
openshift.io/sa.scc.mcs: s0:c1,c0 (3)
openshift.io/sa.scc.supplemental-groups: 1000000000/10000 (4)
openshift.io/sa.scc.uid-range: 1000000000/10000 (5)
$ oc get scc my-custom-scc -o yaml
...
fsGroup:
type: MustRunAs (6)
ranges:
- min: 5000
max: 6000
runAsUser:
type: MustRunAsRange (7)
uidRangeMin: 1000100000
uidRangeMax: 1000100999
seLinuxContext: (8)
type: MustRunAs
SELinuxOptions: (9)
user: <selinux-user-name>
role: ...
type: ...
level: ...
supplementalGroups:
type: MustRunAs (6)
ranges:
- min: 5000
max: 6000
1 |
default is the name of the project. |
2 |
Default values are only produced when the corresponding SCC strategy is not
RunAsAny. |
3 |
SELinux default when not defined in the pod definition or in the SCC. |
4 |
Range of allowable group IDs. ID validation only occurs when the SCC
strategy is RunAsAny. There can be more than one range specified, separated by
commas. See below for supported formats. |
5 |
Same as <4> but for user IDs. Also, only a single range of user IDs is
supported. |
6 |
MustRunAs enforces group ID range checking and provides the container’s
groups default. Based on this SCC definition, the default is 5000 (the minimum
ID value). If the range was omitted from the SCC, then the default would be
1000000000 (derived from the project). The other supported type, RunAsAny, does not
perform range checking, thus allowing any group ID, and produces no default
groups. |
7 |
MustRunAsRange enforces user ID range checking and provides a UID default.
Based on this SCC, the default UID is 1000100000 (the minimum value). If the minimum
and maximum range were omitted from the SCC, the default user ID would be
1000000000 (derived from the project). MustRunAsNonRoot and RunAsAny are
the other supported types. The range of allowed IDs can be defined to include
any user IDs required for the target storage. |
8 |
When set to MustRunAs, the container is created with the SCC’s SELinux
options, or the MCS default defined in the project. A type of RunAsAny
indicates that SELinux context is not required, and, if not defined in the pod,
is not set in the container. |
9 |
The SELinux user name, role name, type, and labels can be defined here. |
-
M/N
, where M
is the starting ID and N
is the count, so the range becomes
M
through (and including) M+N-1
.
-
M-N
, where M
is again the starting ID and N
is the ending ID. The default
group ID is the starting ID in the first range, which is 1000000000
in this
project. If the SCC did not define a minimum group ID, then the project’s
default ID is applied.