5 Commits

Author SHA1 Message Date
Nemo b9057e3bb3 Update '01-AUTH.md' 3 years ago
Nemo 0fd8b51be9 . 3 years ago
Nemo 99c1adface notes 3 years ago
Nemo af828af2f3 Adds refs 3 years ago
Nemo 68cf900e1c Adds links 3 years ago
  1. 10
      01-AUTH.md
  2. 5
      02-NETPOL.md
  3. 2
      03-CIS.md
  4. 27
      04-CONTEXTS.md
  5. 27
      05-PSP.md
  6. 9
      BEST.md
  7. 4
      README.md
  8. 8
      resources/alpine-privileged.yml
  9. 28
      resources/attacker.yaml
  10. 17
      resources/psp-example.yml
  11. 48
      resources/psp.yml
  12. 8
      webhook/svc.yml
  13. 21
      webhook/validating-webhook-configuration.yaml

10
01-AUTH.md

@ -15,11 +15,11 @@
Try by running the following commands:
`kubectl config view`
`kubectl cluster-info`
`kubectl proxy`
`minikube dashboard --url`
`kube auth can-i [verb] [resource]`
- `kubectl config view`
- `kubectl cluster-info`
- `kubectl proxy`
- `minikube dashboard --url`
- `kube auth can-i [verb] [resource]`
Try figuring out what command line flags the minikube
server was started with and use that to figure out what

5
02-NETPOL.md

@ -4,6 +4,11 @@
- Have `kubectl` working against minikube
## References
- https://kubernetes.io/docs/concepts/services-networking/network-policies/
- https://speakerdeck.com/alp/kubernetes-network-policies
# Setup
1. Bring up a new redis server in the `default` namespace

2
03-CIS.md

@ -1,6 +1,6 @@
# CIS Benchmark
1. Get the PDF from https://goo.gl/437pqY
1. Get the PDF from https://git.captnemo.in/attachments/1a66cb8f-14d5-4ecd-8d6a-7054e05143e8
2. Understand how it works
# Run it

27
04-CONTEXTS.md

@ -0,0 +1,27 @@
# security contexts
## References:
- https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
- https://kubernetes.io/docs/concepts/policy/pod-security-policy/
## What to do
1. Create the `attacker.yaml` deployment
2. Go through the https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ task
Skip the bitmasks, but try different flags in the security context and update the deployment to see
what happens with various options.
Try atleast the following:
```
allowPrivilegeEscalation: true
privileged: true
# cd to /dev/ and see after this
readOnlyRootFilesystem: true
# try writing to / after this
runAsGroup
runAsNonRoot
runAsUser
```

27
05-PSP.md

@ -0,0 +1,27 @@
# Pod Security Policy
## References
- https://kubernetes.io/docs/concepts/policy/pod-security-policy/#what-is-a-pod-security-policy
- https://docs.bitnami.com/kubernetes/how-to/secure-kubernetes-cluster-psp/
```bash
# start minikube with PodSecurityPolicy enabled
minikube start --extra-config=apiserver.GenericServerRunOptions.AdmissionControl=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds,PodSecurityPolicy
```
Go through the example reference at https://kubernetes.io/docs/concepts/policy/pod-security-policy/#example:
```bash
# Set up a namespace and a service account to act as for this example. We’ll use this service account to mock a non-admin user.
kubectl create namespace psp-example
kubectl create serviceaccount -n psp-example fake-user
kubectl create rolebinding -n psp-example fake-editor --clusterrole=edit --serviceaccount=psp-example:fake-user
# To make it clear which user we’re acting as and save some typing, create 2 aliases:
alias kubectl-admin='kubectl -n psp-example'
alias kubectl-user='kubectl --as=system:serviceaccount:psp-example:fake-user -n psp-example'
# Create a policy and a pod (see link for file)
kubectl-admin create -f example-psp.yaml
```

9
BEST.md

@ -0,0 +1,9 @@
# Admission Controllers
## References:
- https://kubernetes.io/docs/admin/admission-controllers/#podsecuritypolicy
## Pod Security Policy
`kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/docs/concepts/policy/restricted-psp.yaml`

4
README.md

@ -2,4 +2,6 @@
Workshop material for the talk.
**Open https://k8s.bb8.fun for the slides.**
**Open https://k8s.bb8.fun for the slides.**
This is the code part of the talk, available at https://git.captnemo.in/nemo/kubernetes-security

8
resources/busybox.yml → resources/alpine-privileged.yml

@ -1,14 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: alpine
name: attacker-pod-privileged
namespace: attacker
spec:
containers:
- image: alpine:3.6
- image: redis:alpine
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
name: alpine
name: attacker-pod
securityContext:
runAsUser: 1000
restartPolicy: Always

28
resources/attacker.yaml

@ -0,0 +1,28 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
name: attacker-abc
name: attacker-abc
namespace: attacker
spec:
progressDeadlineSeconds: 600
replicas: 1
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
name: attacker-abc
spec:
containers:
- image: alpine:3.6
name: attacker-abc
command:
- sleep
- "3600"
securityContext:
privileged: true

17
resources/psp-example.yml

@ -0,0 +1,17 @@
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: example
spec:
privileged: false # Don't allow privileged pods!
# The rest fills in some required fields.
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
volumes:
- '*'

48
resources/psp.yml

@ -0,0 +1,48 @@
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default'
apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'
apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
spec:
privileged: false
# Required to prevent escalations to root.
allowPrivilegeEscalation: false
# This is redundant with non-root + disallow privilege escalation,
# but we can provide it for defense in depth.
requiredDropCapabilities:
- ALL
# Allow core volume types.
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
# Assume that persistentVolumes set up by the cluster admin are safe to use.
- 'persistentVolumeClaim'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
# Require the container to run without root privileges.
rule: 'MustRunAsNonRoot'
seLinux:
# This policy assumes the nodes are using AppArmor rather than SELinux.
rule: 'RunAsAny'
supplementalGroups:
rule: 'MustRunAs'
ranges:
# Forbid adding the root group.
- min: 1
max: 65535
fsGroup:
rule: 'MustRunAs'
ranges:
# Forbid adding the root group.
- min: 1
max: 65535
readOnlyRootFilesystem: false

8
webhook/svc.yml

@ -0,0 +1,8 @@
kind: "Service"
apiVersion: "v1"
metadata:
name: "kib"
spec:
type: ExternalName
externalName: kib.bb8.fun
selector: {}

21
webhook/validating-webhook-configuration.yaml

@ -0,0 +1,21 @@
apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ExternalAdmissionHookConfiguration
metadata:
name: image-bouncer-webook
externalAdmissionHooks:
- name: image-bouncer-webhook.suse.nue.com
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
resources:
- pods
failurePolicy: Ignore
clientConfig:
caBundle: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR6RENDQXJTZ0F3SUJBZ0lVVFA3WVZsZm9IazJiR1RHR3BmZEE4QnFwb1lzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2ZqRUxNQWtHQTFVRUJoTUNSRVV4RWpBUUJnTlZCQWdUQ1VaeVlXNWpiMjVwWVRFU01CQUdBMVVFQnhNSgpUblZ5WlcxaVpYSm5NUTB3Q3dZRFZRUUtFd1JUVlZORk1Rd3dDZ1lEVlFRTERBTlNKa1F4S2pBb0JnTlZCQU1UCklXbHRZV2RsTFdKdmRXNWpaWEl0ZDJWaWFHOXZheTVrWldaaGRXeDBMbk4yWXpBZUZ3MHhPREF4TWpReE56UTEKTURCYUZ3MHlNekF4TWpNeE56UTFNREJhTUg0eEN6QUpCZ05WQkFZVEFrUkZNUkl3RUFZRFZRUUlFd2xHY21GdQpZMjl1YVdFeEVqQVFCZ05WQkFjVENVNTFjbVZ0WW1WeVp6RU5NQXNHQTFVRUNoTUVVMVZUUlRFTU1Bb0dBMVVFCkN3d0RVaVpFTVNvd0tBWURWUVFERXlGcGJXRm5aUzFpYjNWdVkyVnlMWGRsWW1odmIyc3VaR1ZtWVhWc2RDNXoKZG1Nd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURzWE1iS0czcjI4NVpsWmdqOApLa2doTGd2TTAyaGJUWUY5dzdwd05GWHdDSXVtTmRnaEUvcHh3NmVUdkxpZW1YTlRvL1VEaGpqZ3JoK292ZGcvCnpoQ0xzKy91UUpxUDY4UU14TUxlMGxMYnRIYkhjZkJ2OGZEdDM5TTBsS1ZBdmRORER2WTVoUkhvVWxGcExZMlYKSmtvUmRTUVNoeFBHK0ZJdWhwUGtIM29NZGtIRFlETjhKVTBsV3hWWStqd2VkY3dOM3R2RDRUb0ZJb3VTYkdNRwprVGQ0VXhDa2R5TVI4dnlzMms1VWxwMmY3RW9qRXIvTTJKVzhZOVU2MGJnS29RZnJUTzJhWWoweTdGUllTVUt6CmtUTUpHMjBNcC9ubFM3eWF5SjVzTVlwdHRUUGcyVFRiRkpKR1Jvc2JQNWdJeDdoRThveURjblFvb1pjWkFuVWcKUHJyZEFnTUJBQUdqUWpCQU1BNEdBMVVkRHdFQi93UUVBd0lCQmpBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUIwRwpBMVVkRGdRV0JCUlVISlNoN3dZTnQwWVA2UzNUdWZ2eWRac2hZakFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBCmJJOFZKNU8vTVNxU2dKM0dMZjNJc2l3Z01BNStOVDQ5QUxVcVdtS2hjTGpjTFZodE1UNFRab2Zrc2tGajBUbFMKTy9ZL0R5NHB3QmlJeG5aaS9aemc3SDhHTmpEb1V1Q2VYYUxwYTJDeTJrcUdNc25LQXc0R1NwbXB3WDFGQkJGRgprUDZXTjJBUUxjaDZzWGFSNTE0ZHRVTmgxZUJMT0xNZHFmR1M5RC9UVnI5NjhvcDVCbW5QSGJSSXljNnlLcENHCjh1M2VicE1JWmNGanVrNm40Y092MFZkYldXWlNEWGhwbWh5alBKSmxXc0Vib3dZQjdpWllLajJoMmMxcmhRcDcKaS8vRjBHWjQzdjNWak8vb05haHg5Q2NRSU52WlVwWFd3aWRkUHd5OG04OE5HcjF3ZGo0MEozOHR2emN3Nm5vTAppeTNzZ0hubHp6a2RMM0E0NEx5ekFRPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
service:
name: kib
namespace: default
Loading…
Cancel
Save