Skip to main content
Calico Enterprise 3.22 (latest) documentation

Deep packet inspection

Big picture

Configure deep packet inspection (DPI) in clusters to get alerts on compromised resources.

Value

Security teams need to run DPI quickly in response to unusual network traffic in clusters so they can identify potential threats. Also, it is critical to run DPI on select workloads (not all) to efficiently make use of cluster resources and minimize the impact of false positives. Calico Enterprise provides an easy way to perform DPI using Snort community rules. You can disable DPI at any time, selectively configure for namespaces and endpoints, and alerts are generated in the Alerts dashboard in the web console.

Concepts

For each deep packet inspection resource (DeepPacketInspection), Calico Enterprise creates a live network monitor that inspects the header and payload information of packets that match the Snort community rules. Whenever malicious activities are suspected, an alert is automatically added to the Security Events page in the Calico Enterprise web console.

Calico Enterprise DPI uses AF_PACKET, a Linux socket that allows an application to receive and send raw packets. It is commonly used for troubleshooting (like tcpdump and Wireshark), but also for network intrusion detection. For details, see AF_Packet.

Before you begin

Not supported:

  • Multi-nic setup
  • Calico Enterprise nodes running Windows hosts

How to

Configure deep packet inspection

Create a YAML file containing one or more DeepPacketInspection resources and apply it to your cluster.

kubectl apply -f <your_deep_packet_inspection_filename>

To stop deep packet inspection, delete the DeepPacketInspection resource from your cluster.

kubectl delete -f <your_deep_packet_inspection_filename>

Examples of selecting workloads

Following is a basic example that selects a single workload that has the label k8s-app with the value nginx.

apiVersion: projectcalico.org/v3
kind: DeepPacketInspection
metadata:
name: sample-dpi-nginx
namespace: sample
spec:
selector: k8s-app == "nginx"

In the following example, we select all workload endpoints in the sample namespace.

apiVersion: projectcalico.org/v3
kind: DeepPacketInspection
metadata:
name: sample-dpi-all
namespace: sample
spec:
selector: all()

Configure resource requirements

Adjust the CPU and RAM used for performing deep packet inspection by updating the component resource in IntrusionDetection.

For a data transfer rate of 1GB/sec on workload endpoints being monitored, we recommend a minimum of 1 CPU and 1GB RAM.

The following example configures deep packet inspection to use a maximum of 1 CPU and 1GB RAM.

apiVersion: operator.tigera.io/v1
kind: IntrusionDetection
metadata:
name: tigera-secure
spec:
componentResources:
- componentName: DeepPacketInspection
resourceRequirements:
limits:
cpu: '1'
memory: 1Gi
requests:
cpu: 100m
memory: 100Mi

Access alerts

The alerts generated by deep packet inspection are available in the web console in the Alerts page.

Verify deep packet inspection is running

Get the status of DeepPacketInspection resource to verify if live traffic is being monitored on selected workload endpoints.

kubectl get <deep_packet_inspection_resource_name> -n <deep_packet_inspection_namespace>

Customize Snort rules and configuration

By default, Calico Enterprise DPI uses Snort community rules with a default Snort3 configuration. You can customize these defaults using init containers that run before the DPI pods start.

Common reasons to customize Snort for DPI include:

  • Custom rules: Replace or supplement the built-in community rules with paid Snort subscription rules or your own custom rules.
  • Alert rate control: Reduce alert noise by configuring Snort3 thresholding, filtering, or suppression through the snort.lua configuration file.

Customizing rules and customizing the Snort configuration are separate procedures that use different files and destination paths. You can apply either or both.

note

Snort3 offers extensive configuration options beyond what is documented here. For full details on writing custom rules or configuring snort.lua, refer to the Snort3 documentation.

Install custom Snort rules

Use this procedure to replace the built-in Snort community rules with your own rule set.

important

If you install custom Snort rules, Calico Enterprise will stop updating the community rules with each minor release. You will be responsible for making sure your rules are up to date.

  1. Create a container with your custom Snort rules.

    1. Copy your Snort rule files into a new ./snort-rules/ directory.

    2. Create a Dockerfile like this one:

      FROM alpine:3.14
      COPY snort-rules /snort-rules
      ENTRYPOINT [ "/bin/sh", "-c", "cp /snort-rules/* /usr/etc/snort/rules/" ]
    3. In the console, run the following commands:

      docker build . -t <your-image-name>:<your-image-tag>
      docker push <your-image-name>:<your-image-tag>

      After the image has been pushed to the registry, you're ready to configure the IntrusionDetection resource.

  2. Update the IntrusionDetection resource with the custom Snort rules image.

    spec:
    deepPacketInspectionDaemonset:
    spec:
    template:
    spec:
    initContainers:
    - name: snort-rules
    image: <your-image-name>:<your-image-tag>

    This can also be done by running the following command:

    kubectl patch intrusiondetection tigera-secure --type merge -p '{"spec":{"deepPacketInspectionDaemonset":{"spec":{"template":{"spec":{"initContainers":[{"name":"snort-rules", "image":"<your-image-name>:<your-image-tag>"}]}}}}}}'
  3. Verify that your custom rules have been installed correctly:

    1. If it's not running already, apply the DeepPacketInspection resource to your cluster.

    2. Extract the list of Snort rules that are currently being used by running the following commands:

      export POD=$(kubectl get pods -n tigera-dpi -o custom-columns=:metadata.name --no-headers | head -n 1) \
      kubectl exec -n tigera-dpi $POD -- tar -cf - /usr/etc/snort/rules | tar --strip-components=4 -xf -
    3. If these rules match those in your custom set, then the installation was successful.

Customize Snort configuration

Use this procedure to modify the Snort3 configuration file (snort.lua). This is required for customizations like alert rate limiting, event filtering, and alert suppression, which are controlled through snort.lua rather than through rule files.

For example, if DPI is generating a high volume of alerts, you can configure Snort3 event filters, suppressions, and rate filters in snort.lua to reduce noise and focus on the alerts that matter. For details on snort.lua configuration options, see the Snort3 documentation.

  1. Extract the default snort.lua from a running DPI pod:

    export POD=$(kubectl get pods -n tigera-dpi -l k8s-app=tigera-dpi \
    -o jsonpath='{.items[0].metadata.name}')
    kubectl cp tigera-dpi/$POD:/usr/etc/snort/snort.lua ./snort.lua -c tigera-dpi
  2. Edit snort.lua with your desired changes.

  3. Create a container with your modified configuration.

    1. Create a Dockerfile:

      FROM alpine:3.14
      COPY snort.lua /snort-config/snort.lua
      ENTRYPOINT [ "/bin/sh", "-c", "cp /snort-config/snort.lua /usr/etc/snort/snort.lua" ]
    2. Build and push the image:

      docker build . -t <your-config-image-name>:<your-config-image-tag>
      docker push <your-config-image-name>:<your-config-image-tag>
  4. Update the IntrusionDetection resource with the custom configuration image.

    spec:
    deepPacketInspectionDaemonset:
    spec:
    template:
    spec:
    initContainers:
    - name: snort-config
    image: <your-config-image-name>:<your-config-image-tag>

    This can also be done by running the following command:

    kubectl patch intrusiondetection tigera-secure --type merge -p '{"spec":{"deepPacketInspectionDaemonset":{"spec":{"template":{"spec":{"initContainers":[{"name":"snort-config", "image":"<your-config-image-name>:<your-config-image-tag>"}]}}}}}}'
  5. Verify that the DPI pods restart successfully:

    kubectl get pods -n tigera-dpi -w

    If pods enter a CrashLoopBackOff state, check the init container and DPI container logs for Lua syntax errors:

    kubectl logs -n tigera-dpi <pod-name> -c tigera-dpi

Combine custom rules and configuration

If you need both custom rules and a custom snort.lua, you can either combine them in a single init container image or use two separate init containers.

Option 1: Single init container (recommended)

Create one image that copies both the rules and the configuration:

FROM alpine:3.14
COPY snort-rules /snort-rules
COPY snort.lua /snort-config/snort.lua
ENTRYPOINT [ "/bin/sh", "-c", "cp /snort-rules/* /usr/etc/snort/rules/ && cp /snort-config/snort.lua /usr/etc/snort/snort.lua" ]

Option 2: Two init containers

Use separate images for rules and configuration. Init containers run in the order they are listed.

spec:
deepPacketInspectionDaemonset:
spec:
template:
spec:
initContainers:
- name: snort-rules
image: <your-rules-image-name>:<your-rules-image-tag>
- name: snort-config
image: <your-config-image-name>:<your-config-image-tag>

Revert to default Snort rules and configuration

To remove all customizations and return to the built-in Snort community rules and default configuration, remove the deepPacketInspectionDaemonset spec from the IntrusionDetection resource:

kubectl patch intrusiondetection tigera-secure --type json -p '[{"op":"remove","path":"/spec/deepPacketInspectionDaemonset"}]'

Additional resources