Skip to content
Draft

. #56

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# Testing Egress Policies Dynamic Module

Quick guide to compile and test your dynamic module with Envoy.

## Prerequisites

- Rust toolchain (`rustc`, `cargo`)
- Envoy proxy (`brew install envoyproxy/envoy/envoy` on macOS)
- `dig` command for DNS testing

## Quick Start

```bash
# 1. Build the module
cd rust
cargo build --release

# 2. Start Envoy (from parent directory)
cd ..
./run-envoy.sh

# 3. In another terminal, test it
./test-egress.sh
```

## Manual Steps

### 1. Build Module

```bash
cd rust
cargo build --release
# Output: target/release/librust_module.dylib (macOS) or .so (Linux)
```

### 2. Set Environment

```bash
export ENVOY_DYNAMIC_MODULES_SEARCH_PATH=/Users/govadia/Desktop/dynamic-modules-examples/rust/target/release
```

### 3. Start Envoy

```bash
envoy -c envoy-egress-test.yaml --log-level info
```

**Expected logs:**
```
[info] Initialized VirtualIpCache with base IP 10.10.0.0
[info] DnsGateway initialized with 2 policies
```

### 4. Test DNS Gateway

```bash
# Query a matching domain
dig @127.0.0.1 -p 5353 api.aws.com +short
# Expected: 10.10.0.0

# Query another domain
dig @127.0.0.1 -p 5353 cdn.example.com +short
# Expected: 10.10.0.1

# Query same domain again (cached)
dig @127.0.0.1 -p 5353 api.aws.com +short
# Expected: 10.10.0.0 (same IP)
```

### 5. Check Envoy Stats

```bash
curl http://127.0.0.1:9901/stats | grep -E "(dns|virtual|policy)"
```

## Configuration

### DNS Gateway Config

The DNS gateway is configured in `envoy-egress-test.yaml`:

```yaml
config:
base_ip: "10.10.0.0" # Start allocating from this IP
policies:
- domain: "*.aws.com" # Wildcard pattern
metadata:
upstream_cluster: "aws_cluster"
tunneling_hostname: "tunnel.aws.com"
```

### How It Works

1. **DNS Query** (port 5353):
- Client queries `api.aws.com`
- DNS gateway matches `*.aws.com` policy
- Allocates virtual IP `10.10.0.0`
- Returns DNS A record with virtual IP

2. **TCP Connection** (port 17100):
- Client connects to `10.10.0.0:17100`
- Hostname lookup filter gets virtual IP
- Looks up policy from cache
- Stores metadata in FilterState
- TCP proxy uses metadata for routing

## Debugging

### Check Module Loading

```bash
# Envoy should log module initialization
grep "dynamic_modules" envoy.log
```

### Check Allocated IPs

```bash
# Query admin endpoint
curl http://127.0.0.1:9901/stats | grep allocated
```

### Enable Debug Logging

```bash
envoy -c envoy-egress-test.yaml --log-level debug
```

### Common Issues

**Module not found:**
```
ENVOY_DYNAMIC_MODULES_SEARCH_PATH not set or incorrect
```
**Solution:** Set to the directory containing your `.dylib` or `.so` file

**No DNS response:**
```
Domain doesn't match any policy pattern
```
**Solution:** Check policy patterns in config

**Config parse error:**
```
Invalid JSON in config field
```
**Solution:** Validate JSON syntax in the `config:` section

## Integration Test

Run the full integration test:

```bash
./test-egress.sh
```

This tests:
- ✅ DNS allocation for new domains
- ✅ Cache hits for repeated queries
- ✅ Policy matching with wildcards
- ✅ Non-matching domains (no response)

## Next Steps

- Add more policy patterns
- Implement TCP routing based on metadata
- Add monitoring/metrics
- Deploy to production environment
1 change: 1 addition & 0 deletions envoy-1.37
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Not Found
1 change: 1 addition & 0 deletions envoy-1.37.0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Not Found
96 changes: 96 additions & 0 deletions envoy-egress-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
admin:
address:
socket_address:
address: 127.0.0.1
port_value: 9901

static_resources:
listeners:
# DNS Gateway - Listens for DNS queries
- name: dns_listener
address:
socket_address:
address: 0.0.0.0
port_value: 5353
protocol: UDP
udp_listener_config:
listener_filters:
- name: envoy.filters.udp_listener.dynamic_modules
typed_config:
"@type": type.googleapis.com/envoy.extensions.dynamic_modules.v3.DynamicModuleConfig
name: dns_gateway
do_not_close: true
config:
base_ip: "10.10.0.0"
policies:
- domain: "*.aws.com"
metadata:
upstream_cluster: "aws_cluster"
tunneling_hostname: "tunnel.aws.com"
- domain: "*.example.com"
metadata:
upstream_cluster: "example_cluster"
tunneling_hostname: "tunnel.example.com"

# TCP Listener - Receives connections to virtual IPs
- name: tcp_listener
address:
socket_address:
address: 0.0.0.0
port_value: 17100
filter_chains:
- filters:
# Hostname lookup filter - looks up policy from virtual IP
- name: envoy.filters.network.dynamic_modules
typed_config:
"@type": type.googleapis.com/envoy.extensions.dynamic_modules.v3.DynamicModuleConfig
name: hostname_lookup
do_not_close: true
config: {}

# TCP proxy - forwards traffic
- name: envoy.filters.network.tcp_proxy
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
stat_prefix: egress_tcp
cluster: default_cluster

clusters:
- name: default_cluster
connect_timeout: 5s
type: STATIC
load_assignment:
cluster_name: default_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8080

- name: aws_cluster
connect_timeout: 5s
type: STATIC
load_assignment:
cluster_name: aws_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8081

- name: example_cluster
connect_timeout: 5s
type: STATIC
load_assignment:
cluster_name: example_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8082
44 changes: 44 additions & 0 deletions envoy-simple-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
admin:
address:
socket_address:
address: 127.0.0.1
port_value: 9901

static_resources:
listeners:
# Simple TCP listener to test hostname lookup filter
- name: tcp_listener
address:
socket_address:
address: 0.0.0.0
port_value: 17100
filter_chains:
- filters:
# Hostname lookup filter - manually initialize cache for testing
- name: envoy.filters.network.dynamic_modules
typed_config:
"@type": type.googleapis.com/envoy.extensions.dynamic_modules.v3.DynamicModuleConfig
name: hostname_lookup
do_not_close: true
config: {}

# TCP proxy - forwards traffic
- name: envoy.filters.network.tcp_proxy
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
stat_prefix: egress_tcp
cluster: default_cluster

clusters:
- name: default_cluster
connect_timeout: 5s
type: STATIC
load_assignment:
cluster_name: default_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8080
37 changes: 37 additions & 0 deletions run-envoy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash

# Egress Policies Dynamic Module - Envoy Startup Script

# Set the module search path
export ENVOY_DYNAMIC_MODULES_SEARCH_PATH=/Users/govadia/Desktop/dynamic-modules-examples/rust/target/release

echo "=== Starting Envoy with Egress Policies Dynamic Module ==="
echo ""
echo "Module path: $ENVOY_DYNAMIC_MODULES_SEARCH_PATH"
echo "Config: envoy-egress-test.yaml"
echo ""
echo "Services:"
echo " - DNS Gateway: udp://0.0.0.0:5353"
echo " - TCP Listener: tcp://0.0.0.0:17100"
echo " - Admin: http://127.0.0.1:9901"
echo ""
echo "Test with: ./test-egress.sh"
echo ""

# Check if envoy is installed
if ! command -v envoy &> /dev/null; then
echo "ERROR: envoy command not found"
echo "Install with: brew install envoyproxy/envoy/envoy"
exit 1
fi

# Check if module exists
if [ ! -f "$ENVOY_DYNAMIC_MODULES_SEARCH_PATH/librust_module.dylib" ] && [ ! -f "$ENVOY_DYNAMIC_MODULES_SEARCH_PATH/librust_module.so" ]; then
echo "ERROR: Dynamic module not found at $ENVOY_DYNAMIC_MODULES_SEARCH_PATH"
echo "Build with: cd rust && cargo build --release"
exit 1
fi

# Start Envoy
cd /Users/govadia/Desktop/dynamic-modules-examples
envoy -c envoy-egress-test.yaml --log-level info
Loading