Kids Proxy - A transparent HTTP/HTTPS interception proxy with embedded DNS server for home network parental controls, powered by Open Policy Agent (OPA).
- Embedded DNS Server - Single IP configuration point for clients
- Transparent Proxy - Intercepts HTTP and HTTPS traffic with TLS termination
- Dynamic TLS Certificates - On-the-fly certificate generation for HTTPS interception
- Intelligent DNS Routing - Intercept or bypass domains at DNS level
- Policy-Based Control - Declarative access rules using OPA and Rego
- Per-Device Policies - Device identification and custom access rules
- Domain/Path Filtering - Fine-grained control with wildcard support
- Time-Based Access - Restrict access by time of day and day of week
- Usage Tracking - Monitor and limit daily usage per category
- Bypass Sensitive Domains - Avoid MITM on banking and critical sites
- Ad Blocking - Block advertisement domains like Pi-hole
- Prometheus Metrics - Built-in observability and monitoring
- Structured Logging - Complete HTTP and DNS query logs via zerolog
- Getting Started - Installation and setup
- Policy Tutorial - Learn to write OPA policies (from blocking everything to advanced use cases)
- CA Installation Guide - Trust the root CA on your devices
- Open Policy Agent & Rego - Understanding the policy engine
KProxy uses a fact-based policy evaluation approach powered by Open Policy Agent (OPA):
┌─────────┐ DNS Query ┌──────────┐
│ Device │─────────────────────→│ DNS │
└─────────┘ │ Server │
│ └────┬─────┘
│ │
│ HTTP/HTTPS Request ┌────▼─────┐ ┌──────────┐
↓ │ Policy │◄────→│ OPA │
┌─────────┐ Facts (IP, MAC, │ Engine │ │ Engine │
│ Proxy │ domain, time, etc) └────┬─────┘ └──────────┘
│ Server │◄──────────────────────────┘
└────┬────┘ Decision (Allow/Block)
│
↓
Internet
-
DNS Stage: When a device queries DNS, KProxy checks if the domain should be bypassed (banking), intercepted (filtered), or blocked (ads)
-
Proxy Stage: For intercepted domains, KProxy:
- Gathers facts about the request (device, time, current usage, URL)
- Evaluates OPA policies written in Rego
- Enforces the decision (allow/block/track usage)
-
Policy Evaluation: OPA policies (
.regofiles) define:- Which devices exist and their profiles
- Time restrictions (e.g., no social media during school hours)
- Domain rules (allow/block by category)
- Usage limits (e.g., 60 minutes of entertainment per day)
- Bypass domains (banking, OCSP, etc.)
| Component | Purpose |
|---|---|
| DNS Server | Resolves queries and routes to proxy or internet |
| HTTP/HTTPS Proxy | Intercepts web traffic with TLS termination |
| Policy Engine | Gathers facts and queries OPA for decisions |
| OPA Engine | Evaluates Rego policies against facts |
| Certificate Authority | Generates TLS certificates on-demand |
| Redis Storage | Stores operational data (usage, DHCP leases) |
| Metrics Server | Prometheus metrics endpoint |
Old approach (database-driven):
Config (Database) → Go Code (hardcoded logic) → Decision
KProxy approach (policy-driven):
Facts (Go) + Policies (Rego) → OPA Engine → Decision
Benefits:
- Configuration as Code: Version control your policies
- Declarative: Describe what should happen, not how
- Testable: Use
opa testto validate before deployment - Flexible: Change rules without modifying application code
- Auditable: Clear separation of facts and policy
Open Policy Agent is a general-purpose policy engine that decouples policy decision-making from policy enforcement. In KProxy:
- You write policies in Rego (
.regofiles) - KProxy gathers facts (device identity, time, usage)
- OPA evaluates policies against facts
- KProxy enforces the decision
Rego is OPA's declarative policy language. Example:
# Allow educational sites for child profile
allow {
input.profile == "child"
some domain in ["*.khanacademy.org", "*.wikipedia.org"]
matches_domain(input.host, domain)
}
# Block social media for children
deny {
input.profile == "child"
some domain in ["*.tiktok.com", "*.snapchat.com"]
matches_domain(input.host, domain)
}| File | Purpose |
|---|---|
policies/config.rego |
Central configuration: devices, profiles, rules, usage limits |
policies/device.rego |
Device identification logic (MAC → IP → CIDR) |
policies/dns.rego |
DNS-level decisions (BYPASS/INTERCEPT/BLOCK) |
policies/proxy.rego |
HTTP/HTTPS request decisions (ALLOW/BLOCK) |
policies/helpers.rego |
Utility functions (domain matching, time checks) |
Learn more: See the Policy Tutorial for step-by-step examples.
- Linux server with network routing capability
- Go 1.21+ for building from source
- Redis for operational data storage
- Root access for binding to privileged ports (DNS 53, HTTP 80, HTTPS 443)
-
Install Redis:
# Debian/Ubuntu sudo apt-get install redis-server sudo systemctl start redis # macOS brew install redis redis-server
-
Clone and build KProxy:
git clone https://github.com/goodtune/kproxy.git cd kproxy make build -
Generate CA certificates:
sudo make generate-ca
-
Configure KProxy:
sudo mkdir -p /etc/kproxy/policies sudo cp configs/config.example.yaml /etc/kproxy/config.yaml sudo cp policies/*.rego /etc/kproxy/policies/ # Edit configuration sudo nano /etc/kproxy/config.yaml sudo nano /etc/kproxy/policies/config.rego
-
Run KProxy:
sudo ./bin/kproxy -config /etc/kproxy/config.yaml
For KProxy to work, clients must:
- Configure DNS to point to the KProxy server IP
- Install the root CA certificate for HTTPS interception
See the CA Installation Guide for detailed instructions per platform.
Option A: Router DHCP (Recommended)
- Configure your router to assign KProxy IP as the DNS server
- All devices will automatically use KProxy
Option B: Per-Device
- Manually set DNS to KProxy IP in device network settings
Server settings in /etc/kproxy/config.yaml:
dns:
listen: ":53"
upstream_servers:
- "8.8.8.8:53"
- "1.1.1.1:53"
proxy:
http_listen: ":80"
https_listen: ":443"
tls:
ca_cert: "/etc/kproxy/ca/root-ca.crt"
ca_key: "/etc/kproxy/ca/root-ca.key"
intermediate_cert: "/etc/kproxy/ca/intermediate-ca.crt"
intermediate_key: "/etc/kproxy/ca/intermediate-ca.key"
storage:
redis:
addr: "localhost:6379"
policy:
opa_policy_source: filesystem
opa_policy_dir: /etc/kproxy/policiesAll access control in /etc/kproxy/policies/config.rego:
package kproxy.config
devices := {
"kids-ipad": {
"name": "Kids iPad",
"identifiers": ["aa:bb:cc:dd:ee:ff"], # MAC address
"profile": "child"
},
"parents-laptop": {
"name": "Parents Laptop",
"identifiers": ["192.168.1.100"], # IP address
"profile": "adult"
}
}
profiles := {
"child": {
"time_restrictions": {
"weekday": {
"days": [1, 2, 3, 4, 5], # Monday-Friday
"start_hour": 15, # 3 PM
"end_hour": 20 # 8 PM
}
},
"rules": [
{
"id": "allow-educational",
"domains": ["*.khanacademy.org", "*.wikipedia.org"],
"action": "allow",
"priority": 10
},
{
"id": "block-social",
"domains": ["*.tiktok.com", "*.snapchat.com"],
"action": "block",
"priority": 20
}
],
"usage_limits": {
"entertainment": {
"daily_minutes": 60,
"domains": ["*.youtube.com", "*.netflix.com"]
}
},
"default_action": "block"
},
"adult": {
"default_action": "allow"
}
}
# Global bypass domains (avoid MITM on sensitive sites)
global_bypass_domains := [
"*.bank.com",
"*.paypal.com",
"ocsp.*.com",
"*.apple.com"
]See the Policy Tutorial for comprehensive examples.
KProxy exposes metrics at :9090/metrics:
http://kproxy-ip:9090/metrics
Key metrics:
kproxy_dns_queries_total- DNS queries by device, action, typekproxy_requests_total- HTTP/HTTPS requests by device, hostkproxy_blocked_requests_total- Blocked requests by device, reasonkproxy_certificates_generated_total- TLS certificates generatedkproxy_usage_minutes_consumed_total- Usage by device, categorykproxy_request_duration_seconds- Request latencykproxy_active_connections- Current active connections
All DNS queries and HTTP/HTTPS requests are logged via zerolog:
{"level":"info","time":"2025-01-15T10:23:45Z","client_ip":"192.168.1.100","domain":"youtube.com","action":"INTERCEPT","latency_ms":12}
{"level":"info","time":"2025-01-15T10:23:46Z","client_ip":"192.168.1.100","method":"GET","host":"youtube.com","path":"/","action":"ALLOW","category":"entertainment"}Route logs to:
- Systemd journal:
journalctl -u kproxy -f - Log aggregation: Vector, Fluentd, etc.
- File: Configure via systemd or Docker
# Install
sudo make install
# Enable and start
sudo systemctl enable kproxy
sudo systemctl start kproxy
# Check status
sudo systemctl status kproxy
# View logs
sudo journalctl -u kproxy -f# Build image
make docker
# Run
docker run -d \
--name kproxy \
-p 53:53/udp \
-p 53:53/tcp \
-p 80:80 \
-p 443:443 \
-p 9090:9090 \
-v /etc/kproxy:/etc/kproxy \
--cap-add=NET_BIND_SERVICE \
kproxy:latest- CA Private Keys - Keep CA keys secure with 600 permissions
- Policy Access - Restrict write access to
/etc/kproxy/policies/ - Bypass Domains - Always bypass banking and OCSP domains
- Log Retention - Implement appropriate retention policies
- Network Security - Firewall the metrics endpoint (9090)
- Regular Updates - Keep KProxy, Redis, and Go dependencies updated
- Verify KProxy is listening:
sudo netstat -tulpn | grep :53 - Check firewall rules allow DNS traffic
- Test DNS resolution:
dig @kproxy-ip example.com - Check logs:
sudo journalctl -u kproxy -f
- Verify root CA is installed on client (see CA Installation Guide)
- Check CA certificate paths in config
- Test certificate:
openssl x509 -in /etc/kproxy/ca/root-ca.crt -text -noout
- Validate Rego syntax:
opa test /etc/kproxy/policies/ -v - Check logs for OPA compilation errors
- Test policy locally:
opa eval -d /etc/kproxy/policies/ -i input.json "data.kproxy.proxy.decision"
- Add device MAC/IP to
policies/config.rego - Check DHCP leases in Redis:
redis-cli KEYS "kproxy:dhcp:*" - Enable debug logging in config
Test your policies before deploying:
# Run policy tests
opa test /etc/kproxy/policies/ -v
# Evaluate a specific query
echo '{"client_ip": "192.168.1.100", "host": "youtube.com"}' | \
opa eval -d /etc/kproxy/policies/ -I -f pretty "data.kproxy.proxy.decision"# Install dependencies
go mod download
# Build
make build
# Run tests
make test
# Run linters
make lint
# Test OPA policies
opa test policies/kproxy/
├── cmd/kproxy/ # Main entry point
├── internal/
│ ├── ca/ # Certificate authority
│ ├── config/ # Configuration loader
│ ├── dns/ # DNS server
│ ├── metrics/ # Prometheus metrics
│ ├── policy/ # Policy engine & OPA integration
│ ├── proxy/ # HTTP/HTTPS proxy
│ ├── storage/ # Storage interface & Redis impl
│ └── usage/ # Usage tracking
├── policies/ # OPA Rego policies
│ ├── config.rego # Central configuration
│ ├── device.rego # Device identification
│ ├── dns.rego # DNS decisions
│ ├── proxy.rego # Proxy decisions
│ └── helpers.rego # Utility functions
├── configs/ # Configuration examples
└── docs/ # Documentation
- Policy Tutorial - Step-by-step guide to writing KProxy policies
- CA Installation Guide - Install root CA on various platforms
- OPA Documentation - Official OPA docs
- Rego Playground - Test Rego policies online
- CLAUDE.md - Development guide for contributors
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests (Go tests + OPA policy tests)
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
- Open Policy Agent - Policy engine
- miekg/dns - DNS library
- Redis - Operational data storage
- Prometheus - Monitoring and metrics
- Issues: https://github.com/goodtune/kproxy/issues
- Discussions: https://github.com/goodtune/kproxy/discussions
Note: KProxy is designed for home network parental controls. Always respect privacy and legal requirements in your jurisdiction.
