Kubernetes network security foundations: Get started on building your Kubernetes network security policies with Calico!

The adoption of cloud native applications has become a necessity for organizations to run their businesses efficiently. As per Gartner, more than 85% of organizations will embrace a cloud-first principle by 2025, which will rely on adopting cloud native applications for complete execution. The massive increase in adoption of cloud native applications has given  rise to more security challenges such as container image vulnerabilities, configuration errors and a larger runtime attack surface. Kubernetes has become the de facto standard platform to host and run cloud native applications. However, as Kubernetes adoption gains momentum, so does the security risk associated with business-critical applications that communicate with multiple external and internal systems. Kubernetes network security is a critical aspect of securing cloud native applications and the Kubernetes platform itself.

This multi-part blog series aims to explore the network security challenges of the Kubernetes environment and provide insights into mitigating them using Calico security controls. The series will cover various aspects of network security, including security policies, application layer security, host network security,  Pod traffic encryption, and the importance of a defense-in-depth security approach. Let’s dive into the world of Kubernetes network security and learn how to protect your organization’s valuable assets.

Part 1: Secure Kubernetes pod traffic flow using Calico Security Policies

To effectively secure cloud native applications running on Kubernetes, it is essential to understand how they differ  from legacy applications. Additionally, it is also important to note that relying solely on network firewalls may not be enough to protect Kubernetes workloads. In this post, we will use a three-tier application to illustrate the importance of securing Kubernetes workloads and the limitations of network firewalls. We will then provide a practical demonstration of how to implement Calico security policies, enabling granular access controls for the three-tier application.

Legacy workloads vs. Kubernetes

  • Legacy applications are typically monolithic and usually programmed to use in-memory function calls. In contrast, microservices are designed as a collection of small and independent services that can be developed, deployed, and scaled independently. These services communicate with each other using API calls over the network.
  • Legacy applications typically involve long-lived workloads that remain online for extended periods of time, often spanning months or even years, while container-based applications typically rely on short-lived workloads that are launched only when necessary.
  • Legacy applications often rely on static IP addresses that are assigned from a specific network segment. However, Kubernetes workloads are designed to be more dynamic and ephemeral. They use IP addresses from a flat network and are typically active for only a short period of time.

Challenges with using traditional network firewalls in Kubernetes environments

To gain a better understanding of the challenges involved in using a network firewall to safeguard Kubernetes workloads, let’s consider a typical zone-based architecture and explore how we can secure a three tier application running in Kubernetes within this framework.

Fig 1: A sample three-tier Kubernetes-based application

Below are some of the most commonly used zones in the traditional network model:

  • DMZ (Demilitarized Zone) at the top
  • Trusted zone in the middle
  • Restricted zone at the bottom

Since we are using a zone-based architecture, it is necessary to deploy a Kubernetes cluster for each zone due to the flat network model of Kubernetes. In this example, we have a three-tier application that requires secure access control using our zone-based architecture. Each application tier runs in a different cluster.

In this application, Customer service is the front end service and runs in the DMZ. Customer service needs to communicate with the Summary service, which runs the business logic and is located in the Trusted zone. However, for this communication to happen, access needs to be granted to a large number of IP addresses through the firewalls between each zone. Summary service also needs to communicate with the Database service in the Restricted zone, and for this, access needs to be given to another set of IP addresses through the firewalls between each zone.

Let’s explore some of the major challenges in this setup. There are significant issues that need to be addressed.

  • The firewall lacks visibility into the service-to-service communication within the cluster. As a result, there is no way to identify anomalies or detect malicious activity within the cluster.
  • The large IP ranges opened between zones may lead to a false sense of security. This enables any workload within any Kubernetes cluster to traverse between zones, which may compromise the security of the entire network.
  • If any workload in the DMZ is compromised, it can lead to lateral movement to the Trusted zone and possibly gain access to the database. With numerous holes in the firewalls, any malicious workload would have full lateral access across zones and potentially gain access to high-risk assets.

The need for Calico Security Policies

Kubernetes’ flat and dynamic network model provides the flexibility to deploy applications anywhere within the cluster, decoupling them from the underlying network infrastructure. However, this poses challenges for legacy network firewalls, which struggle to keep up with the dynamic nature of Kubernetes workloads. Calico security policy is a framework for defining and enforcing authorized traffic between pods and services. Calico provides fine-grained security policies enhancing the security of complex microservices architectures without compromising Kubernetes’ flexibility and agility.

Kubernetes security policies provides multiple advantages:

Security: Security policies enable us to control Pod’s ingress and egress traffic and enforce rules to prevent unauthorized access.
Isolation: Security policies enable us to isolate workloads and prevent interference between them. This can be particularly important when multiple applications run on the same cluster.
Performance: Network performance can be optimized by controlling traffic between Pods for higher efficiency.
Compliance: Security policies are a key tooling to comply with regulatory requirements such as PCI DSS or best practices by enforcing rules on how traffic is allowed to flow between Pods.

Calico Open Source security policy feature set

Now that we’ve established the importance of using Calico security policies to secure Kubernetes workloads, let’s delve into some of the key characteristics that define these policies. Calico provides two sets of security policy features: Core security policies, which are open source and enterprise security policy features.

Core security policy features

  • Security policies use labels and selectors to implement network control over the Kubernetes Pods. Calico provides feature-rich label selectors, which support a number of operators.
  • Calico supports policy Ordering/Precedence, which is crucial when security policies use labels and selectors to implement network control over the Kubernetes Pods. Calico provides feature-rich label selectors, which support a number of operators
  • Security policies provide a comprehensive set of policy actions including allow, deny, pass, log, which enable writing granular policies.
  • Calico provides two types of network policies: network policies and global network policies.  are limited to a specific namespace, while global network policies extend to the entire Kubernetes cluster, enabling administrators to protect cluster nodes and host networked Pods. By leveraging these policies, administrators can exercise greater flexibility and control over their Kubernetes environment using unified policy language.
  • Calico provides an advanced matching system based on a range of resources, including pods, namespaces, and service accounts, which allows administrators to establish highly specific policies for their Kubernetes cluster.
  • When combined with Envoy, Calico enhances its security policies to operate at Layer 7, providing an extra layer of protection for Kubernetes workloads.
  • While security policies are typically implemented based on pod labels, Calico offers an effortless approach to creating policies based on Kubernetes Services. Calico dynamically implements and enforces these policies on the relevant endpoints, making it simpler for users to manage their Kubernetes cluster’s security.
  • In addition to securing cluster pods, Calico host endpoint protection supports securing the cluster nodes themselves, as well as nodes outside the cluster.

Calico Advanced Security Policy Features

  • DNS policy enables users to create policies based on the fully qualified domain name (FQDN) of a destination, granting pods within the cluster permission to communicate with specific destinations outside the cluster.
  • Tiers provide a powerful way for users to establish a hierarchical priority-based policy processing system that allows them to manage access to specific tiers and namespaces. By leveraging the native Kubernetes RBAC, various teams can efficiently manage access and permissions to their respective tiers and namespaces.
  • Policy preview enables you to understand the impact of policy changes in real time before applying them.
  • Staged Policy lets you create and analyze policies without enforcement, using logging to simulate scenarios and gain insight into potential effects. This feature reduces the risk of unintended consequences and helps make informed decisions before enforcing policies.

Note: These features are available in Calico Cloud and Calico Enterprise

Calico Kubernetes Security Policy Resources

Calico provides a sophisticated and powerful policy engine that is empowered through a number of Kubernetes resources. Let’s explore these resources and use them to secure our three tier application used earlier. This blog covers only the core security policy resources. We will cover the enterprise features in the following blogs.

Network Policy is a namespaced-scope resource used to control ingress and egress traffic to and from Pods in a specific namespace.

Global Network Policy is a non-namespaced resource that can be used to control ingress and egress traffic to and from pods across all namespaces in the cluster. Once Calico Host Endpoint Protection is enabled,  Global Network Policy can be used to secure cluster nodes and host networked pods traffic.

Network Set is a namespaced-scope resource and represents a collection of IP CIDRs/domain names. NetworkSet provides an efficient way to apply policies to traffic originating from or destined for external networks outside of the Calico environment.

Global Network Set is pretty similar to NetworkSet except that it is not namespaced.

Secure the three-tier application—The Calico way

Let’s use Calico security policies to secure our three tier application. Following diagram depicts this implementation including the following:

Fig 2: Policy deployment for a three-tier application
  • A single cluster with three primary namespaces (ingress-nginx, kube-system, yaobank) for the purpose of this security policy implementation.
  • Client users connect via nginx ingress to the frontend service named Customer
  • This cluster uses microsegmentation to secure communication between all the services running in the three namespaces including the following:

Name resolution policy

All the pods across the cluster namespaces need to be able to make egress connections to CoreDNS pods in the kube-system namespace on TCP and UDP port 53. CoreDNS pods in kube-system need to allow ingress traffic from all the cluster pods on TCP and UDP port 53. CoreDNS pods also make egress connection to the Internet on TCP and UDP port 53. A Global Network Policy is an efficient way to deploy policies beyond the scope of a specific namespace.

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: cluster-dns-allow
spec:
  order: 1
  ingress:
    - action: Allow
      protocol: TCP
      source:
        namespaceSelector: all()
      destination:
        selector: k8s-app == "kube-dns"
        namespaceSelector: projectcalico.org/name == "kube-system"
        ports:
          - '53'
    - action: Allow
      protocol: UDP
      source:
        namespaceSelector: all()
      destination:
        selector: k8s-app == "kube-dns"
        namespaceSelector: projectcalico.org/name == "kube-system"
        ports:
          - '53'
  egress:
    - action: Allow
      protocol: TCP
      source:
        namespaceSelector: all()
      destination:
        selector: k8s-app == "kube-dns"
        namespaceSelector: projectcalico.org/name == "kube-system"
        ports:
          - '53'
    - action: Allow
      protocol: UDP
      source:
        namespaceSelector: all()
      destination:
        selector: k8s-app == "kube-dns"
        namespaceSelector: projectcalico.org/name == "kube-system"
        ports:
          - '53'
    - action: Allow
      protocol: TCP
      source:
        selector: k8s-app == "kube-dns"
        namespaceSelector: projectcalico.org/name == "kube-system"
      destination:
        ports:
          - '53'
    - action: Allow
      protocol: UDP
      source:
        selector: k8s-app == "kube-dns"
        namespaceSelector: projectcalico.org/name == "kube-system"
      destination:
        ports:
          - '53'
  types:
    - Ingress
    - Egress

Nginx ingress policy

This policy utilizes Global Network Set to group external CIDRs and allow ingress access to nginx. The following security policy references the Global Network Set using the Global Network Set label of “eep.yaobank.com/ingress: internal-it-network”. Nginx-ingress pods will only receive TCP traffic from specific CIDRs outside the cluster on port 80. Nginx-ingress pods also make outbound TCP connections to Customer pods on port 80.

kind: GlobalNetworkSet
apiVersion: projectcalico.org/v3
metadata:
  name: internal-it-network
  labels:
    eep.yaobank.com/ingress: internal-it-network
spec:
  nets:
    - 172.16.1.0/24
    - 172.16.2.0/24
    - 172.16.3.0/24

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
spec:
  selector: app.kubernetes.io/name == "ingress-nginx"
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: eep.yaobank.com/ingress == "internal-it-network"
        namespaceSelector: global()
      destination:
        ports:
          - '80'
  egress:
    - action: Allow
      protocol: TCP
      source: {}
      destination:
        selector: app == "customer"
        namespaceSelector: projectcalico.org/name == "yaobank"
        ports:
          - '80'
    - action: Allow
      protocol: TCP
      source: {}
      destination:
        selector: endpoints.projectcalico.org/serviceName == "kubernetes"
        namespaceSelector: projectcalico.org/name == "default"
        ports:
          - '6443'
  types:
    - Ingress
    - Egress


Customer policy

Customer pods will only accept TCP traffic from nginx-ingress pods on port 80. Customer pods also make outbound TCP connections to Summary pods on port 80.

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: customer
  namespace: yaobank
spec:
  tier: default
  selector: app == "customer"
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: app.kubernetes.io/name == "ingress-nginx"
        namespaceSelector: projectcalico.org/name == "ingress-nginx"
      destination:
        ports:
          - '80'
  egress:
    - action: Allow
      protocol: TCP
      source: {}
      destination:
        selector: app == "summary"
        namespaceSelector: projectcalico.org/name == "yaobank"
        ports:
          - '80'
  types:
    - Ingress
    - Egress

Summary policy

Summary pods will only accept TCP traffic from customer pods on port 80. Summary pods also make outbound TCP connections to database pods on port 2379.

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: default.summary
  namespace: yaobank
spec:
  tier: default
  selector: app == "summary"
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: app == "customer"
        namespaceSelector: projectcalico.org/name == "yaobank"
      destination:
        ports:
          - '80'
  egress:
    - action: Allow
      protocol: TCP
      source: {}
      destination:
        selector: app == "database"
        namespaceSelector: projectcalico.org/name == "yaobank"
        ports:
          - '2379'
  types:
    - Ingress
    - Egress

Database policy

Database pods will only accept TCP traffic from summary pods on port 2379.

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: database
  namespace: yaobank
spec:
  tier: default
  selector: app == "database"
  serviceAccountSelector: ''
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: app == "summary"
        namespaceSelector: projectcalico.org/name == "yaobank"
      destination:
        ports:
          - '2379'
  types:
    - Ingress

Conclusion

This extensive introduction to Calico Enterprise policies and the plethora of additional capabilities can enable you to get started and secure your Kubernetes clusters and workloads. Security policies are critical resources in securing Kubernetes workloads because they allow for fine-grained control over the cluster traffic flow. Additionally, network policies can help ensure compliance with regulatory requirements by enforcing restrictions on traffic flow that align with industry standards and best practices. The future blogs will focus on advanced policies, DNS policy, observability and encryption.

Read part 2 of this blog series: How to secure Kubernetes workloads using Calico DNS Security Policy

Ready to get started? Try Calico Cloud for free.

Join our mailing list

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

X