package bootstrappolicy import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/serviceaccount" ) const ( // SecurityContextConstraintPrivileged is used as the name for the system default privileged scc. SecurityContextConstraintPrivileged = "privileged" SecurityContextConstraintPrivilegedDesc = "privileged allows access to all privileged and host features and the ability to run as any user, any group, any fsGroup, and with any SELinux context. WARNING: this is the most relaxed SCC and should be used only for cluster administration. Grant with caution." // SecurityContextConstraintRestricted is used as the name for the system default restricted scc. SecurityContextConstraintRestricted = "restricted" SecurityContextConstraintRestrictedDesc = "restricted denies access to all host features and requires pods to be run with a UID, and SELinux context that are allocated to the namespace. This is the most restrictive SCC." // SecurityContextConstraintNonRoot is used as the name for the system default non-root scc. SecurityContextConstraintNonRoot = "nonroot" SecurityContextConstraintNonRootDesc = "nonroot provides all features of the restricted SCC but allows users to run with any non-root UID. The user must specify the UID or it must be specified on the by the manifest of the container runtime." // SecurityContextConstraintHostMountAndAnyUID is used as the name for the system default host mount + any UID scc. SecurityContextConstraintHostMountAndAnyUID = "hostmount-anyuid" SecurityContextConstraintHostMountAndAnyUIDDesc = "hostmount-anyuid provides all the features of the restricted SCC but allows host mounts and any UID by a pod. This is primarily used by the persistent volume recycler. WARNING: this SCC allows host file system access as any UID, including UID 0. Grant with caution." // SecurityContextConstraintHostNS is used as the name for the system default scc // that grants access to all host ns features. SecurityContextConstraintHostNS = "hostaccess" SecurityContextConstraintHostNSDesc = "hostaccess allows access to all host namespaces but still requires pods to be run with a UID and SELinux context that are allocated to the namespace. WARNING: this SCC allows host access to namespaces, file systems, and PIDS. It should only be used by trusted pods. Grant with caution." // SecurityContextConstraintsAnyUID is used as the name for the system default scc that // grants access to run as any uid but is still restricted to specific SELinux contexts. SecurityContextConstraintsAnyUID = "anyuid" SecurityContextConstraintsAnyUIDDesc = "anyuid provides all features of the restricted SCC but allows users to run with any UID and any GID. This is the default SCC for authenticated users." // SecurityContextConstraintsHostNetwork is used as the name for the system default scc that // grants access to run with host networking and host ports but still allocates uid/gids/selinux from the // namespace. SecurityContextConstraintsHostNetwork = "hostnetwork" SecurityContextConstraintsHostNetworkDesc = "hostnetwork allows using host networking and host ports but still requires pods to be run with a UID and SELinux context that are allocated to the namespace." // DescriptionAnnotation is the annotation used for attaching descriptions. DescriptionAnnotation = "kubernetes.io/description" ) // GetBootstrapSecurityContextConstraints returns the slice of default SecurityContextConstraints // for system bootstrapping. This method takes additional users and groups that should be added // to the strategies. Use GetBoostrapSCCAccess to produce the default set of mappings. func GetBootstrapSecurityContextConstraints(sccNameToAdditionalGroups map[string][]string, sccNameToAdditionalUsers map[string][]string) []kapi.SecurityContextConstraints { // define priorities here and reference them below so it is easy to see, at a glance // what we're setting var ( // this is set to 10 to allow wiggle room for admins to set other priorities without // having to adjust anyUID. securityContextConstraintsAnyUIDPriority = int32(10) ) constraints := []kapi.SecurityContextConstraints{ // SecurityContextConstraintPrivileged allows all access for every field { ObjectMeta: kapi.ObjectMeta{ Name: SecurityContextConstraintPrivileged, Annotations: map[string]string{ DescriptionAnnotation: SecurityContextConstraintPrivilegedDesc, }, }, AllowPrivilegedContainer: true, Volumes: []kapi.FSType{kapi.FSTypeAll}, AllowHostNetwork: true, AllowHostPorts: true, AllowHostPID: true, AllowHostIPC: true, SELinuxContext: kapi.SELinuxContextStrategyOptions{ Type: kapi.SELinuxStrategyRunAsAny, }, RunAsUser: kapi.RunAsUserStrategyOptions{ Type: kapi.RunAsUserStrategyRunAsAny, }, FSGroup: kapi.FSGroupStrategyOptions{ Type: kapi.FSGroupStrategyRunAsAny, }, SupplementalGroups: kapi.SupplementalGroupsStrategyOptions{ Type: kapi.SupplementalGroupsStrategyRunAsAny, }, SeccompProfiles: []string{"*"}, }, // SecurityContextConstraintNonRoot does not allow host access, allocates SELinux labels // and allows the user to request a specific UID or provide the default in the dockerfile. { ObjectMeta: kapi.ObjectMeta{ Name: SecurityContextConstraintNonRoot, Annotations: map[string]string{ DescriptionAnnotation: SecurityContextConstraintNonRootDesc, }, }, Volumes: []kapi.FSType{kapi.FSTypeEmptyDir, kapi.FSTypeSecret, kapi.FSTypeDownwardAPI, kapi.FSTypeConfigMap, kapi.FSTypePersistentVolumeClaim}, SELinuxContext: kapi.SELinuxContextStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy // will fail. Type: kapi.SELinuxStrategyMustRunAs, }, RunAsUser: kapi.RunAsUserStrategyOptions{ // This strategy requires that the user request to run as a specific UID or that // the docker file contain a USER directive. Type: kapi.RunAsUserStrategyMustRunAsNonRoot, }, FSGroup: kapi.FSGroupStrategyOptions{ Type: kapi.FSGroupStrategyRunAsAny, }, SupplementalGroups: kapi.SupplementalGroupsStrategyOptions{ Type: kapi.SupplementalGroupsStrategyRunAsAny, }, }, // SecurityContextConstraintHostMountAndAnyUID is the same as the restricted scc but allows the use of the hostPath and NFS plugins, and running as any UID. // Used by the PV recycler. { ObjectMeta: kapi.ObjectMeta{ Name: SecurityContextConstraintHostMountAndAnyUID, Annotations: map[string]string{ DescriptionAnnotation: SecurityContextConstraintHostMountAndAnyUIDDesc, }, }, Volumes: []kapi.FSType{kapi.FSTypeHostPath, kapi.FSTypeEmptyDir, kapi.FSTypeSecret, kapi.FSTypeDownwardAPI, kapi.FSTypeConfigMap, kapi.FSTypePersistentVolumeClaim, kapi.FSTypeNFS}, SELinuxContext: kapi.SELinuxContextStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy // will fail. Type: kapi.SELinuxStrategyMustRunAs, }, RunAsUser: kapi.RunAsUserStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy // will fail. Type: kapi.RunAsUserStrategyRunAsAny, }, FSGroup: kapi.FSGroupStrategyOptions{ Type: kapi.FSGroupStrategyRunAsAny, }, SupplementalGroups: kapi.SupplementalGroupsStrategyOptions{ Type: kapi.SupplementalGroupsStrategyRunAsAny, }, }, // SecurityContextConstraintHostNS allows access to everything except privileged on the host // but still allocates UIDs and SELinux. { ObjectMeta: kapi.ObjectMeta{ Name: SecurityContextConstraintHostNS, Annotations: map[string]string{ DescriptionAnnotation: SecurityContextConstraintHostNSDesc, }, }, Volumes: []kapi.FSType{kapi.FSTypeHostPath, kapi.FSTypeEmptyDir, kapi.FSTypeSecret, kapi.FSTypeDownwardAPI, kapi.FSTypeConfigMap, kapi.FSTypePersistentVolumeClaim}, AllowHostNetwork: true, AllowHostPorts: true, AllowHostPID: true, AllowHostIPC: true, SELinuxContext: kapi.SELinuxContextStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy // will fail. Type: kapi.SELinuxStrategyMustRunAs, }, RunAsUser: kapi.RunAsUserStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy // will fail. Type: kapi.RunAsUserStrategyMustRunAsRange, }, FSGroup: kapi.FSGroupStrategyOptions{ Type: kapi.FSGroupStrategyMustRunAs, }, SupplementalGroups: kapi.SupplementalGroupsStrategyOptions{ Type: kapi.SupplementalGroupsStrategyRunAsAny, }, }, // SecurityContextConstraintRestricted allows no host access and allocates UIDs and SELinux. { ObjectMeta: kapi.ObjectMeta{ Name: SecurityContextConstraintRestricted, Annotations: map[string]string{ DescriptionAnnotation: SecurityContextConstraintRestrictedDesc, }, }, Volumes: []kapi.FSType{kapi.FSTypeEmptyDir, kapi.FSTypeSecret, kapi.FSTypeDownwardAPI, kapi.FSTypeConfigMap, kapi.FSTypePersistentVolumeClaim}, SELinuxContext: kapi.SELinuxContextStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy // will fail. Type: kapi.SELinuxStrategyMustRunAs, }, RunAsUser: kapi.RunAsUserStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy // will fail. Type: kapi.RunAsUserStrategyMustRunAsRange, }, FSGroup: kapi.FSGroupStrategyOptions{ Type: kapi.FSGroupStrategyMustRunAs, }, SupplementalGroups: kapi.SupplementalGroupsStrategyOptions{ Type: kapi.SupplementalGroupsStrategyRunAsAny, }, // drops unsafe caps RequiredDropCapabilities: []kapi.Capability{"KILL", "MKNOD", "SYS_CHROOT", "SETUID", "SETGID"}, }, // SecurityContextConstraintsAnyUID allows no host access and allocates SELinux. { ObjectMeta: kapi.ObjectMeta{ Name: SecurityContextConstraintsAnyUID, Annotations: map[string]string{ DescriptionAnnotation: SecurityContextConstraintsAnyUIDDesc, }, }, Volumes: []kapi.FSType{kapi.FSTypeEmptyDir, kapi.FSTypeSecret, kapi.FSTypeDownwardAPI, kapi.FSTypeConfigMap, kapi.FSTypePersistentVolumeClaim}, SELinuxContext: kapi.SELinuxContextStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy // will fail. Type: kapi.SELinuxStrategyMustRunAs, }, RunAsUser: kapi.RunAsUserStrategyOptions{ Type: kapi.RunAsUserStrategyRunAsAny, }, FSGroup: kapi.FSGroupStrategyOptions{ Type: kapi.FSGroupStrategyRunAsAny, }, SupplementalGroups: kapi.SupplementalGroupsStrategyOptions{ Type: kapi.SupplementalGroupsStrategyRunAsAny, }, // prefer the anyuid SCC over ones that force a uid Priority: &securityContextConstraintsAnyUIDPriority, // drops unsafe caps RequiredDropCapabilities: []kapi.Capability{"MKNOD", "SYS_CHROOT"}, }, // SecurityContextConstraintsHostNetwork allows host network and host ports { ObjectMeta: kapi.ObjectMeta{ Name: SecurityContextConstraintsHostNetwork, Annotations: map[string]string{ DescriptionAnnotation: SecurityContextConstraintsHostNetworkDesc, }, }, AllowHostNetwork: true, AllowHostPorts: true, Volumes: []kapi.FSType{kapi.FSTypeEmptyDir, kapi.FSTypeSecret, kapi.FSTypeDownwardAPI, kapi.FSTypeConfigMap, kapi.FSTypePersistentVolumeClaim}, SELinuxContext: kapi.SELinuxContextStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy // will fail. Type: kapi.SELinuxStrategyMustRunAs, }, RunAsUser: kapi.RunAsUserStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy // will fail. Type: kapi.RunAsUserStrategyMustRunAsRange, }, FSGroup: kapi.FSGroupStrategyOptions{ Type: kapi.FSGroupStrategyMustRunAs, }, SupplementalGroups: kapi.SupplementalGroupsStrategyOptions{ Type: kapi.SupplementalGroupsStrategyMustRunAs, }, // drops unsafe caps RequiredDropCapabilities: []kapi.Capability{"KILL", "MKNOD", "SYS_CHROOT", "SETUID", "SETGID"}, }, } // add default access for i, constraint := range constraints { if usersToAdd, ok := sccNameToAdditionalUsers[constraint.Name]; ok { constraints[i].Users = append(constraints[i].Users, usersToAdd...) } if groupsToAdd, ok := sccNameToAdditionalGroups[constraint.Name]; ok { constraints[i].Groups = append(constraints[i].Groups, groupsToAdd...) } } return constraints } // GetBoostrapSCCAccess provides the default set of access that should be passed to GetBootstrapSecurityContextConstraints. func GetBoostrapSCCAccess(infraNamespace string) (map[string][]string, map[string][]string) { groups := map[string][]string{ SecurityContextConstraintPrivileged: {ClusterAdminGroup, NodesGroup}, SecurityContextConstraintsAnyUID: {ClusterAdminGroup}, SecurityContextConstraintRestricted: {AuthenticatedGroup}, } buildControllerUsername := serviceaccount.MakeUsername(infraNamespace, InfraBuildControllerServiceAccountName) pvRecyclerControllerUsername := serviceaccount.MakeUsername(infraNamespace, InfraPersistentVolumeRecyclerControllerServiceAccountName) users := map[string][]string{ SecurityContextConstraintPrivileged: {buildControllerUsername}, SecurityContextConstraintHostMountAndAnyUID: {pvRecyclerControllerUsername}, } return groups, users }