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 champcommkernel est limité à 16 caractères. Firefox s'affiche commeSocket ThreadouWeb Contentselon 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.comapparaissent 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:ESTABLISHEDLes 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
| Outil | Attribution processus | DPI | TUI SSH | Plateformes |
|---|---|---|---|---|
ss / netstat | Partielle | Non | Oui | Linux/BSD |
nethogs | Oui | Non | Oui | Linux uniquement |
iftop | Non | Non | Oui | Linux/BSD |
| bandwhich (Rust) | Oui (agrégé) | Non | Oui | Linux/macOS/Windows |
| Sniffnet (Rust) | Non | Partiel | Non (GUI) | Linux/macOS/Windows |
| RustNet | Oui (eBPF/procfs/PKTAP) | Oui | Oui | Linux/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)
rustnetcap_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-servicepour 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 docker0pour 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
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

