rust-network-mgr 0.1.8

Linux based network management, packet routing and LAN peers IP monitoring service
# 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.
    ```bash
    sudo apt update && sudo apt install nftables
    sudo systemctl enable nftables
    sudo systemctl start nftables
    ```
*   **Build Essentials:** Required for compiling dependencies.
```bash
    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 the `docker` 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 the `nftables_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

1.  **Main Daemon (`src/main.rs`):** Central process coordinating all activities, handling signals, and managing the main event loop.
2.  **Configuration Parser (`src/config.rs`):** Handles loading and validating network configuration from `/etc/rust-network-mgr/config.yaml` or a path specified by `RUST_NETWORK_MGR_CONFIG`.
3.  **Network Monitor (`src/network.rs`):** Uses `rtnetlink` to detect IP address and interface changes, emitting events.
4.  **NFTables Manager (`src/nftables.rs`):** Interacts with `nftables` via the `rustables` crate to update IP sets based on network state. Assumes base `nftables` ruleset (specifically table `inet filter`) and the relevant sets (e.g., `wan_ips`, `lan_ips`) are already defined.
5.  **Control Socket (`src/socket.rs`):** Listens on `/run/rust-network-mgr.sock` for commands (`reload`, `status`, `ping`).
6.  **Docker Monitor (`src/docker.rs`):** (Optional) Connects to the Docker daemon socket using the `bollard` crate. Listens for container `start`, `stop`, and `die` events. Inspects started containers to retrieve their IP addresses and updates the application's internal state. Fails gracefully if the Docker socket is inaccessible.

```mermaid
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

1.  **IP Address Monitoring:** Detect interface IP additions/removals via Netlink.
2.  **Atomic NFTables Set Updates:** Reliably update configured `nftables` sets (e.g., `inet filter/wan_ips`) when corresponding interface IPs change. Uses `rustables` for atomic updates.
3.  **Configuration Parsing:** Load interface configurations specifying DHCP status, static addresses (optional), and the target `nftables_zone`.
4.  **Socket Control:** Accept `reload`, `status`, `ping` commands.
5.  **(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)

```toml
[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 at `target/release/rust-network-mgr`)
*   **Test:** `cargo test` (Some tests require `sudo` and `nftables`)
    *   Run ignored tests: `sudo cargo test -- --ignored`
*   **Lint:** `cargo clippy`
*   **Format:** `cargo fmt`
*   **Run:**
    *   Ensure `/etc/rust-network-mgr/config.yaml` exists or set `RUST_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/`, then `sudo systemctl daemon-reload`, `sudo systemctl start rust-network-mgr`. Check status with `sudo systemctl status rust-network-mgr` and logs with `sudo journalctl -u rust-network-mgr -f`.

### Control Socket Usage

```bash
# 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

1.  **Reliability:** Ensure correct behavior under various network conditions.
2.  **Correctness:** Accurately update `nftables` sets based on monitored IPs.
3.  **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.
4.  **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.
*   More detailed status reporting via the control socket (e.g., listing tracked container IPs).

*(These are ideas, not commitments. Development follows the priorities above.)*