Documentation
  • Introduction
    • How It Works
    • Architecture & Data Flow
    • Why another Agent?
    • eBPF Concepts
    • Use Cases
  • Deployment
  • Qtap
    • Getting Started
    • System Requirements
    • Installation
      • Linux Binary
      • Docker Container
      • Helm Chart
      • Kubernetes Manifest
    • Configuration
      • Storage Configuration
      • Traffic Processing with Plugins
      • Traffic Capture Settings
      • Configuration Examples
  • Qplane
    • Getting Started
      • Create an Account
      • Install Qtap
      • Review your Dashboards
    • Installation
      • Linux Binary
      • Docker Container
      • Helm Chart
    • Configuration
  • Security & Compliance
  • License
  • Appendix
    • Qcontrol (Beta)
    • Java
    • Object Storage
      • Google Cloud Storage
    • S3 Credentials for Qtap using Kubernetes Secrets
  • FAQ
Powered by GitBook
On this page
  • Introduction
  • Understanding the Qcontrol Context
  • Expression Syntax
  • Logical Operators
  • Comparison Operators
  • Value Types
  • Arrays
  • Comments and Whitespace
  • Qcontrol Field Reference
  • Source Fields (src.*)
  • Destination Fields (dst.*)
  • Connection Fields
  • TLS Fields (tls.*)
  • Metadata Fields
  • Common Security Use Cases
  • Allow Essential Services
  • Enforce TLS Security
  • Protect Internal Services
  • Control Process Access
  • Prevent Data Exfiltration
  • Best Practices
  • Rule Organization
  • Rule Writing
  • Performance Tips
  • Comprehensive Production Example
  • Troubleshooting
  1. Appendix

Qcontrol (Beta)

Introduction

Rulekit is the expression engine that powers Qcontrol's rule-based traffic management system. It allows you to define precise conditions for controlling network traffic using a simple, intuitive syntax. This guide will help you understand how to effectively use Rulekit expressions within Qcontrol to implement security policies and traffic controls.

Understanding the Qcontrol Context

Qcontrol uses Rulekit to evaluate and enforce rules against network traffic, primarily focusing on:

  • Outbound connections: Monitoring and controlling where your applications can connect

  • Process attribution: Understanding which processes initiated connections

  • Security enforcement: Allowing or denying traffic based on precise conditions

Rules are evaluated in order, with allow rules typically placed before deny rules to ensure critical services remain accessible.

Expression Syntax

RuleKit expressions follow a straightforward pattern:

<field> <operator> <value>

Multiple conditions can be combined using logical operators:

<field1> <operator1> <value1> and <field2> <operator2> <value2>

Logical Operators

Operator
Aliases
Description
Example

and

&&

Logical AND

dst.port == 443 and tls.version >= 1.3

or

||

Logical OR

dst.port == 80 or dst.port == 443

not

!

Logical NOT

not src.pod.namespace == "kube-system"

Comparison Operators

Operator
Aliases
Description
Example

==

eq

Equal to

dst.port == 443

!=

ne

Not equal to

src.pod.namespace != "kube-system"

>

gt

Greater than

dst.port > 1024

>=

ge

Greater than or equal to

tls.version >= 1.3

<

lt

Less than

dst.port < 1024

<=

le

Less than or equal to

tls.version <= 1.2

=~

matches

Matches regex pattern

dst.domain matches /.example.com$/

contains

Contains substring or element

dst.domain contains "example"

in

Is contained in array

dst.port in [80, 443, 8080]

Value Types

bool

A boolean. For example: true, false.

tls.enabled || allow_insecure == true

number

An integer or floating-point number. For example: 8080, 1.2.

tls.version >= 1.2

string

A double-quoted string. For example: "tcp", "{\"content\": \"example\"}".

dst.domain == "example.com"

regex pattern

A Golang/RE2 regular expression surrounded by forwarded-slashes / or straight pipes |. Can only be compared against string values. For example: \.domain\.com$.

dst.domain matches /\.domain\.com$/
src.process.path matches |^/usr/local/|

IP

An IPv4, IPv6, or an IPv6 dual address. For example:

  • 192.168.1.1

  • 2001:db8:3333:4444:cccc:dddd:eeee:ffff

dst.ip != 10.0.0.1

CIDR

An IPv4 or IPv6 CIDR block. For example:

  • 192.168.0.0/16

  • 2001:db8:3333:4444:cccc:dddd:eeee:0000/48

dst.ip != 10.0.0.0/8

Arrays

Arrays may be expressed using square bracket notation. Arrays may contain mixed types and can be used to make rules more readable.

dst.port in [80, 8080, 53]
-- instead of
dst.port == 80 or dst.port == 8080 or dst.port == 53
dst.ip != [10.0.0.0/8, 192.168.0.0/16, 1.2.3.4]
-- instead of
dst.ip != 10.0.0.0/8 and dst.ip != 192.168.0.0/16 and dst.ip != 1.2.3.4
dst.domain in ["example.com", /\.example\.com$/]
-- instead of
dst.domain == "example.com" or dst.domain matches /\.example\.com$/

Comments and Whitespace

Expressions may contain single-line or multiline comments. Whitespace around values and operators will be ignored.

-- common services
dst.port == 80 /* http */ or dst.port == 53 /* dns */
-- database services
or dst.port in [
  3306,  -- MySQL
  5432,  -- PostgreSQL
  27017, -- MongoDB
  6379   -- Redis
]

Qcontrol Field Reference

This document serves as a reference for the fields available in Qcontrol rules that can be used to monitor and control network traffic.

Source Fields (src.*)

Field
Type
Example
Description

src.process.path

string

/usr/bin/curl

Full path to the executable

src.process.binary

string

curl

Binary name without path

src.process.user.id

int

1000

Numeric user ID

src.process.user.name

string

app-user

Username

src.process.env

map[string]string

{"HOME": "/home/user"}

Environment variables

src.process.hostname

string

worker-pod-1

Process hostname

src.container.id

string

a72dfe9c43a2

Container ID (short or full)

src.container.name

string

app-frontend

Container name

src.container.image

string

nginx:1.21

Container image with tag

src.container.labels

map[string]string

{"app": "frontend"}

Container labels

src.pod.name

string

frontend-5d4d7d4b45-2jrvs

Kubernetes pod name

src.pod.namespace

string

production

Kubernetes namespace

src.pod.labels

map[string]string

{"app": "frontend"}

Kubernetes pod labels

src.ip

IP

10.0.0.1

Source IP address

src.port

uint

55123

Source port number

Destination Fields (dst.*)

Field
Type
Example
Description

dst.ip

IP

192.168.1.10

Destination IP address

dst.port

uint

443

Destination port number

dst.domain

string

api.example.com

Destination domain name

Connection Fields

Field
Type
Example
Description

protocol

string

http2

L7 protocol

values: unknown, http1, http2, dns, grpc

type

string

tcp

Socket type values: tcp, udp, raw, icmp

direction

string

egress

Traffic direction values: egress-external, egress-internal, egress

TLS Fields (tls.*)

Field
Type
Example
Description

tls.enabled

bool

true

Whether TLS is enabled

tls.version

float

1.2

TLS protocol version

tls.sni

string

api.example.com

TLS Server Name Indication

tls.alpn

[]string

["h2", "http/1.1"]

Application-Layer Protocol Negotiation values

Metadata Fields

Field
Type
Example
Description

tags

[]string

["app:frontend", "env:prod"]

List of key-value tags

Common Security Use Cases

Allow Essential Services

Place allow rules at the top of your configuration to ensure critical services remain accessible:

- name: allow essential services
  expr: dst.domain in ["registry.k8s.io", "k8s.gcr.io", "gcr.io", "docker.io"]
  actions: [allow]
  
- name: allow documentation sites
  expr: dst.domain in ["kubernetes.io", "helm.sh", "prometheus.io"]
  actions: [allow]

Enforce TLS Security

Block connections using outdated TLS versions:

- name: block legacy tls
  expr: tls.enabled and tls.version <= 1.2
  actions: [deny]

Protect Internal Services

Control access to internal network services:

- name: restrict sensitive ports
  expr: dst.port in [22, 3306, 6379, 27017] and dst.ip != 10.0.0.0/8
  actions: [deny]

Control Process Access

Restrict what specific applications can connect to:

- name: restrict curl
  expr: src.process.binary == "curl" and not dst.domain in ["api.example.com", "updates.example.com"]
  actions: [deny]

Prevent Data Exfiltration

Block access to cloud storage services except from authorized sources:

- name: block cloud storage
  expr: dst.domain matches /(\.s3\.amazonaws\.com|\.storage\.googleapis\.com|\.blob\.core\.windows\.net)$/ and not src.pod.namespace == "backup"
  actions: [deny]

Best Practices

Rule Organization

  • Put allow rules first: Define what should be explicitly allowed before setting up blocking rules

  • Order by priority: Most critical rules should be evaluated first

  • Group related rules: Keep similar rules together for easier management

Rule Writing

  • Be specific: Write targeted rules that address particular security concerns

  • Use descriptive names: Make rule names clear and self-explanatory

  • Comment complex rules: Add YAML comments to explain reasoning behind rules

  • Test thoroughly: Validate rules in a non-production environment first

  • Readability: Use whitespace and comments within rule expressions for clarity

Performance Tips

  • Use exact matching: Prefer == and in over regex patterns when possible

  • Limit regex complexity: Simple patterns are more efficient

Comprehensive Production Example

Here's an example of a production rule set for Kubernetes environments:

control:
  rules:
    # Allow rules (highest priority)
    - name: allow essential services
      expr: dst.domain in ["registry.k8s.io", "k8s.gcr.io", "gcr.io", "docker.io"]
      actions: [allow]
      
    - name: allow documentation sites
      expr: dst.domain in ["kubernetes.io", "helm.sh", "prometheus.io", "pypi.org"]
      actions: [allow]
    
    - name: allow monitoring traffic
      expr: dst.port in [9090, 9100, 3000]
      actions: [allow]
    
    # Internal service protection
    - name: restrict sensitive ports
      expr: dst.port in [22, 3306, 6379, 27017] and dst.ip != 10.0.0.0/8
      actions: [deny]
    
    - name: enforce secure communications
      expr: tls.enabled and tls.version <= 1.2
      actions: [deny]
    
    # Prevent data exfiltration
    - name: block cloud storage 
      expr: dst.domain matches /(\.s3\.amazonaws\.com|\.storage\.googleapis\.com|\.blob\.core\.windows\.net)$/ and src.pod.namespace != "backup"
      actions: [deny]
    
    # Additional security rules
    - name: block cryptocurrency mining
      expr: dst.domain in ["pool.minergate.com", "cryptonight.net", "coinhive.com", "crypto-loot.com"]
      actions: [deny]
    
    - name: restrict database connections
      expr: |
        dst.port in [
          3306,  -- MySQL
          5432,  -- PostgreSQL
          27017, -- MongoDB
          6379   -- Redis
        ]
        and not src.pod.namespace in ["api", "backend", "monitoring"]
      actions: [deny]

Troubleshooting

If your rules aren't working as expected:

  • Check rule ordering: Rules are evaluated in order - earlier rules take precedence

  • Verify field names: Ensure fields referenced in rules match the actual data

  • Test rule patterns: Validate regex patterns against sample data

  • Check logs: Look for logs showing which rules were matched

  • Simplify and iterate: Start with simple rules and build complexity gradually

PreviousAppendixNextJava

Last updated 28 days ago