bluebox 0.1.2

A fast DNS interceptor and cache for local networks
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
# Bluebox

A fast, transparent DNS interceptor for local networks. Bluebox acts as a parental control / ad-blocking DNS filter that works **without requiring any client configuration**.

## Features

- **Transparent DNS Interception**: Uses ARP spoofing to intercept DNS queries from all devices on the network
- **Domain Blocking**: Block domains by exact match or wildcard patterns (e.g., `*.ads.com`)
- **Response Caching**: Caches DNS responses to improve performance
- **Zero Client Configuration**: Devices don't need any DNS settings changed
- **Traffic Forwarding**: Non-DNS traffic is forwarded to the real gateway transparently
- **Graceful Shutdown**: Restores ARP tables when stopping to avoid network disruption

## How It Works

```
┌─────────────────────────────────────────────────────────────────┐
│                        Local Network                            │
│                                                                 │
│  ┌──────────┐     ┌──────────┐     ┌──────────┐                │
│  │  Phone   │     │  Laptop  │     │  Tablet  │                │
│  └────┬─────┘     └────┬─────┘     └────┬─────┘                │
│       │                │                │                       │
│       │    DNS queries (port 53)        │                       │
│       └────────────────┼────────────────┘                       │
│                        │                                        │
│                        ▼                                        │
│              ┌─────────────────┐                                │
│              │    Bluebox      │◄─── ARP: "I am the gateway"   │
│              │  (Raspberry Pi) │                                │
│              └────────┬────────┘                                │
│                       │                                         │
│         ┌─────────────┴─────────────┐                          │
│         │                           │                          │
│         ▼                           ▼                          │
│  ┌─────────────┐           ┌───────────────┐                   │
│  │ DNS blocked │           │ Forward other │                   │
│  │ → localhost │           │ traffic to    │                   │
│  │             │           │ real gateway  │                   │
│  │ DNS allowed │           └───────┬───────┘                   │
│  │ → upstream  │                   │                           │
│  └─────────────┘                   ▼                           │
│                            ┌──────────────┐                    │
│                            │   Router     │                    │
│                            │  (Gateway)   │                    │
│                            └──────────────┘                    │
└─────────────────────────────────────────────────────────────────┘
```

### ARP Spoofing Explained

1. **Discovery**: Bluebox discovers the gateway (router) IP and MAC address
2. **ARP Poisoning**: Periodically sends ARP replies to all devices claiming to be the gateway
3. **Interception**: Devices send their traffic to Bluebox thinking it's the gateway
4. **DNS Filtering**: DNS queries (port 53) are intercepted and filtered
5. **Forwarding**: All other traffic is forwarded to the real gateway

## Installation

### Prerequisites

- Root/sudo privileges (required for raw packet capture and ARP)
- Linux (Debian/Ubuntu for .deb packages)

### Pre-built Binaries

Download pre-built binaries from the [Releases](https://github.com/jeremie/bluebox/releases) page:

| Platform | Binary | Notes |
|----------|--------|-------|
| Linux x86_64 (glibc) | `bluebox-linux-amd64` | Standard Linux |
| Linux aarch64 (glibc) | `bluebox-linux-arm64` | Raspberry Pi 4+, ARM servers |
| Linux x86_64 (musl) | `bluebox-linux-amd64-musl` | Static binary, works on any Linux |
| Linux aarch64 (musl) | `bluebox-linux-arm64-musl` | Static binary for ARM |

### Debian/Ubuntu (.deb package)

The easiest way to install on Debian-based systems:

```bash
# Download the .deb for your architecture
wget https://github.com/jeremie/bluebox/releases/latest/download/bluebox_amd64.deb
# or for ARM64 (Raspberry Pi 4+)
wget https://github.com/jeremie/bluebox/releases/latest/download/bluebox_arm64.deb

# Install
sudo dpkg -i bluebox_*.deb
```

The .deb package includes:
- Binary at `/usr/bin/bluebox`
- Example config at `/etc/bluebox/config.toml`
- Systemd service file
- Dedicated `bluebox` user/group for security

After installation:
```bash
# Edit the configuration
sudo nano /etc/bluebox/config.toml

# Enable and start the service
sudo systemctl enable bluebox
sudo systemctl start bluebox
```

### Building from Source

Requirements: Rust 1.75+ (edition 2024)

```bash
git clone https://github.com/jeremie/bluebox.git
cd bluebox
cargo build --release
```

The binary will be at `target/release/bluebox`.

### Raspberry Pi Setup

1. Install Rust on your Raspberry Pi:
   ```bash
   curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
   ```

2. Clone and build:
   ```bash
   git clone https://github.com/jeremie/bluebox.git
   cd bluebox
   cargo build --release
   ```

3. Copy the binary and config:
   ```bash
   sudo cp target/release/bluebox /usr/local/bin/
   sudo mkdir -p /etc/bluebox
   sudo cp config.toml /etc/bluebox/config.toml
   ```

4. Run as a systemd service (see [Systemd Service]#systemd-service below)

Alternatively, download the pre-built `bluebox_arm64.deb` package for Raspberry Pi 4+.

## Configuration

Create a `config.toml` file:

```toml
# Network interface (optional, auto-detected if not specified)
# interface = "eth0"

# Upstream DNS resolver
upstream_resolver = "1.1.1.1:53"

# Cache TTL in seconds
cache_ttl_seconds = 300

# Domains to block (exact match or wildcard)
blocklist = [
    # Social media
    "*.facebook.com",
    "facebook.com",
    "*.instagram.com",
    "instagram.com",
    "*.tiktok.com",
    "tiktok.com",
    
    # Ads and tracking
    "*.doubleclick.net",
    "*.googlesyndication.com",
    "*.googleadservices.com",
    "*.facebook-dns.com",
    "*.adnxs.com",
]

# External blocklist sources (optional)
# Load blocklists from files or remote URLs
[[blocklist_sources]]
name = "steven-black-hosts"
enabled = true
source = { type = "remote", url = "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" }
format = "hosts"
refresh_interval_hours = 24

[[blocklist_sources]]
name = "local-custom"
enabled = true
source = { type = "file", path = "/etc/bluebox/custom-blocklist.txt" }
format = "domains"

# ARP spoofing for transparent interception
[arp_spoof]
enabled = true
# gateway_ip = "192.168.1.1"  # Optional, auto-detected
spoof_interval_secs = 2
restore_on_shutdown = true
forward_traffic = true
```

### Configuration Options

| Option | Description | Default |
|--------|-------------|---------|
| `interface` | Network interface to use | Auto-detect |
| `upstream_resolver` | Upstream DNS server | Required |
| `cache_ttl_seconds` | How long to cache DNS responses | 300 |
| `blocklist` | List of domains/patterns to block | `[]` |
| `blocklist_sources` | External blocklist sources (see below) | `[]` |
| `buffer_pool_size` | Size of packet buffer pool | 64 |
| `channel_capacity` | Packet queue capacity | 1000 |

### Blocklist Sources

You can load blocklists from local files or remote URLs. Each source has the following options:

| Option | Description | Default |
|--------|-------------|---------|
| `name` | Unique identifier for this source | Required |
| `enabled` | Whether to use this source | `true` |
| `source.type` | `file` or `remote` | Required |
| `source.path` | Path to local file (for `file` type) | - |
| `source.url` | URL to fetch (for `remote` type) | - |
| `format` | File format: `domains`, `hosts`, or `adblock` | `domains` |
| `refresh_interval_hours` | How often to refresh remote sources | - |

**Supported formats:**
- `domains` - One domain per line
- `hosts` - Standard hosts file format (e.g., `0.0.0.0 example.com`)
- `adblock` - AdBlock filter syntax (future support)

### ARP Spoof Options

| Option | Description | Default |
|--------|-------------|---------|
| `enabled` | Enable transparent interception | `false` |
| `gateway_ip` | Gateway IP to impersonate | Auto-detect |
| `spoof_interval_secs` | Seconds between ARP packets | 2 |
| `restore_on_shutdown` | Restore ARP tables on exit | `true` |
| `forward_traffic` | Forward non-DNS traffic | `true` |

## Usage

### Basic Usage (Passive Mode)

Without ARP spoofing, devices must be configured to use Bluebox as their DNS server:

```bash
sudo ./bluebox
```

### Transparent Mode (ARP Spoofing)

With ARP spoofing enabled, no client configuration is needed:

```bash
# Edit config.toml to enable arp_spoof
sudo ./bluebox
```

### Systemd Service

If you installed via the .deb package, the systemd service is already set up. Just enable and start it:

```bash
sudo systemctl enable bluebox
sudo systemctl start bluebox
sudo systemctl status bluebox
```

For manual installations, create `/etc/systemd/system/bluebox.service`:

```ini
[Unit]
Description=Bluebox DNS Interceptor and Cache
Documentation=https://github.com/jeremie/bluebox
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=bluebox
Group=bluebox
ExecStart=/usr/bin/bluebox --config /etc/bluebox/config.toml
Restart=on-failure
RestartSec=5

# Security hardening
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/var/cache/bluebox

# Required for binding to port 53 and ARP spoofing
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_NET_ADMIN

[Install]
WantedBy=multi-user.target
```

You'll also need to create the user and directories:

```bash
sudo addgroup --system bluebox
sudo adduser --system --ingroup bluebox --no-create-home --home /var/cache/bluebox bluebox
sudo mkdir -p /var/cache/bluebox
sudo chown bluebox:bluebox /var/cache/bluebox
```

Then enable and start:

```bash
sudo systemctl daemon-reload
sudo systemctl enable bluebox
sudo systemctl start bluebox
```

## Architecture

```
src/
├── main.rs              # Entry point, orchestration
├── lib.rs               # Library exports
├── config.rs            # Configuration loading
├── error.rs             # Error types
├── dns/
│   ├── blocker.rs       # Domain blocking logic
│   └── resolver.rs      # Upstream DNS resolution
├── cache/
│   └── dns_cache.rs     # Response caching (Moka)
├── network/
│   ├── arp.rs           # ARP spoofing
│   ├── forward.rs       # Traffic forwarding
│   ├── capture.rs       # Packet capture (pnet)
│   ├── packet.rs        # Packet construction
│   └── buffer.rs        # Buffer pooling
└── server.rs            # Query handling
```

### Design Principles

- **Trait-based abstractions**: All components have traits for easy testing/mocking
- **Minimal allocations**: Buffer pooling to reduce heap allocations
- **Async I/O**: Tokio for efficient async operations
- **Zero-copy where possible**: Direct packet manipulation

## Testing

```bash
# Run all tests
cargo test

# Run with logging
RUST_LOG=debug cargo test

# Run benchmarks
cargo bench
```

## Security Considerations

- **Root Required**: Bluebox needs root privileges for raw packet capture and ARP
- **Network Scope**: Only use on networks you own or have permission to manage
- **ARP Spoofing**: This technique is commonly used for parental controls and enterprise monitoring, but could be misused - use responsibly
- **Graceful Shutdown**: Always let Bluebox shut down gracefully (Ctrl+C) to restore ARP tables

## Roadmap

### Implemented
- [x] DNS query interception and filtering
- [x] Domain blocking (exact + wildcard)
- [x] Response caching with TTL
- [x] ARP spoofing for transparent interception
- [x] Traffic forwarding for non-DNS packets
- [x] Gateway auto-detection
- [x] Graceful shutdown with ARP restoration
- [x] External blocklist sources (file and remote URL)
- [x] Multiple blocklist formats (domains, hosts, adblock)

### Planned
- [ ] Web UI for configuration and statistics
- [ ] Per-device policies (allow/block specific devices)
- [ ] DNS-over-HTTPS (DoH) upstream support
- [ ] Statistics and logging dashboard
- [ ] Scheduled blocking (e.g., no social media 9pm-7am)
- [ ] DHCP server mode (alternative to ARP spoofing)
- [ ] IPv6 support for ARP spoofing (NDP)

## Troubleshooting

### "Failed to find network interface"

Make sure you're running as root:
```bash
sudo ./bluebox
```

### "Failed to detect gateway"

Manually specify the gateway in config:
```toml
[arp_spoof]
enabled = true
gateway_ip = "192.168.1.1"  # Your router's IP
```

### Devices lose internet after starting Bluebox

This usually means traffic forwarding isn't working. Check:
1. `forward_traffic = true` in config
2. The gateway MAC was discovered (check logs for "Discovered gateway MAC")
3. IP forwarding is enabled: `sudo sysctl net.ipv4.ip_forward=1`

### Network doesn't recover after stopping Bluebox

If you kill Bluebox with `kill -9` instead of Ctrl+C, ARP tables won't be restored. Fix by:
```bash
# Clear ARP cache on affected devices, or
# Restart their network interface, or
# Wait for ARP cache to expire (usually 1-5 minutes)
```

## License

MIT

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.