What you can’t do with Kubernetes network policies (unless you use Calico): TLS Encryption

Kubernetes documentation clearly defines what use cases you can achieve using Kubernetes network policies and what you can’t. You are probably familiar with the scope of network policies and how to use them to secure your workload from undesirable connections. Although it is possible to cover the basics with Kubernetes native network policies, there is a list of use cases that you cannot implement by just using these policies. You can refer to the Kubernetes documentation to review the list of “What you can’t do with network policies (at least, not yet)”.

Here are some of the use cases that you cannot implement using only the native Kubernetes network policy API (transcribed from the Kubernetes documentation):

  • Forcing internal cluster traffic to go through a common gateway.
  • Anything TLS related.
  • Node specific policies.
  • Creation or management of “Policy requests” that are fulfilled by a third party.
  • Default policies which are applied to all namespaces or pods.
  • Advanced policy querying and reachability tooling.
  • The ability to log network security events.
  • The ability to explicitly deny policies.
  • The ability to prevent loopback or incoming host traffic (Pods cannot currently block localhost access, nor do they have the ability to block access from their resident node).

In this multi-part blog series, we will address the user stories explaining why it is essential to protect your environment and how you can implement them using Calico. In my previous blog, What you can’t do with Kubernetes network policies (unless you use Calico), we talked about use case number one—forcing internal cluster traffic to go through a common gateway. In this blog post, we’ll be focusing on use case number two—anything TLS related.

Use case: Anything TLS related

Calico is known for containers and Kubernetes security, and specifically, securing workload communications, which involves the effective utilization of Kubernetes Network Policy. This feature serves as a means to safeguard containerized workloads by limiting the flow of traffic exclusively to and from trusted origins. By doing so, it becomes possible to exercise control over the traffic. Nonetheless, despite this control, the traffic itself is susceptible to interception.

To address this issue, a prevalent solution involves encrypting the traffic at the application layer through protocols such as Transport Layer Security (TLS). Alternatively, encryption can be applied at a lower infrastructure level using IPsec. However, these methods introduce an extra layer of complexity. Calico, on the other hand, effectively tackles this challenge by employing WireGuard to implement encryption for data during transit. By leveraging WireGuard, Calico manages to mitigate the need for added complexity.

WireGuard operates as a module within the Linux kernel, offering enhanced performance and reduced power consumption compared to IPsec and OpenVPN tunneling protocols. In line with this, Calico incorporates WireGuard to support encryption for both IPv4 and IPv6 traffic. This encryption functionality can be enabled separately for each protocol, allowing Calico to automatically generate and manage WireGuard tunnels between nodes. Consequently, this ensures transport-level security for inter-node communication and in-cluster pod traffic within the Calico environment.

WireGuard ensures secure encapsulation of IP packets over UDP. Central to WireGuard is the concept of Cryptokey Routing, which involves associating public keys with a designated set of tunnel IP addresses permitted within the tunnel. Every network interface of a node possesses a private key and a roster of peers (other nodes). Each node is assigned a public key, which serves as a concise and straightforward means for mutual authentication between nodes. In the context of Calico, a WireGuard interface is incorporated on each node, configured with the private key and the public keys of other nodes. This facilitates the transmission of packets across the interface, ensuring a secure communication channel.

To get started, it is necessary to have a Kubernetes cluster with WireGuard installed on the host operating system.You can refer to the WireGuard website for a comprehensive list of supported operating systems and installation instructions. Keep in mind that once WireGuard is installed, you may need to reboot your machines to ensure the necessary kernel modules are accessible. It’s worth noting that some node operating systems may not support WireGuard or may not have it pre-installed. Enabling Calico WireGuard encryption does not mandate that all nodes have WireGuard installed. However, it’s important to acknowledge that traffic to or from a node without WireGuard installed will not be encrypted.

Enable WireGuard in a cluster

To activate WireGuard encryption for IPv4 on all nodes, you can utilize the wireguardEnabled: true parameter. Likewise, for IPv6 encryption, you can employ the wireguardEnabledV6: true parameter. If you wish to enable encryption for both IPv4 and IPv6, you can use both parameters simultaneously. Additionally, you have the flexibility to modify other WireGuard attributes as needed. For a comprehensive list of available WireGuard parameters and configuration assessment, you can refer to the Felix configuration. This will provide you with detailed information on how to customize and optimize your WireGuard settings within the Calico environment.

It’s important to note that by default, the natOutgoing parameter is set to true for the default IPv4 IP pool. However, for IPv6, this parameter is not automatically enabled. It’s worth mentioning that WireGuard requires natOutgoing to be enabled for both IPv4 and IPv6. Therefore, when utilizing IPv6 WireGuard, it is necessary to enable NAT outgoing for the IPv6 IP pools explicitly. This ensures proper functionality and compatibility between WireGuard and IPv6 within your Calico configuration.

We highly recommend reviewing and adjusting the Maximum Transmission Unit (MTU) utilized by Calico networking when WireGuard is enabled. This adjustment is crucial to enhance network performance. To achieve optimal results, please refer to the Configure MTU to maximize network performance guide, which provides step-by-step instructions on how to set the MTU to a value that is suitable for your specific network environment. By configuring the MTU appropriately, you can ensure efficient and high-performance networking within your Calico deployment.

Verify that encryption is enabled

When WireGuard is enabled, an annotation with the WireGuard public key is created on each node of the cluster. You can run the following command to verify that the WireGuard public key was successfully created:

> k get nodes -o yaml | grep annotation -A 5
    annotations:
      csi.volume.kubernetes.io/nodeid: '{"csi.www.tigera.io":"aks-nodepool1-23148925-vmss000000","disk.csi.azure.com":"aks-nodepool1-23148925-vmss000000","file.csi.azure.com":"aks-nodepool1-23148925-vmss000000"}'
      node.alpha.kubernetes.io/ttl: "0"
      projectcalico.org/WireguardPublicKey: ORo21+69byn6YHC0pX3Fgq9G1Q+y7hP/e3EkKIclUlY=
      volumes.kubernetes.io/controller-managed-attach-detach: "true"
    creationTimestamp: "2023-05-11T15:23:48Z"
--
    annotations:
      csi.volume.kubernetes.io/nodeid: '{"csi.www.tigera.io":"aks-nodepool1-23148925-vmss000001","disk.csi.azure.com":"aks-nodepool1-23148925-vmss000001","file.csi.azure.com":"aks-nodepool1-23148925-vmss000001"}'
      node.alpha.kubernetes.io/ttl: "0"
      projectcalico.org/WireguardPublicKey: Z8kiiLl5d9eZsAuTe38nSha2vCZ6VTwsqU6j6F/+d3I=
      volumes.kubernetes.io/controller-managed-attach-detach: "true"
    creationTimestamp: "2023-05-11T15:24:07Z"

Once the WireGuard is enabled, you will be able to see the statistics on Calico Cloud’s dashboard. For this, log in to the Calico Cloud and go to the Dashboard. The WireGuard graphics can be found at the bottom of the dashboard, but you can optionally reorganize it.

What traffic will be encrypted?

Although WireGuard is commonly associated with client/server VPN setups, it can be effectively configured and utilized in a peer-to-peer mesh architecture as well. This is precisely how Calico is designed to operate within a Kubernetes environment. With Calico, all nodes that have WireGuard enabled will establish peering connections with each other, forming an encrypted mesh network. Notably, Calico also supports traffic flow within a cluster where some nodes have WireGuard enabled while others do not. This flexibility allows for seamless integration and operation in mixed environments, ensuring secure communication across your Kubernetes cluster.

Our objective in utilizing WireGuard was to prioritize simplicity, security, and speed when encrypting data in transit within a Kubernetes cluster. It doesn’t rely on mTLS or IPsec, eliminating the need for complex configuration requirements. In essence, WireGuard can be viewed as an additional overlay network with the added advantage of built-in encryption. By incorporating WireGuard, Calico ensures that data transmission remains secure while maintaining a straightforward and efficient approach to encryption within the Kubernetes environment.

 

The following diagram illustrates different scenarios of packet flow within a cluster when WireGuard is enabled. It showcases the various paths and interactions that occur between nodes, highlighting how encrypted packets are transmitted and received throughout the network. By visualizing these packet flow scenarios, it becomes easier to understand the communication patterns and the role of WireGuard in securing data transmission within the cluster.

Pods on the same host:

  • Packets are routed to the WireGuard table.
  • When the destination IP address corresponds to a pod located on the same host, Calico takes a specific approach. It inserts a “throw” entry into the WireGuard routing table, which essentially directs the packet back to the main routing table. From there, the packet is routed to the interface associated with the host side of the veth (virtual Ethernet) pair linked to the target pod. It’s important to note that in this scenario, the packet flows in an unencrypted manner, as it doesn’t require encryption for communication within the same host (shown in blue on the diagram).

Pods on different nodes:

  • Packets are directed to the WireGuard table.
  • A routing entry is matched for the destination pod IP and sent to the WireGuard device wireguard.cali.
  • WireGuard device encrypts (shown in red on the diagram) and encapsulates the packet, and sets a fwmark to prevent routing loops.
  • WireGuard device encrypts the packet with the public key of the peer it matches for the destination podIP (allowed IP), encapsulates it in UDP, and marks it with a special fwmark to prevent routing loops.
  • The packet is sent through the network interface card to the destination node, where the reverse process happens.
  • This also works for host traffic (for example, host-networked pods).

Conclusion

In this blog post, we explored the integration of WireGuard into Calico, a powerful security feature for securing container workloads in Kubernetes clusters. WireGuard stands out for its simplicity, superior performance, and low power consumption compared to other tunneling protocols. With Calico’s implementation of WireGuard, container traffic can be encrypted and secured, providing a robust layer of protection.

Calico also takes advantage of WireGuard’s peer-to-peer mesh architecture, enabling nodes with WireGuard enabled to form an encrypted network. Even in clusters with a mix of nodes, where some have WireGuard enabled and others do not, Calico ensures seamless traffic flow with appropriate encryption.

By leveraging WireGuard in Calico, users benefit from a simple, secure, and efficient solution for encrypting data in transit within Kubernetes clusters. WireGuard acts as an overlay network, seamlessly integrating encryption capabilities without the complexity of mTLS or IPsec.

The integration of WireGuard into Calico empowers users to achieve secure and efficient encryption of container traffic in Kubernetes clusters. With its simplicity, performance, and compatibility advantages, WireGuard in Calico offers a streamlined solution for ensuring data confidentiality and integrity within containerized environments.

In the next blog of this series, we will address node-specific policy limitations for native Kubernetes network policies and show how Calico can automatically create host endpoints for your Kubernetes nodes. This means Calico can manage the lifecycle of host endpoints as your cluster evolves, ensuring nodes are always protected by a network policy. Stay tuned!

Ready to try Calico encryption with WireGuard? Sign up for a free trial of Calico Cloud

Join our mailing list

Get updates on blog posts, workshops, certification programs, new releases, and more!

X