Skip to content

Commit

Permalink
[PSS] Add script for migrating a cluster from PSP to PSS (#6952) (#6959)
Browse files Browse the repository at this point in the history
The script migrate_cluster_psp_to_pss.sh has two modes of operation:

 * check: will check whether there are pods that violate the PSS
 "baseline" profile. It's useful to see where the security policy can
 be tightened from the default "privileged" profile.
 * migrate: will perform the migration on the current K8s context.
 --policy-version should specify the target policy version, usually
 the same version as the K8s cluster.

The migration works in two phases:

1. Disabling PodSecurityPolicy

 * create an allow-everything security policy
 * create a rolebinding that binds each namespace service account
 to the security policy newly created. this effectively disables the
 PodSecurityPolicy admission controller

2. Enabling Pod Security Standards

* enforce the "privileged" profile on all namespaces
* warn & audit violations of the "baseline" profile

Example usage:

$ ./migrate_cluster_psp_to_pss.sh --policy-version=v1.25 check

$ ./migrate_cluster_psp_to_pss.sh --policy-version=v1.25 migrate

If unspecified, the default target policy version is "v1.24".
  • Loading branch information
sionescu authored Mar 7, 2023
1 parent d0f791e commit 1aa86fa
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 0 deletions.
123 changes: 123 additions & 0 deletions terraform/scripts/migrate_cluster_psp_to_pss.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/usr/bin/env bash

function msg() {
if [[ ${VERBOSE} == true ]]; then
echo ${@} 2>&1
fi
}

function disable_psp_ns () {
local _ns=${1}
msg "Disabling PodSecurityPolicy on namespace ${_ns}"
kubectl delete -n "${_ns}" rolebinding disable-psp 2>/dev/null
kubectl create -n "${_ns}" rolebinding disable-psp \
--clusterrole privileged-psp --group "system:serviceaccounts:${_ns}"
}

function set_pss_label() {
local _ns=${1}
local _policy=${2}
msg "Namespace ${_ns}: setting policy ${_policy}"
kubectl label --overwrite ns "${_ns}" "${_policy}"
}

function set_pss_labels_ns() {
local _ns=${1}
set_pss_label "${_ns}" "pod-security.kubernetes.io/enforce=privileged"
set_pss_label "${_ns}" "pod-security.kubernetes.io/enforce-version=${POLICY_VERSION}"
set_pss_label "${_ns}" "pod-security.kubernetes.io/warn=baseline"
set_pss_label "${_ns}" "pod-security.kubernetes.io/warn-version=${POLICY_VERSION}"
set_pss_label "${_ns}" "pod-security.kubernetes.io/audit=baseline"
set_pss_label "${_ns}" "pod-security.kubernetes.io/audit-version=${POLICY_VERSION}"
}

function list_ns() {
kubectl get ns | grep Active | awk '{ print $1 }'
}

function migrate() {
msg "Creating resource PodSecurityPolicy/privileged-psp"
local scriptdir=$(dirname $(readlink -f ${0}))
kubectl apply -f "${scriptdir}"/privileged-psp.yaml

msg "Creating role 'privileged-psp'"
kubectl delete clusterrole privileged-psp 2>/dev/null
kubectl create clusterrole privileged-psp \
--verb use --resource podsecuritypolicies --resource-name privileged-psp

local _ns
for _ns in $(list_ns); do
disable_psp_ns "${_ns}"
set_pss_labels_ns "${_ns}" "${POLICY_VERSION}"
done
}

POLICY_VERSION=v1.24
VERBOSE=false
DEBUG=false
cmd=""

optspec="h-:"
while getopts "$optspec" optchar; do
case "${optchar}" in
-)
case "${OPTARG}" in
debug)
DEBUG=true
set +x
;;
verbose)
VERBOSE=true
;;
policy-version=*)
val=${OPTARG#*=}
opt=${OPTARG%=$val}
POLICY_VERSION=${val}
;;
*)
if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" != ":" ]; then
echo "Unknown option --${OPTARG}" >&2
fi
;;
esac;;
*)
echo "Unknown argument: '-${OPTARG}'" >&2
exit 2
;;
esac
done
shift $((OPTIND -1))

case $# in
0)
cmd="usage"
;;
1)
cmd=${1}
;;
*)
echo "Too many parameters on the command line" >&2
exit 2
;;
esac

case ${cmd} in
usage)
echo "Usage: $(basename ${0}) [--verbose] [--debug] [--policy-version=<value>] check | migrate" >&2
echo "Default PSS policy version: ${POLICY_VERSION}" >&2
exit 1
;;
check)
echo "Hint: you can get the list of labels with kubectl get ns --show-labels"
kubectl label --dry-run=server \
--overwrite ns --all \
pod-security.kubernetes.io/enforce=baseline
;;
migrate)
migrate
;;
*)
echo "Unknown command:" ${cmd}
exit 2
;;
esac
27 changes: 27 additions & 0 deletions terraform/scripts/privileged-psp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: privileged-psp
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
spec:
privileged: true
allowPrivilegeEscalation: true
allowedCapabilities:
- '*'
volumes:
- '*'
hostNetwork: true
hostPorts:
- min: 0
max: 65535
hostIPC: true
hostPID: true
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'

0 comments on commit 1aa86fa

Please sign in to comment.