{"id":19759418,"url":"https://github.com/linuxacademy/webinar-automating-kubernetes-security","last_synced_at":"2025-06-20T11:39:34.128Z","repository":{"id":85209888,"uuid":"308656533","full_name":"linuxacademy/webinar-automating-kubernetes-security","owner":"linuxacademy","description":"Will Boyd 10.30.2020 ACG webinar","archived":false,"fork":false,"pushed_at":"2020-10-30T15:00:21.000Z","size":3,"stargazers_count":20,"open_issues_count":1,"forks_count":19,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-01-10T23:15:45.088Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/linuxacademy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-30T14:36:19.000Z","updated_at":"2023-11-20T21:37:36.000Z","dependencies_parsed_at":"2023-03-13T04:40:07.919Z","dependency_job_id":null,"html_url":"https://github.com/linuxacademy/webinar-automating-kubernetes-security","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linuxacademy%2Fwebinar-automating-kubernetes-security","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linuxacademy%2Fwebinar-automating-kubernetes-security/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linuxacademy%2Fwebinar-automating-kubernetes-security/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linuxacademy%2Fwebinar-automating-kubernetes-security/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/linuxacademy","download_url":"https://codeload.github.com/linuxacademy/webinar-automating-kubernetes-security/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241090461,"owners_count":19907957,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T03:29:19.322Z","updated_at":"2025-02-28T02:42:41.636Z","avatar_url":"https://github.com/linuxacademy.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Automating Kubernetes Security\n\nThis is a walkthrough guide for the live demo performed during the `Automating Kubernetes Security` webinar.\n\n## Cluster Setup\nSet up a Kubernetes cluster with `kubeadm`, or use an existing one.\n\nDemo environment info:\n- OS: `Ubuntu 18.04 Bionic Beaver LTS`\n- Container Runtime: `Docker 19.03.12`\n- Kubernetes version: `1.19.2`\n- Networking Plugin: `Calico`\n\n## Set Up a Namespace and Non-Admin ServiceAccount to Use for Testing\nCreate a Namespace.\n\n```\nkubectl create ns development\n```\n\nCreate the ServiceAccount.\n\n```\nkubectl create sa nonadmin -n development\n```\n\nCreate a RoleBinding allowing the account to edit objects in the `development` Namespace.\n\n```\nvi rb-nonadmin-edit.yml\n```\n\n```\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: rb-nonadmin-edit\n  namespace: development\nroleRef:\n  kind: ClusterRole\n  name: edit\n  apiGroup: rbac.authorization.k8s.io\nsubjects:\n- kind: ServiceAccount\n  name: nonadmin\n  namespace: development\n```\n\n```\nkubectl create -f rb-nonadmin-edit.yml --save-config\n```\n\nVerify that you can run commands as the `nonadmin` user. You should see the message `No resources found in development namespace.` since no Pods have been created in the Namespace.\n\n```\nkubectl --as=system:serviceaccount:development:nonadmin get pods -n development\n```\n\n## Create a PodSecurityPolicy\nCreate a new PodSecurityPolicy that will prevent pods from using privileged mode.\n\n```\nvi psp-nopriv.yml\n```\n\n```\napiVersion: policy/v1beta1\nkind: PodSecurityPolicy\nmetadata:\n  name: psp-nopriv\nspec:\n  privileged: false\n  runAsUser:\n    rule: RunAsAny\n  fsGroup:\n    rule: RunAsAny\n  seLinux:\n    rule: RunAsAny\n  supplementalGroups:\n    rule: RunAsAny\n  volumes:\n  - configMap\n  - downwardAPI\n  - emptyDir\n  - persistentVolumeClaim\n  - secret\n  - projected\n```\n\nCreate the PodSecurityPolicy.\n\n```\nkubectl create -f psp-nopriv.yml --save-config\n```\n\n## Set Up RBAC to Authorize the Use of the PodSecurityPolicy for a New ServiceAccount\nCreate a ClusterRole that allows the use of our PodSecurityPolicy.\n\n```\nvi cr-use-psp.yml\n```\n\n```\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: cr-use-psp\nrules:\n- apiGroups: ['policy']\n  resources: ['podsecuritypolicies']\n  verbs:     ['use']\n  resourceNames:\n  - psp-nopriv\n```\n\nCreate the ClusterRole.\n\n```\nkubectl create -f cr-use-psp.yml --save-config\n```\n\nCreate a ServiceAccount.\n\n```\nkubectl create sa nonprivileged -n development\n```\n\nCreate a RoleBinding that allows the `nonprivileged` ServiceAccount to use the PodSecurityPolicy in the `default` Namespace.\n\n```\nvi rb-nonprivileged.yml\n```\n\n```\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: rb-nonprivileged\n  namespace: development\nroleRef:\n  kind: ClusterRole\n  name: cr-use-psp\n  apiGroup: rbac.authorization.k8s.io\nsubjects:\n- kind: ServiceAccount\n  name: nonprivileged\n  namespace: development\n```\n\nCreate the RoleBinding.\n\n```\nkubectl create -f rb-nonprivileged.yml --save-config\n```\n\n## Turn on the PodSecurityPolicy Admission Controller\n\n```\nsudo vi /etc/kubernetes/manifests/kube-apiserver.yaml\n```\n\nLocate the line for the `--enable-admission-plugins` and add `PodSecurityPolicy` to the list.\n\n```\n- --enable-admission-plugins=NodeRestriction,PodSecurityPolicy\n```\n\nRun a command to make sure the API Server is still responding after the change to the manifest file (it may take a few moments to come back up).\n\n```\nkubectl get nodes\n```\n\n## Create a Pod\nCreate a basic Pod, using the `nonadmin` ServiceAccount created earlier.\n\n```\nvi pod-basic.yml\n```\n\n```\napiVersion: v1\nkind: Pod\nmetadata:\n  name: pod-basic\n  namespace: development\nspec:\n  containers:\n  - name: nginx\n    image: nginx\n```\n\n```\nkubectl create -f pod-basic.yml --as=system:serviceaccount:development:nonadmin --save-config\n```\n\nThis operation will fail, since the Pod does not have access to any PodSecurityPolicies that would allow it to be created.\n\nLet's try again, this time ensuring the Pod has access to our PodSecurityPolicy by giving it the `nonprivileged` ServiceAccount.\n\n```\nvi pod-with-psp-access.yml\n```\n\n```\napiVersion: v1\nkind: Pod\nmetadata:\n  name: pod-with-psp-access\n  namespace: development\nspec:\n  serviceAccountName: nonprivileged\n  containers:\n  - name: nginx\n    image: nginx\n```\n\n```\nkubectl create -f pod-with-psp-access.yml --as=system:serviceaccount:development:nonadmin --save-config\n```\n\nThis time, it should succeed since the Pod's ServiceAccount has access to the PodSecurityPolicy, and the Pod does not violate any policies.\n\nExamine the Pod with `kubectl describe`.\n\n```\nkubectl describe pod pod-with-psp-access -n development\n```\n\nNote that there an annotation which lists the PodSecurityPolicy that allowed the Pod.\n\nLet's try to create a Pod that does violate the policy by requesting privileged access.\n\n```\nvi pod-privileged.yml\n```\n\n```\napiVersion: v1\nkind: Pod\nmetadata:\n  name: pod-privileged\n  namespace: development\nspec:\n  serviceAccountName: nonprivileged\n  containers:\n  - name: nginx\n    image: nginx\n    securityContext:\n      privileged: true\n```\n\n```\nkubectl create -f pod-privileged.yml --as=system:serviceaccount:development:nonadmin --save-config\n```\n\nThis should fail, since the privileged mode containers are not allowed by the PodSecurityPolicy.\n\n## Fix Mirror Pod Creation for Static Pods\nList your system Pods.\n\n```\nkubectl get pods -n kube-system\n```\n\nYou may notice that the kube-apiserver mirror Pod is missing. While the API Server itself is in fact running since it is managed by kubelet and bypasses PodSecurityPolicies, the PodSecurityPolicies are preventing the mirror Pod from being created. This makes these system Pods invisible in the Kubernetes API. Let's fix it!\n\nCreate a new PodSecurityPolicy that will allow static mirror Pods.\n\n```\nvi psp-static.yml\n```\n\n```\napiVersion: policy/v1beta1\nkind: PodSecurityPolicy\nmetadata:\n  name: psp-static\nspec:\n  allowPrivilegeEscalation: true\n  fsGroup:\n    rule: RunAsAny\n  hostNetwork: true\n  runAsUser:\n    rule: RunAsAny\n  seLinux:\n    rule: RunAsAny\n  supplementalGroups:\n    rule: RunAsAny\n  volumes:\n  - configMap\n  - downwardAPI\n  - emptyDir\n  - persistentVolumeClaim\n  - secret\n  - projected\n  - hostPath\n```\n\n```\nkubectl create -f psp-static.yml --save-config\n```\n\nCreate a ClusterRole with access to the policy.\n\n```\nvi cr-use-psp-static.yml\n```\n\n```\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: cr-use-psp-static\nrules:\n- apiGroups: ['policy']\n  resources: ['podsecuritypolicies']\n  verbs:     ['use']\n  resourceNames:\n  - psp-static\n```\n\n```\nkubectl create -f cr-use-psp-static.yml --save-config\n```\n\nCreate a ClusterRoleBinding to allow Kubernetes Nodes to use the policy.\n\n```\nvi crb-use-psp-static.yml\n```\n\n```\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: crb-use-psp-static\nroleRef:\n  kind: ClusterRole\n  name: cr-use-psp-static\n  apiGroup: rbac.authorization.k8s.io\nsubjects:\n- kind: Group\n  name: system:nodes\n```\n\n```\nkubectl create -f crb-use-psp-static.yml --save-config\n```\n\nList system Pods again.\n\n```\nkubectl get pods -n kube-system\n```\n\nYou should see a `kube-apiserver` Pod appear. If it doesn't, you may need to wait a minute or two and try again.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinuxacademy%2Fwebinar-automating-kubernetes-security","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinuxacademy%2Fwebinar-automating-kubernetes-security","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinuxacademy%2Fwebinar-automating-kubernetes-security/lists"}