[//]: # (Confidential document)
[//]: # (01/05/2025)
[//]: # (v 1.7.3)

# Kubernetes  labs v1.7.3 - Security

## Security :   RBAC


Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within your organization.

RBAC authorization uses the rbac.authorization.k8s.io API group to drive authorization decisions, allowing you to dynamically configure policies through the Kubernetes API.

To enable RBAC, start the API server with the --authorization-mode flag set to a comma-separated list that includes RBAC; 


## Lab1: RBAC

  - Create 
	- Namespace
	- Service Account
	- long-lived API token for a ServiceAccount
	- Role
	- RoleBinding
 - Get Roles, RoleBinding
 - Describe Roles
 - Check access using auth can-i 


```bash
kubectl create -f manifests/rbac.yaml
kubectl get ServiceAccount -n rbac
kubectl get Roles -n rbac
kubectl get RoleBinding -n rbac
kubectl describe Roles -n rbac
kubectl auth can-i get pods --as=system:serviceaccount:rbac:dev-service-account
kubectl auth can-i get cm --as=system:serviceaccount:rbac:dev-service-account
kubectl auth can-i get cm --as=system:serviceaccount:rbac:dev-service-account -n rbac
```

## Lab2: Kubeconfig

  - Generate Kubeconfig
    Usage ./kubeconfig.sh ( namespace ) ( service account name ) ( secret name )
```
dos2unix manifests/kubeconfig.sh
chmod +x manifests/kubeconfig.sh
./manifests/kubeconfig.sh rbac dev-service-account dev-secret
kubectl --kubeconfig=kubeconfig-rbac get po
kubectl --kubeconfig=kubeconfig-rbac get cm 
kubectl --kubeconfig=kubeconfig-rbac get cm  -n rbac

kubectl delete -f manifests/rbac.yaml

```

## Lab3: Token

The token is a JSON Web Token (JWT), encoded as base64 as specified in the JWT RFC.
jwt.io is a useful tool to decode JWT. 

  - Generate Token
  - Manually create an API token for a ServiceAccount
```
kubectl run --restart=Never busybox -it --image=busybox --rm --quiet -- \
cat /var/run/secrets/kubernetes.io/serviceaccount/token

```

## Secuirty :  Network Policies

Network Policies are an application-centric construct which allow you to specify how a pod is allowed to communicate with various network "entities over the network. 
Network Policies apply to a connection with a pod on one or both ends, and are not relevant to other connections.

By default, if no policies exist in a namespace, then all ingress and egress traffic is allowed to and from pods in that namespace. 

## Lab4: Network Policies

 - DENY all traffic to an application
    - Run a pod
    - Test connectivity from another pod (Traffic is allowed)
    - Apply deny all policy
    - Test connectivity from another pod (Traffic dropped!)
 - ALLOW all traffic to an application
    - Run a pod
    - Apply allow all policy
    - Test con nectivity from another pod (Traffic is allowed)
- LIMIT traffic to an application
    - Run a pod with labels
    - Apply limit traffic policy
    - Test connectivity from another pod (Traffic dropped!)
    - Test connectivity from another pod with app=bookstore & role=frontend labels (Traffic is allowed)
 - DENY all non-whitelisted traffic to a namespace
    - Run a pod
    - Apply limit traffic policy
    - Test connectivity from another pod in the same ns (Traffic dropped!)
    - Test connectivity from another pod in another ns (Traffic dropped!)
  - DENY all traffic from other namespaces
    - Run a pod
    - Apply limit traffic policy
    - Test connectivity from another pod in another ns (Traffic dropped!)
    - Test connectivity from another pod in the same ns (Traffic is allowed)
  - ALLOW traffic to an application from all namespaces
    - Run a pod
    - Apply limit traffic policy
    - Test connectivity from another pod in another ns (Traffic is allowed)
  - ALLOW all traffic from a namespace
    - Run a pod
    - Apply limit traffic policy
    - Test connectivity from another pod in dev ns (Traffic dropped!)
    - Test connectivity from another pod in prod ns (Traffic is allowed)
  - ALLOW traffic from some pods in another namespace
    - Run a pod
    - Apply limit traffic policy
    - Test connectivity from another pod in same ns (Traffic dropped!)
    - Test connectivity from another pod with labels type=monitoring in dev ns (Traffic dropped!)
    - Test connectivity from another pod in other ns (Traffic dropped!)
    - Test connectivity from another pod with labels type=monitoring in ns other   (Traffic is allowed)
	
```
kubectl run web --image=nginx --labels app=web --expose --port 80
kubectl run --rm -i -t --image=alpine test-wget -- sh
# wget -qO- http://web
 
kubectl apply -f manifests/web-deny-all.yaml

kubectl run --rm -i -t --image=alpine test-wget -- sh
# wget -qO- --timeout=2 http://web

kubectl delete po,service web
kubectl delete networkpolicy web-deny-all
-----

kubectl run web --image=nginx --labels=app=web --expose --port 80
kubectl apply -f manifests/web-allow-all.yaml
kubectl run test-wget --rm -i -t --image=alpine -- sh
# wget -qO- --timeout=2 http://web

kubectl delete po,service web
kubectl delete networkpolicy web-allow-all
-----

kubectl run apiserver --image=nginx --labels app=bookstore,role=api --expose --port 80
kubectl apply -f manifests/api-allow.yaml

kubectl run test-wget --rm -i -t --image=alpine -- sh
# wget -qO- --timeout=2 http://apiserver

kubectl run test-wget --rm -i -t --image=alpine --labels app=bookstore,role=frontend -- sh
# wget -qO- --timeout=2 http://apiserver

kubectl delete po,service apiserver
kubectl delete networkpolicy api-allow
-----

kubectl run apiserver --image=nginx --labels app=api --expose --port 80
kubectl apply -f manifests/default-deny-all.yaml

kubectl run test-wget --rm -i -t --image=alpine --labels app=bookstore -- sh
# wget -qO- --timeout=2 http://apiserver

kubectl create namespace other
kubectl run test-wget --rm -i -t --image=alpine --namespace=other -- sh
# wget -qO- --timeout=2 http://apiserver.default
 
kubectl delete po,service apiserver
kubectl delete networkpolicy default-deny-all
kubectl delete namespace other
-----

kubectl create namespace secondary
kubectl run web --namespace secondary --image=nginx --labels=app=web --expose --port 80
kubectl apply -f manifests/deny-from-other-namespaces.yaml
kubectl run test-wget --namespace=default --rm -i -t --image=alpine -- sh
# wget -qO- --timeout=2 http://web.secondary

kubectl run test-wget --namespace=secondary --rm -i -t --image=alpine -- sh
# wget -qO- --timeout=2 http://web.secondary

kubectl delete po,service web -n secondary
kubectl delete networkpolicy deny-from-other-namespaces -n secondary
kubectl delete namespace secondary
-----

kubectl create namespace secondary
kubectl run web --image=nginx --namespace secondary  --labels=app=web --expose --port 80
kubectl apply -f manifests/web-allow-all-namespaces.yaml

kubectl run test-wget --namespace=default --rm -i -t --image=alpine -- sh
# wget -qO- --timeout=2 http://web.secondary

kubectl delete po,service web -n secondary
kubectl delete networkpolicy web-allow-all-namespaces -n secondary
kubectl delete namespace secondary
-----

kubectl run web --image=nginx --labels=app=web --expose --port 80
		
kubectl create namespace dev
kubectl label namespace/dev purpose=testing

kubectl create namespace prod
kubectl label namespace/prod purpose=production

kubectl apply -f manifests/web-allow-prod.yaml

kubectl run test-wget --namespace=dev --rm -i -t --image=alpine -- sh
# wget -qO- --timeout=2 http://web.default

kubectl run test-wget --namespace=prod --rm -i -t --image=alpine -- sh
# wget -qO- --timeout=2 http://web.default

kubectl delete networkpolicy web-allow-prod
kubectl delete po,service web
kubectl delete namespace prod
kubectl delete namespace dev
-----

kubectl run web --image=nginx  --labels=app=web --expose --port 80
kubectl create namespace other
kubectl label namespace/other team=operations
kubectl apply -f manifests/web-allow-all-ns-monitoring.yaml

kubectl run test-wget --rm -i -t --image=alpine -- sh
# wget -qO- --timeout=2 http://web.default
 
kubectl run test-wget --labels type=monitoring --rm -i -t --image=alpine -- sh
# wget -qO- --timeout=2 http://web.default
 
$ kubectl run test-wget --namespace=other --rm -i -t --image=alpine -- sh
# wget -qO- --timeout=2 http://web.default
 
kubectl run test-wget --namespace=other --labels type=monitoring --rm -i -t --image=alpine -- sh
# wget -qO- --timeout=2 http://web.default
 
kubectl delete networkpolicy web-allow-all-ns-monitoring
kubectl delete namespace other
kubectl delete po,service web
-----
```

## Clean up
```
kubectl delete -f ./manifests
```