Skip to content

Commit 5a059a3

Browse files
authored
feat: add Landlock sandbox and capability dropping for Linux (#86)
* feat: add Landlock sandbox and capability dropping for Linux - Restrict filesystem access to /proc only after initialization - Block TCP bind/connect on kernel 6.4+ (network sandbox) - Drop CAP_NET_RAW after pcap handle opened - Add --no-sandbox and --sandbox-strict CLI options - Show privilege info on non-Linux platforms in UI - Add SECURITY.md documentation * fix: remove unused set_sandbox_info and hide Landlock line on non-Linux * fix: gate SandboxInfo to Linux only to fix clippy warnings * fix: add is_admin() function for Windows builds The Windows build was failing because ui.rs called crate::is_admin() but the function didn't exist. Added the implementation using Windows Security API to check if the process has elevated privileges. Also added Win32_Security feature to windows crate dependencies. * fix: add is_admin() to main.rs for Windows binary crate The previous fix added is_admin() to lib.rs but ui.rs is compiled as part of the binary crate (main.rs), not the library crate. Added the function to main.rs so crate::is_admin() resolves correctly.
1 parent dd0b7e0 commit 5a059a3

16 files changed

Lines changed: 1023 additions & 79 deletions

File tree

ARCHITECTURE.md

Lines changed: 3 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This document describes the technical architecture and implementation details of
99
- [Platform-Specific Implementations](#platform-specific-implementations)
1010
- [Performance Considerations](#performance-considerations)
1111
- [Dependencies](#dependencies)
12-
- [Security Considerations](#security-considerations)
12+
- [Security](#security)
1313

1414
## Multi-threaded Architecture
1515

@@ -315,78 +315,6 @@ RustNet is built with the following key dependencies:
315315
- **ring** - Cryptographic operations (for TLS/SNI parsing)
316316
- **aes** - AES encryption support (for protocol detection)
317317

318-
## Security Considerations
318+
## Security
319319

320-
### Privileged Access
321-
322-
RustNet requires privileged access for packet capture:
323-
- **Raw socket access** - Intercept network traffic at low level (read-only, non-promiscuous mode)
324-
- **BPF device access** - Load packet filters into kernel
325-
- **eBPF programs** - Optional kernel probes for enhanced process tracking (Linux only)
326-
327-
**Mitigation:**
328-
- Use Linux capabilities instead of full root (CAP_NET_RAW for packet capture, CAP_BPF+CAP_PERFMON for eBPF)
329-
- Use macOS group-based access (`access_bpf` group)
330-
- Audit which users have packet capture permissions
331-
- Operates in read-only mode - cannot modify or inject packets
332-
333-
### Read-Only Operation
334-
335-
The tool only monitors traffic; it does not:
336-
- Modify packets
337-
- Block connections
338-
- Inject traffic
339-
- Alter routing tables
340-
- Change firewall rules
341-
342-
### Log File Privacy
343-
344-
Log files may contain sensitive information:
345-
- IP addresses and ports
346-
- Hostnames and SNI data
347-
- Process names and PIDs
348-
- DNS queries and responses
349-
350-
**Best Practices:**
351-
- Disable logging by default (no `--log-level` flag)
352-
- Secure log directory permissions
353-
- Implement log rotation and retention policies
354-
- Review logs for sensitive data before sharing
355-
356-
### No External Communication
357-
358-
RustNet operates entirely locally:
359-
- No telemetry or analytics
360-
- No network requests (except monitored traffic)
361-
- No cloud services or remote APIs
362-
- All data stays on your system
363-
364-
### eBPF Security
365-
366-
When using experimental eBPF support:
367-
- Requires additional kernel capabilities (`CAP_BPF`, `CAP_PERFMON`)
368-
- eBPF programs are verified by kernel before loading
369-
- Limited to read-only operations (no packet modification)
370-
- Automatically falls back to procfs if eBPF fails
371-
372-
### Audit and Compliance
373-
374-
For production environments:
375-
- **Audit logging** of who runs RustNet with packet capture privileges
376-
- **Network monitoring policies** and compliance with data protection regulations
377-
- **User access reviews** for privileged network access
378-
- **Automated capability management** via configuration management systems
379-
380-
### Threat Model
381-
382-
**What RustNet protects against:**
383-
- Unauthorized users cannot capture packets without proper permissions
384-
- Capability-based permissions limit blast radius of compromise
385-
386-
**What RustNet does NOT protect against:**
387-
- Users with packet capture permissions can see all unencrypted traffic
388-
- Root/Administrator users can modify RustNet or capture packets directly
389-
- Physical access to the machine enables packet capture
390-
- Network-level attacks (RustNet is a monitoring tool, not a security appliance)
391-
392-
For detailed permission setup and security best practices, see [INSTALL.md](INSTALL.md).
320+
For security documentation including Landlock sandboxing, privilege requirements, and threat model, see [SECURITY.md](SECURITY.md).

Cargo.lock

Lines changed: 42 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ procfs = "0.18"
4848
libbpf-rs = { version = "0.25", optional = true }
4949
bytes = { version = "1.11", optional = true }
5050
libc = { version = "0.2", optional = true }
51+
landlock = { version = "0.4", optional = true }
52+
caps = { version = "0.5", optional = true }
5153

5254
[target.'cfg(any(target_os = "macos", target_os = "freebsd"))'.dependencies]
5355
libc = "0.2"
@@ -58,6 +60,7 @@ windows = { version = "0.62", features = [
5860
"Win32_NetworkManagement_IpHelper",
5961
"Win32_NetworkManagement_Ndis",
6062
"Win32_Networking_WinSock",
63+
"Win32_Security",
6164
"Win32_System_LibraryLoader",
6265
"Win32_System_Threading",
6366
] }
@@ -80,6 +83,7 @@ windows = { version = "0.62", features = [
8083
"Win32_NetworkManagement_IpHelper",
8184
"Win32_NetworkManagement_Ndis",
8285
"Win32_Networking_WinSock",
86+
"Win32_Security",
8387
"Win32_System_LibraryLoader",
8488
"Win32_System_Threading",
8589
] }
@@ -91,9 +95,11 @@ libbpf-cargo = { version = "0.25", optional = true }
9195
# eBPF is enabled by default for enhanced performance on Linux.
9296
# On non-Linux platforms, this feature has no effect as all eBPF code
9397
# and dependencies are Linux-specific (guarded by target_os checks).
94-
default = ["ebpf"]
98+
# Landlock provides security sandboxing on Linux 5.13+.
99+
default = ["ebpf", "landlock"]
95100
linux-default = ["ebpf"] # Deprecated: kept for backwards compatibility
96101
ebpf = ["libbpf-rs", "bytes", "libc", "dep:libbpf-cargo"]
102+
landlock = ["dep:landlock", "dep:caps"]
97103

98104
# Minimal cross configuration to override dependency conflicts
99105
[workspace.metadata.cross.build.env]

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ A cross-platform network monitoring tool built with Rust. RustNet provides real-
2626
- **Terminal User Interface**: Beautiful TUI built with ratatui with adjustable column widths
2727
- **Multi-threaded Processing**: Concurrent packet processing for high performance
2828
- **Optional Logging**: Detailed logging with configurable log levels (disabled by default)
29+
- **Security Sandboxing**: Landlock-based filesystem/network restrictions on Linux 5.13+ (see [SECURITY.md](SECURITY.md))
2930

3031
<details>
3132
<summary><b>eBPF Enhanced Process Identification (Linux Default)</b></summary>
@@ -232,6 +233,7 @@ See [USAGE.md](USAGE.md) for complete timeout details.
232233

233234
- **[INSTALL.md](INSTALL.md)** - Detailed installation instructions for all platforms, permission setup, and troubleshooting
234235
- **[USAGE.md](USAGE.md)** - Complete usage guide including command-line options, filtering, sorting, and logging
236+
- **[SECURITY.md](SECURITY.md)** - Security features including Landlock sandboxing and privilege management
235237
- **[ARCHITECTURE.md](ARCHITECTURE.md)** - Technical architecture, platform implementations, and performance details
236238
- **[PROFILING.md](PROFILING.md)** - Performance profiling guide with flamegraph setup and optimization tips
237239
- **[ROADMAP.md](ROADMAP.md)** - Planned features and future improvements

SECURITY.md

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Security
2+
3+
RustNet processes untrusted network data, making defense-in-depth security critical. This document describes the security measures implemented.
4+
5+
## Table of Contents
6+
7+
- [Landlock Sandboxing (Linux)](#landlock-sandboxing-linux)
8+
- [Privilege Requirements](#privilege-requirements)
9+
- [Read-Only Operation](#read-only-operation)
10+
- [No External Communication](#no-external-communication)
11+
- [Log File Privacy](#log-file-privacy)
12+
- [eBPF Security](#ebpf-security)
13+
- [Threat Model](#threat-model)
14+
- [Audit and Compliance](#audit-and-compliance)
15+
- [Reporting Security Issues](#reporting-security-issues)
16+
17+
## Landlock Sandboxing (Linux)
18+
19+
On Linux 5.13+, RustNet uses [Landlock](https://landlock.io/) to restrict its own capabilities after initialization. This limits the damage if a vulnerability in packet parsing is exploited.
20+
21+
### What Gets Restricted
22+
23+
| Restriction | Kernel Version | Description |
24+
|-------------|----------------|-------------|
25+
| Filesystem | 5.13+ | Only `/proc` readable (for process identification) |
26+
| Network | 6.4+ | TCP bind/connect blocked (RustNet is passive) |
27+
| Capabilities | Any | `CAP_NET_RAW` dropped after pcap socket opened |
28+
29+
### How It Works
30+
31+
1. **Initialization phase**: RustNet loads eBPF programs, opens packet capture handles, and creates log files
32+
2. **Sandbox application**: After init, Landlock restricts filesystem and network access
33+
3. **Capability drop**: `CAP_NET_RAW` is removed from the process (existing pcap socket remains valid)
34+
35+
### Security Benefits
36+
37+
If an attacker exploits a vulnerability in DPI/packet parsing:
38+
- Cannot read arbitrary files (credentials, configs, etc.)
39+
- Cannot write to filesystem (except configured log paths)
40+
- Cannot make outbound TCP connections (data exfiltration blocked)
41+
- Cannot bind TCP ports (reverse shell blocked)
42+
- Cannot create new raw sockets (capability dropped)
43+
44+
### CLI Options
45+
46+
```
47+
--no-sandbox Disable Landlock sandboxing
48+
--sandbox-strict Require full sandbox enforcement or exit
49+
```
50+
51+
### Graceful Degradation
52+
53+
- **Kernel < 5.13**: Sandboxing skipped, warning logged
54+
- **Kernel 5.13-6.3**: Filesystem restrictions only
55+
- **Kernel 6.4+**: Full filesystem + network restrictions
56+
- **Docker**: May be blocked by seccomp; app continues normally
57+
58+
## Privilege Requirements
59+
60+
RustNet requires privileged access for packet capture:
61+
62+
| Platform | Requirement |
63+
|----------|-------------|
64+
| Linux | `CAP_NET_RAW` capability or root |
65+
| macOS | Root or BPF group membership (`access_bpf` group) |
66+
| Windows | Administrator (for Npcap) |
67+
| FreeBSD | Root or BPF device access |
68+
69+
### Why Privileges Are Needed
70+
71+
- **Raw socket access** - Intercept network traffic at low level (read-only, non-promiscuous mode)
72+
- **BPF device access** - Load packet filters into kernel
73+
- **eBPF programs** - Optional kernel probes for enhanced process tracking (Linux only)
74+
75+
### Recommended: Capability-based Execution (Linux)
76+
77+
Instead of running as root, grant only the required capabilities:
78+
79+
```bash
80+
# Modern Linux (5.8+): packet capture + eBPF
81+
sudo setcap 'cap_net_raw,cap_bpf,cap_perfmon=eip' $(which rustnet)
82+
83+
# Legacy Linux (pre-5.8): packet capture + eBPF
84+
sudo setcap 'cap_net_raw,cap_sys_admin=eip' $(which rustnet)
85+
86+
# Packet capture only (no eBPF process detection)
87+
sudo setcap cap_net_raw=eip $(which rustnet)
88+
```
89+
90+
After sandbox application, `CAP_NET_RAW` is dropped - the process retains only the minimum privileges needed.
91+
92+
## Read-Only Operation
93+
94+
RustNet only monitors traffic; it does not:
95+
- Modify packets
96+
- Block connections
97+
- Inject traffic
98+
- Alter routing tables
99+
- Change firewall rules
100+
101+
The packet capture is opened in non-promiscuous, read-only mode.
102+
103+
## No External Communication
104+
105+
RustNet operates entirely locally:
106+
- No telemetry or analytics
107+
- No network requests (except monitored traffic)
108+
- No cloud services or remote APIs
109+
- All data stays on your system
110+
111+
## Log File Privacy
112+
113+
Log files may contain sensitive information:
114+
- IP addresses and ports
115+
- Hostnames and SNI data
116+
- Process names and PIDs
117+
- DNS queries and responses
118+
119+
**Best Practices:**
120+
- Disable logging by default (no `--log-level` flag)
121+
- Secure log directory permissions
122+
- Implement log rotation and retention policies
123+
- Review logs for sensitive data before sharing
124+
125+
## eBPF Security
126+
127+
When using eBPF for enhanced process detection (default on Linux):
128+
129+
- Requires additional kernel capabilities (`CAP_BPF`, `CAP_PERFMON`)
130+
- eBPF programs are verified by kernel before loading
131+
- Limited to read-only operations (no packet modification)
132+
- Automatically falls back to procfs if eBPF fails
133+
134+
## Threat Model
135+
136+
**What RustNet protects against:**
137+
- Unauthorized users cannot capture packets without proper permissions
138+
- Capability-based permissions limit blast radius of compromise
139+
- Landlock sandbox contains potential exploitation
140+
141+
**What RustNet does NOT protect against:**
142+
- Users with packet capture permissions can see all unencrypted traffic
143+
- Root/Administrator users can modify RustNet or capture packets directly
144+
- Physical access to the machine enables packet capture
145+
- Network-level attacks (RustNet is a monitoring tool, not a security appliance)
146+
147+
## Audit and Compliance
148+
149+
For production environments:
150+
- **Audit logging** of who runs RustNet with packet capture privileges
151+
- **Network monitoring policies** and compliance with data protection regulations
152+
- **User access reviews** for privileged network access
153+
- **Automated capability management** via configuration management systems
154+
155+
## Reporting Security Issues
156+
157+
Please report security vulnerabilities via GitHub Issues or contact the maintainers directly.

USAGE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ Options:
7878
-r, --refresh-interval <MILLISECONDS> UI refresh interval in milliseconds [default: 1000]
7979
--no-dpi Disable deep packet inspection
8080
-l, --log-level <LEVEL> Set the log level (if not provided, no logging will be enabled)
81+
--json-log <FILE> Enable JSON logging of connection events to specified file
82+
--no-sandbox Disable Landlock sandboxing (Linux only)
83+
--sandbox-strict Require full sandbox enforcement or exit (Linux only)
8184
-h, --help Print help
8285
-V, --version Print version
8386
```

0 commit comments

Comments
 (0)