Platform9 Blog

How to Implement PCI Requirement Of “Data Encryption In Flight” In Kubernetes Clusters

As I talk with customers and prospects that are interested in  Platform9 Managed Kubernetes offering, PCI requirements come up frequently.  One critical PCI requirement is data encryption in flight within the Kubernetes cluster.  This blog is a guided tutorial on exactly how to implement data encryption within a k8s cluster using Calico and WireGuard on top of Platform9’s free tier.

Installation

Create a PMK Cluster

The following values were used to create a PMK Cluster:

Create a PMK Cluster

Create a PMK Cluster

Once that we have our PMK Cluster up and running, only two steps are required to enable wireguard on a Kubernetes cluster, WireGuard at OS level & WireGuard at Kubernetes, let’s go through each of these steps.

WireGuard at OS (CentOS 7 in this example)

Let’s install the prerequisites needed according to your operating system on each of the nodes forming your PMK cluster this involves masters and workers, let’s follow the next link https://www.wireguard.com/install, reboot your nodes as necessary according to the packages altered, in this environment we are using Centos 7.

$ sudo yum install epel-release elrepo-release
$ sudo yum install yum-plugin-elrepo
$ sudo yum install kmod-wireguard wireguard-tools

WireGuard at Kubernetes

In order to enable Wireguard at our PMK cluster, we should patch the Calico Felix configuration right after our nodes have the wireguard packages installed at the O.S level

To patch the Felix configuration you will need to leverage on calicoctl binary, this binary needs a kubeconfig file to work properly, by default Platform9 ships this binary in the master nodes, you just need to create a folder structure for calico and provide a kubeconfig file, Platform9 also provides an internal admin kubeconfig for other internal purposes to demonstrate the WireGuard feature you can leverage on the next steps to achieve it.

NOTE: calicoctl can also be used outside the cluster as long as you provide a kubeconfig file that targets your PMK cluster.

Create calico folder path

[root@master00 ~]# mkdir /etc/calico

Create Calico configuration file

[root@master00 ~]# cat <<'EOF' > /etc/calico/calicoctl.cfg
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
  datastoreType: "kubernetes"
  kubeconfig: "/etc/pf9/kube.d/kubeconfigs/admin.yaml"
EOF

Now Let’s patch the felixconfiguration to enable WireGuard across all the clusters:

[root@master00 ~]# /opt/pf9/pf9-kube/bin/calicoctl patch felixconfiguration default --type='merge' -p '{"spec":{"wireguardEnabled":true}}'

Testing

Let’s validate that Public Keys have been generated on each of our nodes, by running the following command

$ calicoctl get node <NODE-NAME> -o yaml
 ...
 status:
   ...
   wireguardPublicKey: jlkVyQYooZYzI2wFfNhSZez5eWh44yfq1wKVjLvSXgY=
   ...

Let’s deploy a couple of test pods to validate that east-west traffic is being encrypted, in this environment, we will be using the following manifests as the pods originating and receiving the traffic.

Deploy some pods that we will use to generate traffic from the CentOS pods towards the Nginx pods.

[root@master00 ~]# cat << 'EOF' > wireguard-deploy-pf9.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wireguard-test-deploy
spec:
  replicas: 4
  selector:
    matchLabels:
     app: wireguard
  template:
    metadata:
      labels:
        app: wireguard
    spec:
      containers:
      - name: pf9-tooler
        image: docker.io/centos/tools:latest
        command:
          - /sbin/init
EOF
[root@master00 ~]# kubectl apply -f wireguard-deploy-pf9.yaml

Deploy some nginx pods that will receive the traffic from the centos pods.

[root@master00 ~]# cat << 'EOF' > nginx-deploy-pf9.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 4 # tells deployment to run 4 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
EOF
[root@master00 ~]# kubectl apply -f nginx-deploy-pf9.yaml

Generate some traffic from the centos-tool(wireguard-test-deploy) pod towards the Nginx over port 80 via a watch curl command.

These are the two pods participating in the traffic:

wireguard-test-deploy-f7985fcdf-mcz2p   1/1     Running   0          13m    10.20.115.9     192.168.50.55   <none>           <none>

nginx-deployment-66b6c48dd5-fd7k2       1/1     Running   3          5d2h   10.20.246.118   192.168.50.53   <none>           <none>

The centOS (wireguard-test-deployment) pod is in worker 192.168.50.55

The Nginx pod is in worker 192.168.50.53

Let’s login inside the centos pod, and generate traffic against Pod’s IP 10.20.246.118

[root@master00 ~]# kubectl exec -it wireguard-test-deploy-f7985fcdf-mcz2p -- bash
[root@wireguard-test-deploy-f7985fcdf-mcz2p /]# watch curl -n 0.1 10.20.246.118

Log into one of the workers that are participating in this communication and confirm via the wg command that packet transfer is increasing over the encrypted session, wg command is present on each of our nodes as a result of installing WireGuard packages, let’s do a watch with the default time so you can see how the received encrypted traffic is increasing over time.

[root@worker02 ~]# watch wg
Every 2.0s: wg                                                                                                                                                                          Tue Apr  6 20:57:57 2021interface: wireguard.cali
public key: Vg1/L/b9jGIPixk6p0H9/bDkNK3l9sDyDvJSYx85LgU=
private key: (hidden)
listening port: 51820
fwmark: 0x40000peer: TDtpx4DNBAIg9dJ5dtt2lECeg4iIJurt3ZMYLbUZliQ=
endpoint: 192.168.50.59:51820
allowed ips: 10.20.178.12/32, 10.20.178.0/26
latest handshake: 23 seconds ago
transfer: 436.28 KiB received, 439.27 KiB sentpeer: MPkoh0erajxIBylgx48mJOidNyzxUhYTCjOg9DO7r3k=
endpoint: 192.168.50.55:51820
allowed ips: 10.20.115.0/26, 10.20.115.28/32
latest handshake: 1 minute, 44 seconds ago
transfer: 1.50 MiB received, 4.05 MiB sent

We can also validate by tcpdump for port 80 on the external interface of your worker node where traffic is flowing and you shouldn’t be able to see any port 80 traffic at all since this is encrypted.

Install tcpdump in case it is not installed in your O.S

[root@worker02 ~]# yum install tcpdump -y
[root@worker02 ~]# tcpdump -i eth0 -nn port 80 -vvv
<EMPTY>

Lastly, if you desire to disable WireGuard encryption, this action can be performed in a declarative way, lets disable WireGuard encryption while we are still hitting our Nginx Pod and sniffing for port 80, you should be able to see now port 80 traffic flowing.

[root@master00 ~]# calicoctl patch felixconfiguration default --type='merge' -p '{"spec":{"wireguardEnabled":false}}'
[root@worker01 ~]# tcpdump -i eth0 -nn port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
21:17:10.529020 IP 10.20.115.9.39636 > 10.20.246.118.80: Flags [S], seq 4249531524, win 28000, options [mss 1400,sackOK,TS val 8444466 ecr 0,nop,wscale 7], length 0
21:17:10.529455 IP 10.20.246.118.80 > 10.20.115.9.39636: Flags [S.], seq 763109226, ack 4249531525, win 27760, options [mss 1400,sackOK,TS val 8443383 ecr 8444466,nop,wscale 7], length 0
21:17:10.529966 IP 10.20.115.9.39636 > 10.20.246.118.80: Flags [.], ack 1, win 219, options [nop,nop,TS val 8444467 ecr 8443383], length 0

Let’s enable WireGuard back in our cluster so our east-west traffic is encrypted.

[root@master00 ~]# calicoctl patch felixconfiguration default --type='merge' -p '{"spec":{"wireguardEnabled":true}}'

That’s all folks!

Benefits

Calico + WireGuard on Platform9 Managed Kubernetes provides an easy declarative way to encrypt data in-flight for east-west traffic in Kubernetes environments.

Conclusion

Platform9’s customers need to tackle the encryption challenge for data in flight for PCI compliance.  The blog illustrates that by leveraging Platform9 Managed Kubernetes, calico, and WireGuard just how easily this can be accomplished.  While this is only one of the steps for hardening a k8s cluster it is of critical importance and can be easily accomplished.

You may also enjoy

SELinux, Kubernetes RBAC, and Shipping Security Policies for On-prem Applications

By Jay Vyas

Why and How to Run Machine Learning Workloads on Kubernetes

By Platform9

The browser you are using is outdated. For the best experience please download or update your browser to one of the following: