7 releases
Uses new Rust 2024
0.1.8 | Apr 4, 2025 |
---|---|
0.1.7 | Apr 4, 2025 |
#258 in Unix APIs
600 downloads per month
82KB
1K
SLoC
Packet Router, Network Manager and IP monitor
This document outlines a unified network management service written in Rust. It monitors network interface IP address changes and dynamically updates nftables
sets accordingly. Optionally, it can also monitor Docker container lifecycle events and track their IP addresses. It is designed for Linux systems (Ubuntu/Debian) using nftables
.
Prerequisites
- Rust Toolchain: Install Rust (https://rustup.rs/).
- nftables: Ensure
nftables
is installed and running.sudo apt update && sudo apt install nftables sudo systemctl enable nftables sudo systemctl start nftables
- Build Essentials: Required for compiling dependencies.
sudo apt install build-essential pkg-config libmnl-dev
- (Optional) Docker Socket Access: For Docker container monitoring, the user running the service needs read access to the Docker daemon socket (typically
/var/run/docker.sock
). This might involve adding the user to thedocker
group.
Overview and Rationale
The network manager service is responsible for:
- Dynamic Monitoring: Detecting real-time changes to network interfaces and IP addresses using Netlink.
- Firewall Coordination: Automatically updating predefined
nftables
IP sets based on thenftables_zone
configured for each monitored interface. - Configuration: Loading interface monitoring configurations from a YAML file.
- Control: Accepting basic commands via a Unix domain socket.
- (Optional) Docker Event Monitoring: Tracking container start/stop events and their associated IP addresses.
This Rust implementation provides memory safety, improved concurrency handling, and maintainability.
Implementation Details
Core Components
- Main Daemon (
src/main.rs
): Central process coordinating all activities, handling signals, and managing the main event loop. - Configuration Parser (
src/config.rs
): Handles loading and validating network configuration from/etc/rust-network-mgr/config.yaml
or a path specified byRUST_NETWORK_MGR_CONFIG
. - Network Monitor (
src/network.rs
): Usesrtnetlink
to detect IP address and interface changes, emitting events. - NFTables Manager (
src/nftables.rs
): Interacts withnftables
via therustables
crate to update IP sets based on network state. Assumes basenftables
ruleset (specifically tableinet filter
) and the relevant sets (e.g.,wan_ips
,lan_ips
) are already defined. - Control Socket (
src/socket.rs
): Listens on/run/rust-network-mgr.sock
for commands (reload
,status
,ping
). - Docker Monitor (
src/docker.rs
): (Optional) Connects to the Docker daemon socket using thebollard
crate. Listens for containerstart
,stop
, anddie
events. Inspects started containers to retrieve their IP addresses and updates the application's internal state. Fails gracefully if the Docker socket is inaccessible.
graph TD
A[Main Daemon] --> B(Configuration Parser)
A --> C(Network Monitor)
A --> D(NFTables Manager)
A --> E(Control Socket)
A --> J(Docker Monitor)
subgraph "Input/Output"
F[YAML Config] --> B
G[System Netlink] <--> C
H[nftables API] <--> D
I[Unix Socket Commands] <--> E
K[Docker Daemon Socket] <--> J
end
C -- IP/Interface Events --> A
J -- Docker Events --> A
A -- Update Sets --> D
E -- Control Commands --> A
Core Functional Requirements
- IP Address Monitoring: Detect interface IP additions/removals via Netlink.
- Atomic NFTables Set Updates: Reliably update configured
nftables
sets (e.g.,inet filter/wan_ips
) when corresponding interface IPs change. Usesrustables
for atomic updates. - Configuration Parsing: Load interface configurations specifying DHCP status, static addresses (optional), and the target
nftables_zone
. - Socket Control: Accept
reload
,status
,ping
commands. - (Optional) Docker IP Tracking: Maintain an internal map of running container IDs to their discovered IP addresses.
Example Configuration (/etc/rust-network-mgr/config.yaml
)
```yaml
interfaces:
- name: eth0 # Interface name
dhcp: true # Monitor DHCP addresses for this interface
nftables_zone: wan # Maps to nftables set 'wan_ips' in table 'inet filter'
- name: eth1 address: 192.168.1.1/24 # Optional static address info (not currently used for monitoring logic) nftables_zone: lan # Maps to nftables set 'lan_ips' in table 'inet filter'
... other interfaces
### NFTables Setup Example
This service *expects* a base `nftables` configuration to exist. It only manages the *elements* within predefined sets.
Example base `/etc/nftables.conf` snippet:
```nftables
table inet filter {
set wan_ips {
type ipv4_addr
flags dynamic
}
set lan_ips {
type ipv4_addr
flags dynamic
}
chain input {
type filter hook input priority 0; policy accept;
# Example rule using the set
ip saddr @wan_ips counter drop
}
# ... other chains and rules
}
Directory Structure
rust-network-mgr/
├── Cargo.toml
├── src/
│ ├── main.rs
│ ├── network.rs
│ ├── nftables.rs
│ ├── config.rs
│ ├── socket.rs
│ ├── docker.rs # Docker monitoring module
│ └── types.rs
├── tests/
│ ├── basic_tests.rs
│ └── nftables_manager_tests.rs # Requires root/nftables access
├── pkg-files/
│ ├── systemd/
│ │ └── rust-network-mgr.service # Example systemd unit
│ └── config/
│ └── default.yaml # Example config
└── README.md
Key Rust Dependencies (Current)
[dependencies]
# Core Async/Runtime
tokio = { version = "1", features = ["full"] }
futures = "0.3"
# Network Monitoring
rtnetlink = "0.16.0"
netlink-packet-route = "0.22.0"
# NFTables Interaction
rustables = "0.8.6"
# Docker Interaction (Optional Feature)
bollard = "0.15"
# Configuration
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9"
directories = "5.0" # For finding config dirs
# Error Handling & Logging
anyhow = "1.0"
thiserror = "1.0"
log = "0.4"
env_logger = "0.10" # Or tracing/tracing-subscriber
# Utilities
nix = "0.27.1" # For Unix socket permissions
(See Cargo.toml
for the definitive list)
Build, Test, and Run
- Build:
cargo build --release
(Binary attarget/release/rust-network-mgr
) - Test:
cargo test
(Some tests requiresudo
andnftables
)- Run ignored tests:
sudo cargo test -- --ignored
- Run ignored tests:
- Lint:
cargo clippy
- Format:
cargo fmt
- Run:
- Ensure
/etc/rust-network-mgr/config.yaml
exists or setRUST_NETWORK_MGR_CONFIG
. - (Docker) Ensure the service user has permissions for
/var/run/docker.sock
if Docker monitoring is desired. - Run directly (requires privileges for Netlink/nftables/Docker):
sudo target/release/rust-network-mgr
- Use the example systemd service: Copy
pkg-files/systemd/rust-network-mgr.service
to/etc/systemd/system/
, thensudo systemctl daemon-reload
,sudo systemctl start rust-network-mgr
. Check status withsudo systemctl status rust-network-mgr
and logs withsudo journalctl -u rust-network-mgr -f
.
- Ensure
Control Socket Usage
# Send commands using socat (install if needed: sudo apt install socat)
echo "status" | sudo socat - UNIX-CONNECT:/run/rust-network-mgr.sock
echo "reload" | sudo socat - UNIX-CONNECT:/run/rust-network-mgr.sock
echo "ping" | sudo socat - UNIX-CONNECT:/run/rust-network-mgr.sock
Development Priorities & Scope
- Reliability: Ensure correct behavior under various network conditions.
- Correctness: Accurately update
nftables
sets based on monitored IPs. - Simplicity: Maintain a focused scope on coordinating Netlink events with
nftables
set updates. Optional features like Docker monitoring should be self-contained and fail gracefully. - Testability: Design components for unit and integration testing.
Current Scope: This tool focuses primarily on monitoring interface IPs via Netlink and updating pre-existing nftables
sets based on a simple configuration map (nftables_zone
). It does not manage nftables
rules, tables, or chains beyond adding/removing IPs from sets. The optional Docker monitoring currently tracks container IPs internally but does not yet integrate them into nftables
rules.
Potential Future Features / Roadmap
While the core focus is narrow, future enhancements could include:
- More sophisticated
nftables
interaction (e.g., managing rules directly). - IPv6 support in
nftables
sets. - Docker Integration Enhancements:
- Using discovered container IPs in
nftables
rules/sets (e.g., based on container labels or predefined mappings). - Monitoring Docker network attach/detach events for more granular IP tracking.
- Using discovered container IPs in
- More detailed status reporting via the control socket (e.g., listing tracked container IPs).
(These are ideas, not commitments. Development follows the priorities above.)
Dependencies
~26–41MB
~668K SLoC