Passer au contenu principal

RustNet : moniteur réseau TUI avec attribution par processus et DPI

Romain Grosos

Le diagnostic réseau en temps réel reste un angle mal couvert dans la boîte à outils sysops standard. ss -tupn donne les ports ouverts. tcpdump capte les paquets bruts. Aucun des deux ne répond à la question « quel processus fait quoi, vers où, avec quel protocole applicatif ? » en un seul affichage live. RustNet (domcyrus, MIT) comble précisément ce vide depuis une TUI utilisable en SSH, sans forwarding X11 ni capture à analyser en post-mortem.

Pourquoi maintenant

Deux tendances convergent. L'écosystème Rust a produit ces dernières années une série d'outils TUI qui réinventent des classiques C : ripgrep, fd, bat, trippy, bandwhich. Dénominateur commun : sécurité mémoire par construction, binaire statique sans dépendance système, cross-platform. En parallèle, la surface à surveiller dans les infras self-hostées a augmenté. Une douzaine de conteneurs Docker génèrent des connexions sortantes difficiles à auditer : quel service « offline » appelle une API externe ? Quel conteneur résout des noms DNS inattendus ? Les outils existants répondent à cette question partiellement et séparément. RustNet tente d'y répondre dans un affichage unique.

Fonctionnalités techniques

Attribution processus

C'est la feature qui justifie l'existence du projet. Wireshark voit des paquets, pas des sockets. netstat/ss voient des sockets, pas le trafic en cours. RustNet associe chaque connexion réseau à un PID et au nom du processus propriétaire.

Sur Linux, deux modes coexistent :

  • eBPF (défaut sur Linux 5.8+) : programmes kernel attachés aux syscalls tcp_connect, udp_sendmsg, etc. Overhead minimal, capture des processus de courte durée que le polling procfs manquerait. Contrainte : le champ comm kernel est limité à 16 caractères. Firefox s'affiche comme Socket Thread ou Web Content selon le thread actif.
  • procfs (fallback) : scan de /proc/net/tcp + /proc/<pid>/fd/. Noms complets, overhead CPU plus élevé. RustNet bascule automatiquement si les capabilities eBPF font défaut, et affiche le mode actif dans le panneau statistiques.

Sur macOS, PKTAP extrait les métadonnées processus directement depuis le kernel (PID + nom complet sans troncature). Sur Windows, l'attribution par processus reste expérimentale.

Deep Packet Inspection

RustNet effectue un DPI applicatif sur le trafic capturé via libpcap. Les protocoles détectés :

  • HTTP : avec extraction du host header
  • TLS/HTTPS : avec extraction du SNI. Les connexions vers api.github.com apparaissent avec ce hostname, pas l'IP nue
  • QUIC : suivi des phases (QUIC_INITIAL, QUIC_HANDSHAKE, QUIC_CONNECTED) et détection des frames CONNECTION_CLOSE
  • DNS : requêtes et réponses en temps réel
  • SSH : avec détection de version
  • NTP, mDNS, LLMNR, DHCP, SNMP, SSDP, NetBIOS : visibilité sur le trafic de découverte local souvent ignoré

Le SNI TLS est transmis en clair dans le ClientHello. RustNet ne déchiffre rien, mais identifie l'hôte destination même sur des connexions HTTPS. Pour la plupart des cas d'audit, c'est suffisant.

Gestion des états et timeouts

RustNet maintient un état par connexion avec des timeouts protocol-aware : SSH 30 min, HTTP/HTTPS 10 min, DNS 30 sec, TIME_WAIT 30 sec. Les connexions approchant l'expiration changent de couleur (blanc, jaune, rouge) avant suppression automatique.

L'état interne repose sur un DashMap (hashmap concurrente à shards, sans verrou global), partagé entre les N threads de traitement de paquets (4 par défaut) et le thread UI via un snapshot périodique sous RwLock.

Filtrage interactif

Le filtrage est vim/fzf-style, appliqué en temps réel :

port:443
src:10.0.0
sni:github.com
process:nginx
state:ESTABLISHED

Les filtres sont cumulables et s'appliquent à la volée sans redémarrage.

Export PCAP enrichi

--pcap-export <file> génère un fichier .pcap standard ouvrable dans Wireshark, accompagné d'un sidecar .jsonl avec les métadonnées PID/processus par connexion. Le script scripts/pcap_enrich.py fusionne les deux, pour obtenir dans Wireshark le contexte processus complet que Wireshark seul ne peut pas fournir (il voit des paquets, pas des sockets).

Comparaison avec les outils existants

OutilAttribution processusDPITUI SSHPlateformes
ss / netstatPartielleNonOuiLinux/BSD
nethogsOuiNonOuiLinux uniquement
iftopNonNonOuiLinux/BSD
bandwhich (Rust)Oui (agrégé)NonOuiLinux/macOS/Windows
Sniffnet (Rust)NonPartielNon (GUI)Linux/macOS/Windows
RustNetOui (eBPF/procfs/PKTAP)OuiOuiLinux/macOS/Windows/FreeBSD

bandwhich est le concurrent le plus direct sur la partie attribution par processus, mais son focus est la bande passante agrégée, pas la visibilité connexion par connexion avec DPI. Les deux sont complémentaires.

Sniffnet propose des alertes configurables et une interface graphique, utiles pour une supervision continue ou une présentation non-technique. RustNet est plus orienté debugging ponctuel en SSH.

nethogs reste pertinent pour un usage rapide (présent dans les dépôts des distros majeures), mais sans DPI et limité à Linux.

Utilisation terrain

Installation Linux avec capabilities :

# Via crates.io
cargo install rustnet-monitor

# Via PPA Ubuntu 25.10+, COPR Fedora 42+, pacman Arch Linux
# Voir INSTALL.md pour les détails distro

# Capabilities recommandées (sans sudo)
sudo setcap 'cap_net_raw,cap_bpf,cap_perfmon=eip' $(which rustnet)
rustnet

cap_net_admin n'est pas requis. La capture est read-only, non-promiscuous. Sur les kernels antérieurs à 5.8, cap_sys_admin remplace cap_bpf + cap_perfmon.

Cas d'usage courants :

  • Audit service suspect : filtre process:nom-service pour voir toutes les connexions sortantes avec SNI et ports
  • Debug TLS : filtre sni: pour identifier les endpoints réels d'un service (utile pour valider qu'un SDK analytics ne contacte pas un CDN externe non attendu)
  • Surveillance DNS : sans filtre, la colonne DPI remonte immédiatement les requêtes DNS, y compris les lookups mDNS et LLMNR souvent ignorés
  • Monitoring Docker : rustnet -i docker0 pour le bridge Docker ; une image Docker officielle est disponible pour les environnements conteneurisés
  • Forensique : rustnet --pcap-export /tmp/capture.pcap --json-log /tmp/events.jsonl, puis analyse dans Wireshark avec enrichissement PID

La troncature à 16 caractères des noms de processus en mode eBPF est une contrainte du champ comm kernel, pas un choix de conception RustNet. Pour les applications multi-threadées (navigateurs, Electron), le mode procfs donne des noms complets au prix d'un overhead CPU plus élevé. RustNet propose le flag --no-default-features à la compilation pour forcer le mode procfs exclusivement.

Le sandboxing Landlock (Linux 5.13+) est actif par défaut, ce qui restreint l'accès filesystem et réseau au minimum nécessaire. C'est une décision de sécurité pertinente pour un outil qui tourne avec des capabilities élevées et parse du trafic réseau non fiable.

Sources

GitHub - domcyrus/rustnet: A cross-platform network monitoring terminal UI tool built with Rust.
A cross-platform network monitoring terminal UI tool built with Rust. - domcyrus/rustnet
Show HN: RustNet, a network monitoring TUI with process identification | Hacker News
RustNet: Terminal-based network monitor with QUIC and TLS inspection - looking for feedback and Windows contributors
by u/hubabuba44 in rust
RustNet - Monitor what your self-hosted services are actually doing on the network
by u/hubabuba44 in selfhosted
rustnet - A cross-platform network monitoring TUI tool. - Terminal Trove
A cross-platform network monitoring TUI tool.