Encrypt in-cluster pod traffic


Big picture

Enable WireGuard to secure on-the-wire, in-cluster pod traffic in a Calico cluster.


When this feature is enabled, Calico automatically creates and manages WireGuard tunnels between nodes providing transport-level security for on-the-wire, in-cluster pod traffic. WireGuard provides formally verified secure and performant tunnels without any specialized hardware. For a deep dive in to WireGuard implementation, see this whitepaper.


This how-to guide uses the following Calico features:

  • Felix configuration resource with WireGuard configuration parameters

Before you begin…

  • Install and configure calicoctl
  • Verify the operating system(s) running on the nodes in the cluster support WireGuard.
  • WireGuard in Calico requires node IP addresses to establish secure tunnels between nodes. Calico can automatically detect IP address of a node using IP Setting and IP autodetection method in calico/node resource.
    • Set IP (or IP6) environment variable to autodetect.
    • Set IP_AUTODETECTION_METHOD (or IP6_AUTODETECTION_METHOD) to an appropriate value. If there are multiple interfaces on a node, set the value to detect the IP address of the primary interface.

Note: WireGuard in Calico does not support IPv6 at this time. Also, encryption using WireGuard is not supported on managed Kubernetes platforms which don’t use Calico CNI (e.g. managed Kubernetes platforms EKS, and GKE). WireGuard is supported when using Azure CNI on AKS, and on this platform will encrypt not just pod-to-pod traffic but host-to-host traffic as well.

How to

Install WireGuard

WireGuard is included in Linux 5.6+ kernels, and has been backported to earlier Linux kernels in some Linux distributions.

Install WireGuard on cluster nodes using instructions for your operating system. Note that you may need to reboot your nodes after installing WireGuard to make the kernel modules available on your system.

Use the following instructions for these operating systems that are not listed on the WireGuard installation page.

To install WireGuard on the default Amazon Machine Image (AMI):

   sudo yum install kernel-devel-`uname -r` -y
   sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm -y
   sudo curl -o /etc/yum.repos.d/jdoss-wireguard-epel-7.repo https://copr.fedorainfracloud.org/coprs/jdoss/wireguard/repo/epel-7/jdoss-wireguard-epel-7.repo
   sudo yum install wireguard-dkms wireguard-tools -y

AKS cluster nodes currently run Ubuntu with a kernel that has WireGuard installed already, so there is no manual installation required.

To install WireGuard for OpenShift v4.8:

  1. Install requirements:
  2. Download and configure the tools needed for kmods.
       FAKEROOT=$(mktemp -d)
       git clone https://github.com/tigera/kmods-via-containers
       cd kmods-via-containers
       make install FAKEROOT=${FAKEROOT}
       cd ..
       git clone https://github.com/tigera/kvc-wireguard-kmod
       cd kvc-wireguard-kmod
       make install FAKEROOT=${FAKEROOT}
       cd ..
  3. Configure/edit ${FAKEROOT}/root/etc/kvc/wireguard-kmod.conf.

    a. You must then set the URLs for the KERNEL_CORE_RPM, KERNEL_DEVEL_RPM and KERNEL_MODULES_RPM packages in the conf file $FAKEROOT/etc/kvc/wireguard-kmod.conf. Obtain copies for kernel-core, kernel-devel, and kernel-modules rpms from RedHat Access and host it in an http file server that is reachable by your OCP workers.

    b. For more details and help about configuring kvc-wireguard-kmod/wireguard-kmod.conf, see the kvc-wireguard-kmod README file. Notes about wireguard version to kernel version compatibility is also available there.

  4. Get RHEL Entitlement data from your own RHEL8 system from a host in your cluster.
    tar -czf subs.tar.gz /etc/pki/entitlement/ /etc/rhsm/ /etc/yum.repos.d/redhat.repo

    Please refer to Openshift documentation for more information about these entitlement files.

  5. Copy the subs.tar.gz file to your workspace and then extract the contents using the following command.
    tar -x -C ${FAKEROOT}/root -f subs.tar.gz
  6. Transpile your machine config using CoreOS Butane.
    cd kvc-wireguard-kmod
    make ignition FAKEROOT=${FAKEROOT} > mc-wg.yaml
  7. With the KUBECONFIG set for your cluster, run the following command to apply the MachineConfig which will install WireGuard across your cluster.
    oc create -f mc-wg.yaml

Enable WireGuard for a cluster

Note: Nodes that do not support WireGuard will not be secured by WireGuard tunnels, even if traffic running on the node to and from the pods goes to nodes that do support WireGuard.

Enable WireGuard encryption across all the nodes using the following command.

calicoctl patch felixconfiguration default --type='merge' -p '{"spec":{"wireguardEnabled":true}}'

For OpenShift, add the Felix configuration with WireGuard enabled under custom resources.

Note: The above command can be used to change other WireGuard attributes. For a list of other WireGuard parameters and configuration evaluation, see the Felix configuration.

We recommend that you review and modify the MTU used by Calico networking when WireGuard is enabled to increase network performance. Follow the instructions in the Configure MTU to maximize network performance guide to set the MTU to a value appropriate for your network.

Disable WireGuard for an individual node

To disable WireGuard on a specific node with WireGuard installed, modify the node-specific Felix configuration. e.g., to turn off encryption for pod traffic on node my-node, use the following command:

cat <<EOF | kubectl apply -f -
apiVersion: projectcalico.org/v3
kind: FelixConfiguration
  name: node.my-node
  logSeverityScreen: Info
  reportingInterval: 0s
  wireguardEnabled: false

With the above command, Calico will not encrypt any of the pod traffic to or from node my-node.

To enable encryption for pod traffic on node my-node again:

calicoctl patch felixconfiguration node.my-node --type='merge' -p '{"spec":{"wireguardEnabled":true}}'

Verify configuration

To verify that the nodes are configured for WireGuard encryption, check the node status set by Felix using calicoctl. For example:

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

Disable WireGuard for a cluster

To disable WireGuard on all nodes modify the default Felix configuration. For example:

  calicoctl patch felixconfiguration default --type='merge' -p '{"spec":{"wireguardEnabled":false}}'

Above and beyond