Security on Kubernetes

SecurityContext

A SecurityContext defines privilege and access control settings for Pods or
containers and can include the following:

  • UID- and GID-based Discretionary Access Control
  • SELinux security labels
  • Linux Capabilities
  • AppArmor
  • Seccomp
  • The AllowPrivilegeEscalation setting
  • The runAsNonRoot setting

Setting SecurityContext

  • kubectl apply -f security-context.yaml
  • kubectl get pod security-context-demo
  • kubectl exec -it security-context-demo -- sh
    • ps # will show processes running UID 1000
    • cd /data; ls -l # will show fsGroup as owning GID
    • id
    • exit

 

Kubernetes Users

  • The Kubernetes API doesn’t define users for people to authenticate and
    authorize
  • Users are obtained externally
    • Defined by X.509 certificates
    • Obtained from external OpenID-based authentication (Google, AD and many more)
  • ServiceAccounts are used to authorize Pods to get access to specific API resources

 

Configuring Roles

  • Roles are used on Namespaces and use Verbs to specify access to specific
    resources in that Namespace
  • Use kubectl create role to create roles

 

Creating RoleBindings

  • RoleBindings connect users or ServiceAccounts to Roles
  • Use kubectl create rolebinding to create it

 

Creating ServiceAccounts

  • A ServiceAccount is used to authorize Pods to get information from the API
  • All Pods have a default ServiceAccount which provides minimal access
  • If more access is needed, specific ServiceAccounts can be created
  • ServiceAccounts don’t have specific configuration, they are used in RoleBindings to get access to specific Roles

Configuring ServiceAccounts

1. Create a Pod, using the standard ServiceAccount: kubectl apply -f
mypod.yaml

2. Use kubectl get pods mypod -o yaml to check current SA configuration

3. Access the Pod using kubectl exec -it mypod -- sh, try to list Pods using curl on the API:

1. apk add --update curl
2. curl https://kubernetes/api/v1 --insecure  # will be forbidden

4. Use the Default ServiceAccount token and try again:

1. TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token)
2. curl -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1/ --insecure

5. Try the same, but this time to list Pods – it will fail:

1. curl -H "Authorization: Bearer $TOKEN"https://kubernetes/api/v1/namespaces/default/pods/ --insecure

Configuring ServiceAccounts

1. Create a ServiceAccount: kubectl apply -f mysa.yaml

2. Define a role that allows to list all Pods in the default NameSpace: kubectl apply -f list-pods.yaml

3. Define a RoleBinding that binds the mysa to the Role just created: kubectl apply -f list-pods-mysa-binding.yaml

4. Create a Pod that uses the mysa SA to access this Role: kubectl apply -f mysapod.yaml

5. Access the Pod, use the mysa ServiceAccount token and try again:

1. apk add --update curl
2. TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token)
3. curl -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1/ --insecure

6. Try the same, but this time to list Pods:

1. curl -H "Authorization: Bearer $TOKEN"https://kubernetes/api/v1/namespaces/default/pods/ --insecure

We see above very simple mysa ServiceAccount definition and very simple role list-pods. This role is providing access to list pods.

The namespace of role binding is default. The subject is SA mysa and namespace default.

 

ClusterRoles

  • Roles have a Namespace scope, ClusterRoles apply to the entire cluster
  • The working is similar to the working of Roles
  • To provide access to ClusterRoles, use users or ServiceAccounts and provide access through a ClusterRoleBinding

 

User Accounts

  • Kubernetes has no User objects
  • User accounts consist of an authorized certificate that is completed with some authorization as defined in RBAC
  • To create a user account, the following steps need to be performed
    • Create a public/private key pair
    • Create a Certificate Signing Request
    • Sign the Certificate
    • Create a configuration file that uses these keys to access the K8s clust
    • Create an RBAC Role
    • Create an RBAC RoleBinding

Creating User Accounts

Step 1: Create a user working environment

    • kubectl create ns students
    • kubectl create ns staff
    • kubectl config get-contexts

Step 2: Create the User account

  • sudo useradd -m -G sudo -s /bin/bash anna
  • sudo passwd anna
  • su - anna
  • openssl genrsa -out anna.key 2048# Generating private key
  • openssl req -new -key anna.key -out anna.csr -subj "/CN=anna/O=k8s" # certificate signing request
  • sudo openssl x509 -req -in anna.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out anna.crt -days 1800 # kubernetes CA need to sign the signing request

Step 3: Update the Kubernetes Credentials Files for the new user

    • mkdir /home/anna/.kube
    • sudo cp -i /etc/kubernetes/admin.conf /home/anna/.kube/config
    • sudo chown -R anna:anna /home/anna/.kube
    • kubectl config set-credentials anna --client-certificate=/home/anna/anna.crt --client-key=/home/anna/anna.key

Step 4: Create a Default Context for the new user

    • kubectl config set-context anna-context --cluster=kubernetes \
      --namespace=staff --user=anna
    • kubectl config use-context anna-context # will set context permanently
    • kubectl get pods # will fail as no RBAC has been configured yet
    • kubectl config get-contexts

Step 5: Configure RBAC to define a staff role

    • su - student
    • vim staff-role.yaml
    • kubectl apply -f staff-role.yaml

Step 6: Bind a user to the new role

    • vim rolebind.yaml
    • kubectl apply -f rolebind.yaml

Step 7: Test it

    • su - anna; kubectl config view
    • kubectl create deployment nginx --image=nginx
    • kubectl get pods

Step 8: Create a View-only Role

    • su - student
    • vim students-role.yaml
    • vim rolebindstudents.yaml
    • kubectl apply -f students-role.yaml
    • kubectl apply -f rolebindstudents.yaml

Lab: Managing Security

  • Create a Role that allows for viewing of pods in the default namespace
  • Configure a RoleBinding that allows all authenticated users to use this role