seehandshake 1.0.5

Visualize TLS handshakes in your terminal, in real time.
Documentation

SeeHandshake

Visualize TLS handshakes in your terminal, in real time.

seehandshake is a passive TLS handshake observer. It captures packets on a chosen network interface, reassembles TLS records off the TCP stream, parses the plaintext portions of the handshake (TLS 1.3 ClientHello and ServerHello), and renders each connection in a three-panel Ratatui interface with an optional educational overlay that explains what each message does and why it exists.

Think of it as htop meets Wireshark meets an interactive TLS textbook.

Status

Early development. The MVP targets TLS 1.3 visualization; see the roadmap for what is coming next.

Screenshots

(Screenshots will land here once the UI stabilizes.)

What you can see, and what you cannot

TLS 1.3 encrypts every handshake message after ServerHello under keys derived from the server's ephemeral private key. A passive observer without those keys cannot decrypt EncryptedExtensions, Certificate, CertificateVerify, or Finished.

seehandshake is honest about this:

  • ClientHello and ServerHello are parsed in full (SNI, ALPN offered/chosen, cipher suites offered/chosen, supported groups, key share group, TLS version).
  • Later stages are detected from encrypted record boundaries and labeled accordingly. The certificate Subject/Issuer fields display encrypted (TLS 1.3) for pure TLS 1.3 connections.
  • The three-pane view (connections on the left, the record timeline in the middle, connection metadata or per-record sections on the right) lets you step through every TLS record on the wire in order. Arrowing into a record flips the right pane into a sectioned, educational breakdown: plaintext handshake messages are broken out field by field (random, session_id, every cipher suite with its hex code, every extension with its decoded body and raw bytes); encrypted records get an honest flight-position label (e.g. likely EncryptedExtensions + Certificate) and a ciphertext preview. Each section carries a direction hint ("You sent this" / "The server sent you this") and a short "what this is / why it matters" blurb.
  • On Linux, every row also shows the local process that opened the socket: curl (pid 1234, uid 1000) with the full cmdline, or firefox for browser flows. CLI cmdlines are the user action; browser processes identify the app, not the specific click. See docs/attribution.md.

See docs/tls13-visibility.md for the full explanation. Support for SSLKEYLOGFILE-based decryption and for TLS 1.2 (where the certificate is sent in plaintext) is planned.

Install

Live capture needs elevated privileges on every platform. After installing, see Permissions for the one extra step.

crates.io (any platform with Rust)

cargo install seehandshake

Debian / Ubuntu 24.04+ or Debian 13+ (prebuilt .deb)

Download the .deb for your architecture from the latest release, then let apt pull in the dependencies:

sudo apt install ./seehandshake_*_amd64.deb      # or _arm64.deb on ARM

Older distros (Ubuntu 22.04 and earlier) ship libpcap0.8 rather than the time64 build the .deb expects. Use cargo install seehandshake there instead.

macOS and Windows (prebuilt binaries)

Grab the archive for your platform from the latest release and extract the seehandshake binary:

  • macOS (Intel or Apple Silicon): no runtime to install; libpcap ships with the system. If Gatekeeper blocks the binary, run xattr -d com.apple.quarantine ./seehandshake.
  • Windows: install Npcap first, then run from an Administrator terminal.

From source

git clone https://github.com/AustinJAkerley/SeeHandshake.git
cd SeeHandshake
cargo install --path .

Requires:

  • Rust 1.74 or newer
  • libpcap development headers
    • Debian/Ubuntu: sudo apt install libpcap-dev
    • Fedora: sudo dnf install libpcap-devel
    • macOS: preinstalled with the system; no action needed
    • Windows: install the Npcap SDK

Package managers (in progress)

A Homebrew tap, an AUR package, and eventual submission to the official Debian archive (sudo apt install seehandshake) are planned.

Permissions

Live packet capture requires elevated privileges.

  • Linux: either run as root, or grant the binary the required capabilities:

    sudo setcap cap_net_raw,cap_net_admin=eip $(which seehandshake)
    
  • macOS: /dev/bpf* devices must be readable by the invoking user, or run with sudo.

  • Windows: install Npcap and run from an Administrator terminal.

Quickstart

seehandshake --list-interfaces        # list available interfaces
seehandshake --interface en0          # capture on en0
seehandshake                          # capture on the default interface

Then, in another terminal:

curl https://example.com

The connection will appear in the left panel; the middle panel lists every TLS record on the wire as it arrives; the right panel shows the negotiated metadata for the selected connection, including an Origin row on Linux naming the local process that owns the socket. Use / (or Tab) to move focus between panes and / to select within a pane. Arrowing through records flips the right pane into a per-record educational breakdown, one section per field/extension. Press enter (or ) to step further right; on a highlighted section it expands the long-form explanation. esc moves focus one pane left. Press e to globally toggle the educational long-form text. Press f to switch the middle pane between the record list and a Client↔Server flow diagram, d to toggle the full-screen handshake reference overlay, and w to wipe all tracked connections. Press q to quit.

Architecture

┌──────────┐   frames    ┌───────────────┐   updates    ┌────────┐
│ capture  │────────────▶│ parser+track  │─────────────▶│   UI   │
│ (pcap)   │             │ (etherparse + │              │(Ratatui)│
│          │             │  tls-parser)  │              │        │
└──────────┘             └───────────────┘              └────────┘
      ▲                          │                           │
      │                          │                           │
   PacketSource              HandshakeInfo               keyboard
   trait (swappable          (serde::Serialize:          (crossterm)
   for pcap files,           export-ready)
   test mocks)

Three threads, connected by std::sync::mpsc channels: no global mutable state, no async runtime. See docs/architecture.md.

Documentation

Contributing

See CONTRIBUTING.md and CODE_OF_CONDUCT.md.

Security

To report a vulnerability, see SECURITY.md.

Roadmap

Design decisions in the MVP already leave room for:

  • TLS 1.2 support (plaintext certificate parsing)
  • SSLKEYLOGFILE decryption
  • PCAP file import (offline analysis)
  • JSON, Markdown, and Mermaid export
  • Certificate chain visualization
  • Live traffic statistics
  • Session resumption visualization
  • Terminal themes
  • Plugin architecture

License

MIT. See LICENSE.