Published on 00/00/0000
Last updated on 00/00/0000
Published on 00/00/0000
Last updated on 00/00/0000
Share
Share
9 min read
Share
istio-init
to create iptables rules before the other containers in the pod can start. This requires the user, or service-account that's deploying pods in the mesh, to have sufficient privileges to deploy containers with NET_ADMIN
capability - a kernel capability that allows the reconfiguration of networks. In general, we want to avoid giving application pods this capability.
CNI (Container Network Interface), a Cloud Native Computing Foundation project, consists of a specification and libraries for writing plugins to configure network interfaces in Linux containers, along with a number of supported plugins.The Istio CNI plugin replaces the
istio-init
container, which provides the same functionality, but without requiring Istio users to enable elevated privileges. It performs traffic redirection in the setup phase of the Kubernetes pod's lifecycle, thereby removing the NET_ADMIN
capability requirement for users deploying pods to the mesh.
For a more detailed explanation on how Istio CNI works, check out our Enhancing Istio service mesh security with a CNI plugin blog post.
Pod Security Policies provide fine-grained authorization for pod creation.Let's try to quickly summarize how they work:
Note: You must enable the PSP admission controller in your Kubernetes cluster to use PSPs.
This is the gist of PSPs, but you can find a more in-depth explanation of how they work in an earlier blog post, which includes working examples and a detailed list of the security aspects used to constrain them: An illustrated deepdive into Pod Security Policies.
istiod
was introduced. Per that release, SDS was also simplified and the NodeAgent
component began to undergo deprecation. Istio 1.6 continued to make architectural changes by removing all the legacy control plane components. With these alterations, by the time of Istio 1.6's release, there were many fewer control plane components to secure.
In the meantime, further efforts were made to run the remaining components without root privileges (e.g. root port ranges and root file paths ceased to be used). Let's take a look at the remaining Istio components in Istio 1.6.
istiod
istio-coredns
istio-telemetry
istio-policy
istio-proxy
sidecar containeristio-gateway
deployments without root privileges.
Instead of the istio-init
container, the Istio CNI plugin can be used in such a way that the NET_ADMIN
capability can be dropped.
These are the bare minimum privileges necessary for the remaining components. Let's take a look at how we can enforce them with PSPs.
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: psp-restricted
spec:
allowPrivilegeEscalation: false
forbiddenSysctls:
- "*"
fsGroup:
ranges:
- max: 65535
min: 1
rule: MustRunAs
requiredDropCapabilities:
- ALL
runAsUser:
rule: MustRunAsNonRoot
runAsGroup:
rule: MustRunAs
ranges:
- min: 1
max: 65535
seLinux:
rule: RunAsAny
supplementalGroups:
ranges:
- max: 65535
min: 1
rule: MustRunAs
volumes:
- configMap
- emptyDir
- projected
- secret
- downwardAPI
- persistentVolumeClaim
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: psp-host
spec:
allowPrivilegeEscalation: true
fsGroup:
rule: RunAsAny
hostNetwork: true
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- secret
- configMap
- emptyDir
- hostPath
All the necessary resources, including Roles and RoleBindings, for this setup can be found in the Banzai Cloud Istio operator repo, here.
$ gcloud beta container clusters create psp-demo --enable-network-policy --enable-pod-security-policy --cluster-version=1.16.9-gke.2 --node-version=1.16.9-gke.2 --num-nodes=5
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
psp-demo europe-west1-b 1.16.9-gke.2 35.187.123.4 n1-standard-1 1.16.9-gke.2 5 RUNNING
kustomization.yaml
file with the following content in any directory:
bases:
- github.com/banzaicloud/istio-operator/config?ref=release-1.6
- github.com/banzaicloud/istio-operator/config/overlays/psp?ref=release-1.6
$ kubectl apply -k .
namespace/istio-system created
customresourcedefinition.apiextensions.k8s.io/istios.istio.banzaicloud.io created
customresourcedefinition.apiextensions.k8s.io/meshgateways.istio.banzaicloud.io created
customresourcedefinition.apiextensions.k8s.io/remoteistios.istio.banzaicloud.io created
role.rbac.authorization.k8s.io/istio-operator-psp-host created
role.rbac.authorization.k8s.io/istio-operator-psp-restricted created
clusterrole.rbac.authorization.k8s.io/istio-operator-manager-role created
rolebinding.rbac.authorization.k8s.io/istio-operator-psp-host created
rolebinding.rbac.authorization.k8s.io/istio-operator-psp-restricted created
clusterrolebinding.rbac.authorization.k8s.io/istio-operator-manager-rolebinding created
service/istio-operator-controller-manager-service created
statefulset.apps/istio-operator-controller-manager created
podsecuritypolicy.policy/istio-operator-psp-host created
podsecuritypolicy.policy/istio-operator-psp-restricted created
Note: If you don't want to use Kustomize, you can deploy the operator through whichever documented method you prefer, and then you can create your own PSP resources tailored to your specific needs.
$ kubectl -n istio-system apply -f https://raw.githubusercontent.com/banzaicloud/istio-operator/release-1.6/config/samples/istio_v1beta1_istio_cni_gke.yaml
istio.istio.banzaicloud.io/istio-sample created
$ kubectl get po -n=istio-system
NAME READY STATUS RESTARTS AGE
istio-cni-node-8kxsm 2/2 Running 0 3m3s
istio-cni-node-jx7k6 2/2 Running 0 3m2s
istio-cni-node-mqgkn 2/2 Running 0 3m3s
istio-cni-node-pdz5q 2/2 Running 0 3m3s
istio-cni-node-zp98z 2/2 Running 0 3m2s
istio-ingressgateway-5c5b6c7fdd-bqwn7 1/1 Running 0 2m32s
istio-operator-controller-manager-0 1/1 Running 0 11m
istiod-76fb86d68f-tf5rv 1/1 Running 0 3m4s
istio-ingressgateway
pod as root:
kubectl patch istio -n istio-system istio-sample --type=json -p='[{"op": "replace", "path": "/spec/gateways/ingress/runAsRoot", "value":true}]'
istio-ingressgateway
pod is unable start:
$ kubectl get po -n=istio-system -l app=istio-ingressgateway
NAME READY STATUS RESTARTS AGE
istio-ingressgateway-5c5b6c7fdd-bqwn7 1/1 Running 0 3m32s
istio-ingressgateway-5d979f4dd4-jqlgq 0/1 CreateContainerConfigError 0 106s
$ kubectl describe po -n=istio-system -l app=istio-ingressgateway
Warning Failed 6s (x10 over 118s) kubelet, gke-psp-demo-default-pool-7528dec2-kww1 Error: container has runAsNonRoot and image will run as root
runAsRoot
flag back to false
so that we can proceed with our demonstration:
kubectl patch istio -n istio-system istio-sample --type=json -p='[{"op": "replace", "path": "/spec/gateways/ingress/runAsRoot", "value":false}]'
bookinfo-psp.yaml
:
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: istio
spec:
fsGroup:
rule: RunAsAny
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: istio
rules:
- apiGroups:
- policy
resourceNames:
- istio
resources:
- podsecuritypolicies
verbs:
- use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: istio-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: istio
subjects:
- kind: ServiceAccount
name: bookinfo-productpage
namespace: default
- kind: ServiceAccount
name: bookinfo-details
namespace: default
- kind: ServiceAccount
name: bookinfo-ratings
namespace: default
- kind: ServiceAccount
name: bookinfo-reviews
namespace: default
kubectl apply -f bookinfo-psp.yaml
podsecuritypolicy.policy/istio created
clusterrole.rbac.authorization.k8s.io/istio created
clusterrolebinding.rbac.authorization.k8s.io/istio-user created
kubectl -n default apply -f https://raw.githubusercontent.com/istio/istio/release-1.6/samples/bookinfo/platform/kube/bookinfo.yaml
kubectl -n default apply -f https://raw.githubusercontent.com/istio/istio/release-1.6/samples/bookinfo/networking/bookinfo-gateway.yaml
INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
open http://$INGRESS_HOST/productpage
kubectl -n default delete -f https://raw.githubusercontent.com/istio/istio/release-1.6/samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl -n default delete -f https://raw.githubusercontent.com/istio/istio/release-1.6/samples/bookinfo/platform/kube/bookinfo.yaml
kubectl -n default delete -f bookinfo-psp.yaml
kubectl -n istio-system delete -f https://raw.githubusercontent.com/banzaicloud/istio-operator/release-1.6/config/samples/istio_v1beta1_istio_cni_gke.yaml
kubectl delete -k .
Get emerging insights on emerging technology straight to your inbox.
Discover why security teams rely on Panoptica's graph-based technology to navigate and prioritize risks across multi-cloud landscapes, enhancing accuracy and resilience in safeguarding diverse ecosystems.
The Shift is Outshift’s exclusive newsletter.
Get the latest news and updates on cloud native modern applications, application security, generative AI, quantum computing, and other groundbreaking innovations shaping the future of technology.