Skip to content

the-shadow-0/PortPulse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

41 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

⚑ PortPulse

See every Linux process, port, connection, and DNS lookup live in one interactive map.

License: MIT Rust eBPF PRs Welcome GitHub Stars

πŸ” What process is talking? 🌐 To which domain? πŸšͺ Through which port? ⚠️ With what risk?


🎬 See it in Action

PortPulse Demo

30-second demo: status check β†’ port explanation β†’ process tracing β†’ live TUI dashboard


πŸ“Š Dashboard Preview

PortPulse Dashboard

Real-time dashboard: connections, DNS queries, timeline, and suspicious activity β€” all in one view


πŸš€ Why PortPulse?

Linux debugging is fragmented. You juggle between ss, netstat, lsof, DNS logs, process trees, and firewall rules β€” all disconnected, all manual.

PortPulse unifies everything into a single real-time command center:

Traditional Way PortPulse Way
ss -tupn + lsof -i + dig portpulse live
Manually correlating PIDs to connections Auto-correlated process β†’ port β†’ domain mapping
No risk assessment Built-in heuristic risk scoring (0.0 β†’ 1.0)
Separate tools for each task One unified TUI with 5 views
No DNS visibility Real-time DNS query capture
No container awareness Docker/Kubernetes container detection

πŸ’‘ Think of PortPulse as htop for your network β€” but with risk intelligence and eBPF superpowers.


⚑ Quickstart

# Install from source
git clone https://github.com/the-shadow-0/PortPulse.git
cd PortPulse && cargo install --path crates/cli

# Launch the dashboard (use sudo for eBPF probes)
sudo portpulse live

# Or without root (fallback mode)
portpulse live --no-ebpf

That's it. Two commands to full network visibility.


✨ Features

🌐 Live Process-to-Port Mapping

See every active connection with its owning process, user, container, and domain in real-time.

πŸ” DNS Query Capture

Catch every DNS resolution as it happens β€” see which process queried what domain, when, and what it resolved to.

⚠️ Risk Scoring Engine

Every connection is scored from 0.0 (safe) to 1.0 (critical) using heuristics:

  • Suspicious TLDs (.tk, .ml, .xyz)
  • Known bad ports (4444, 31337, 6667)
  • Domain entropy (DGA detection)
  • DNS tunneling patterns
  • Unknown/unnamed processes
  • Root processes on non-standard ports

πŸ”΄ Suspicious Lane

A persistent alert bar at the top of the screen highlighting high-risk connections with blinking indicators.

⚑ Animated Connection Graph

The WOW feature β€” processes and domains connected by live-updating edges:

  • Blue for normal connections
  • Pulsing red for suspicious activity
  • Port labels at edge midpoints
  • Legend with node type icons
Connection Graph

Interactive connection graph: processes ↔ domains with live risk coloring

🌳 Process Tree View

Hierarchical view of processes with tree-drawing characters, showing connection counts per process.

πŸ“‹ Timeline

Chronological log of all network events: connections opened/closed, DNS queries, policy violations.

πŸ›‘οΈ Policy Engine

Define custom rules:

  • "Never talk to domain X"
  • "Alert on port 4444"
  • "Block IP range 10.0.0.0/8"
  • "Alert when process Y makes connections"

πŸ”’ Quarantine Mode

Generate nftables rules to block suspicious domains:

portpulse quarantine --domain evil.tk

πŸ“Š Export System

Export to JSON or CSV for SIEM integration:

portpulse export --format json --what connections -o report.json

πŸ“Έ Screenshots

Dashboard View

Dashboard

Unified dashboard: connections table, DNS log, and timeline in one split view

Connection Graph

Connection Graph

Animated graph showing process→domain connections with risk-colored edges

Connection Detail

Connection Detail

Deep-dive into a suspicious connection: risk score breakdown with actionable reasons


πŸ–₯️ CLI Commands

portpulse live                       # Interactive TUI dashboard
portpulse live --threshold 0.3       # Lower suspicious threshold
portpulse live --no-ebpf             # Force /proc fallback mode

portpulse trace --pid 1234           # Trace a specific process
portpulse trace --pid 1234 -c        # Include child processes

portpulse explain 443                # What's using port 443?
portpulse explain 4444               # Why is port 4444 suspicious?

portpulse quarantine -d evil.tk      # Generate blocking rules
portpulse export -f csv -w all       # Export everything as CSV

portpulse status                     # Check eBPF & system status

⌨️ Keyboard Shortcuts

Key Action
1 β€” 5 Switch panels (Dashboard, Connections, DNS, Processes, Graph)
Tab Cycle through panels
j / ↓ Move selection down
k / ↑ Move selection up
Enter Open detail view for selected connection
/ Filter by process name, domain, or port
s Toggle sort direction
Esc Back / close detail view
q Quit PortPulse

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                       User Interface                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚   TUI   β”‚  β”‚   CLI    β”‚  β”‚  Export   β”‚  β”‚   Policy     β”‚ β”‚
β”‚  β”‚ ratatui β”‚  β”‚   clap   β”‚  β”‚ JSON/CSV β”‚  β”‚   Engine     β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚       β”‚            β”‚             β”‚                β”‚          β”‚
β”‚  β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚                    Core Engine                          β”‚ β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚ β”‚
β”‚  β”‚  β”‚ Aggregator β”‚  β”‚ Classifier β”‚  β”‚   Event Bus      β”‚  β”‚ β”‚
β”‚  β”‚  β”‚ (correlate)β”‚  β”‚ (risk)     β”‚  β”‚ (tokio broadcast)β”‚  β”‚ β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                         β”‚                                    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚                Event Source Layer                        β”‚ β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚  β”‚  β”‚  eBPF Probes     β”‚    β”‚  /proc/net Fallback        β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  (kprobes, tp)   β”‚    β”‚  (tcp, udp, tcp6, udp6)    β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  via Aya         β”‚    β”‚  + /proc/*/fd inode scan   β”‚ β”‚ β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  β”‚                    Linux Kernel                           β”‚
β”‚  β”‚  tcp_v4_connect Β· inet_csk_accept Β· udp_sendmsg         β”‚
β”‚  β”‚  tcp_set_state  Β· /proc/net/*     Β· socket inodes       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

βš™οΈ Tech Stack

Component Technology Why
Core Rust Zero-cost abstractions, memory safety, blazing performance
Kernel Probes eBPF (via Aya) Safe kernel-level tracing without kernel modules
Terminal UI Ratatui + Crossterm Modern TUI framework with rich widgets and canvas
Async Runtime Tokio High-throughput concurrent event processing
CLI Clap Ergonomic argument parsing with color output
Serialization Serde Fast JSON/CSV export

🎯 Use Cases

πŸ” Incident Response

"Something is phoning home from this server β€” what process, what domain, when did it start?"

sudo portpulse live --threshold 0.3

🐳 Container Debugging

"Which container is making unexpected network calls?"

PortPulse detects Docker/containerd containers automatically via cgroup analysis.

πŸ›‘οΈ Security Audit

"Show me all connections to non-standard ports by root processes."

Use the filter (/) and sort (s) in the TUI to drill down instantly.

πŸ“Š Compliance Reporting

"Export all network activity for audit review."

portpulse export --format csv --what all -o audit-report.csv

πŸ› Dev Debugging

"Why is my app connecting to this IP? What DNS resolution led there?"

portpulse trace --pid $(pgrep myapp) --children
portpulse explain 8080

πŸ“¦ Installation

From Source (Recommended)

git clone https://github.com/the-shadow-0/PortPulse.git
cd PortPulse
cargo install --path crates/cli

One-Line Install

curl -sSf https://raw.githubusercontent.com/the-shadow-0/PortPulse/main/scripts/install.sh | bash

Package Managers (Coming Soon)

# Homebrew
brew install portpulse

# Arch Linux (AUR)
yay -S portpulse

# Debian/Ubuntu
sudo dpkg -i portpulse_0.1.0_amd64.deb

🀝 Contributing

We welcome contributions! See CONTRIBUTING.md for details.

Please read our Code of Conduct before participating.

Good First Issues

  • Add more port descriptions to the explain command
  • Add IPv6 support to the connection graph
  • Implement sort-by-column in the connections table
  • Add configurable color themes
  • Write more unit tests for the classifier

Plugin Ideas

  • Prometheus metrics exporter
  • Elasticsearch/OpenSearch sink
  • Slack/Discord alerting
  • Custom DNS resolvers
  • GeoIP enrichment module

πŸ” Security

  • Local-first: All data stays on your machine. No telemetry, no phone-home.
  • Read-only eBPF: Probes are strictly observational β€” they cannot modify kernel state.
  • No payload capture: PortPulse captures metadata (IPs, ports, PIDs) β€” never packet contents.
  • Privilege separation: eBPF requires root; the TUI can run unprivileged with /proc fallback.
  • Audit logging: Every policy violation is logged with timestamps and evidence.

For vulnerability reporting, see SECURITY.md.


πŸ’¬ Community


πŸ“„ License

MIT License β€” see LICENSE for details.


⚑ Built with Rust, eBPF, and ❀️ for the open-source community.

If PortPulse helped you, consider giving it a ⭐ β€” it means the world to us!

⬆ Back to top