Kubernetes Security
Tags: rbac, admissioncontrol, networkpolicies, kuberentes
Published: 2023-11-19 19:15:05

In this post you are going to learn about the basics of the Kubernetes security. You will see how the "admission control" of the kube-apiserver works, how to authorize with RBAC and how to set network policies.

## Accessing the Kubernetes API
All requests that reach the API are encrypted using TLS,  therefore you need to configure SSL certificates or use `kubeadmin`

1. Authentication
2. Authorization
3. Admission Control

### Authentication

This is done with certificates, tokens or a basic authentication (username and password).

Users are not created by the API and should be managed by the operating system or an external server.
System accounts aka service accounts aka service principal are used by processes to access the API.

It can also be done with Webhooks, to verify bearer tokens or a connection with an external OpenId provider.

You define the type of authentication in the `kube-apiserver` startup options and select the authenticator module:
`--basic-auth-file`
`--oidc-issuer-url`
`--token-auth-file`
`--authorization-webhook-config-file`


If one or more Authenticator Modules are used, each is tried until successful, and the order is not guaranteed. 
Anonymous access can also be enabled, otherwise you will get a 401 response. 

### Authorization
There are three main modules for Authorization
Node: is needed for the kubelet to communicate with the kube-apiserver
RBAC - Role Bases Access Control: All non kubelet traffic would be checked by RBAC, if set
Webhook:All non kubelet traffic would be checked by RBAC, if set

You can configure them in the kube-apiserver startup options
`--authorization-mode=Node,RBAC`

The attributes of the request are checked agains the policies like (user, usergroup, namespace, http verbs).
To see the authorization information of a cluster run
`kubectl config get-contexts`

#### RBAC - Role Based Access Control

All resources are modelled API objects in Kubernetes.

##### API Groups
These resources belong to API groups, like core and apps. They allow HTTP verbs like POST, GET, PUT, DELETE.
RBAC settings are additive, with no permission allowed unless defined.

**Rules** - Rules can act upon an API group.
**Roles** - One or more rules with affect a scope of a single namespace.
**ClusterRoles** - Scoped for the entire cluster.


### Admission Control
Admission controllers intercept and modify requests.
They can modify the content or validate it, and potentially deny the request.
`--enable-admission-plugins=NamespaceLifecycle,LimitRanger`
`--disable-admission-plugins=PodNodeSelector`

## Security Contexts
This is a Kubernetes object that defines privileges and access control settings for a Pod or a container inside a Pod. Below you can find the most used security context options.

### RunAsUser
Specifies the user or group ID under which the process should run inside the container. This helps to isolate processes and restrict their access.
### Privileged
If set to true, the container gains access to all Linux capabilities, effectively turning off all isolation between the host and the container. Using privileged mode should be done cautiously, as it can introduce security risks.
### ReadOnlyRootFilesystem
When set to true, the container's root file system is mounted as read-only. This provides an additional layer of security by preventing processes within the container from writing to the root file system.
### Capabilities:
Allows you to add or remove specific Linux capabilities for processes within the container. This provides fine-grained control over what the processes are allowed to do.
```
apiVersion: v1
kind: Pod
metadata:
  name: yourpod
spec:
  containers:
  - name: yourcontainer
    image: yourimage
    securityContext:
      runAsUser: 1000 // user id, default is 0, which is the root user
      capabilities:
        add: ["NET_ADMIN"]
      readOnlyRootFilesystem: true
```

If the security context is set wrong, you will see an warning in the status of your pods.

### PodSecurity Admission Controllers
PodSecurity admission controllers are part of the built-in set of admission controllers in Kubernetes.
You can define policies on different levels and customize them as needed.
They are part of the Admission Control Framework.
They are designed to be compatible with a variety of container runtimes.
You can set it in the cluster configuration. 

```
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
apiServer:
  extraArgs:
    enable-admission-plugins: "PodSecurity,PodNodeSelector"
```

and use the policy like:

```
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restrictive
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  volumes:
    - 'configMap'
    - 'emptyDir'
  hostNetwork: false
  hostIPC: false
  hostPID: false
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'RunAsAny'
```

## Network Security Policies
By default, all pods can reach each other all ingress and egress traffic is allowed. This has been a high-level networking requirement in Kubernetes. But the ingress and egress trafic can be controlled by a policy. The network policy.

### Network Policy Sample
```
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: ingress-egress-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policy types:
    - Ingress
    - Egress
  ingress:
    - from:
        - ipBlock:
            cidr: 172.17.0.0/16
            except:
              - 172.17.1.0/24
        - namespaceSelector:
            matchLabels:
              project: yourproject
        - podSelector:
            matchLabels:
              role: frontend
      ports:
        - protocol: TCP
          port: 6379
  egress:
    - to:
        - ipBlock:
            cidr: 10.0.0.0/24
      ports:
        - protocol: TCP
          port: 5978

```

#### Default Network Policy
The empty braces in the below example match all Pods, that are not selected by another Network Policy and will not allow ingress traffic. 
```
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress
```

Further reading:
[Controlling Access to Kubernetes API](https://kubernetes.io/docs/concepts/security/controlling-access/)
[What is TLS](https://www.internetsociety.org/deploy360/tls/basics/)
[Configure Service Accounts](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/)
[Dynamic Admission Control](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/)
[Network Policy Recipes](https://github.com/ahmetb/kubernetes-network-policy-recipes)