Skip to content

Installation

github-actions[bot] edited this page Jul 29, 2026 · 1 revision

Prerequisites

  • Rust 1.97+ (for building from source)
  • libpcap headers (libpcap-dev on Debian/Ubuntu, libpcap-devel on RHEL/Fedora)
  • pkg-config (for libpcap detection during build)

Installer (recommended)

One command on Linux (x86_64/aarch64) or macOS:

curl -fsSL https://www.sipnab.com/install.sh | sh

The install script detects your OS, CPU architecture, and glibc version, downloads the matching versioned release tarball (sipnab-<version>-<target-triple>.tar.gz) together with its .sha256 file, verifies the checksum, and installs the binary to /usr/local/bin (using sudo only if that directory isn't writable). Prefer to read it first: https://www.sipnab.com/install.sh.

Two environment variables tune it. To pin a specific version instead of taking whatever the latest release is:

curl -fsSL https://www.sipnab.com/install.sh | SIPNAB_VERSION=0.5.59 sh

To install somewhere other than /usr/local/bin — a directory you already own, so no root is involved:

curl -fsSL https://www.sipnab.com/install.sh | SIPNAB_INSTALL_DIR="$HOME/.local/bin" sh

On Linux the installer chooses between two build variants: the dynamically linked -gnu build (requires glibc >= 2.36 — Debian 12+, Ubuntu 23.04+ — and libpcap installed via your package manager) and the static musl build (no glibc/libpcap requirement; TUI audio playback unavailable, everything else identical). The 2.36 figure is the floor the release workflow actually enforces on every gnu binary, and the installer now uses that same cutover — it serves musl only to hosts below glibc 2.36, or with no glibc at all. It previously cut over at 2.39 for eleven releases, so hosts between 2.36 and 2.39 (Debian 12 among them) received the static build and lost TUI audio even though the gnu build ran there fine.

Pre-built Binaries

Every GitHub release ships versioned tarballs per target triple, each with a matching .sha256 checksum file:

  • sipnab-<version>-x86_64-unknown-linux-gnu.tar.gz — dynamic, needs glibc >= 2.36 + libpcap
  • sipnab-<version>-aarch64-unknown-linux-gnu.tar.gz — same, for arm64
  • sipnab-<version>-x86_64-unknown-linux-musl.tar.gz — static, runs on any glibc (no TUI audio)
  • sipnab-<version>-aarch64-unknown-linux-musl.tar.gz — same, for arm64
  • sipnab-<version>-x86_64-apple-darwin.tar.gz / sipnab-<version>-aarch64-apple-darwin.tar.gz — macOS

The unknown in x86_64-unknown-linux-gnu is the vendor field of the Rust target triple (arch-vendor-os-abi) — the canonical value meaning "no specific vendor", which is why the macOS files say apple in that position. It is part of the platform name, not a failed detection or a broken build. Names are kept as the canonical triple deliberately: they match rustc -vV, they are what SHA256SUMS.txt and the build-provenance attestation cover, and the install script constructs them.

Architecture naming: x86_64 = amd64 (Intel/AMD), aarch64 = arm64 (ARM); tarballs use the former, .deb packages the latter. uname -m tells you which one you are.

On Linux x86_64, the static musl tarball runs on any distro and any glibc, Alpine included. Replace <version> with the latest, e.g. 0.5.59:

# Run all of these, in order.
curl -LO https://github.com/NormB/sipnab/releases/download/v<version>/sipnab-<version>-x86_64-unknown-linux-musl.tar.gz
tar xzf sipnab-<version>-x86_64-unknown-linux-musl.tar.gz
sudo install -m 755 sipnab-<version>-x86_64-unknown-linux-musl/sipnab /usr/local/bin/sipnab

The same three steps on Linux aarch64, against the aarch64 musl tarball:

# Run all of these, in order.
curl -LO https://github.com/NormB/sipnab/releases/download/v<version>/sipnab-<version>-aarch64-unknown-linux-musl.tar.gz
tar xzf sipnab-<version>-aarch64-unknown-linux-musl.tar.gz
sudo install -m 755 sipnab-<version>-aarch64-unknown-linux-musl/sipnab /usr/local/bin/sipnab

Manual download with checksum verification (replace <version> with the latest, e.g. 0.5.59):

# Run all of these, in order.
V=<version> T=x86_64-unknown-linux-gnu
curl -LO "https://github.com/NormB/sipnab/releases/download/v$V/sipnab-$V-$T.tar.gz"
curl -LO "https://github.com/NormB/sipnab/releases/download/v$V/sipnab-$V-$T.tar.gz.sha256"
sha256sum -c "sipnab-$V-$T.tar.gz.sha256"
tar -xzf "sipnab-$V-$T.tar.gz"   # unpacks into ./sipnab-$V-$T/
sudo install -m 755 "sipnab-$V-$T/sipnab" /usr/local/bin/sipnab

The dynamic …-unknown-linux-gnu.tar.gz builds add TUI audio playback but require glibc >= 2.36 (Debian 12+, Ubuntu 23.04+) and libpcap. That floor is enforced, not estimated: the gnu targets build inside a Debian bookworm container and a release-workflow gate rejects any binary linking a newer GLIBC_ symbol. On an older distro they fail with version `GLIBC_2.36' not found -- use the static musl build.

Cargo (from source)

cargo install sipnab --features full

On Alpine or any musl target, --features full will not give you audio. The playback plugin is loaded with dlopen, and static musl has no dynamic loader — it returns "Dynamic loading not supported". The build succeeds and the binary reports audio in --version, but playback can never work. Build without the audio feature, or build dynamically linked (RUSTFLAGS="-C target-feature=-crt-static" plus apk add alsa-lib alsa-lib-dev), which is Alpine-only. See the site's Build from Source page for both recipes.

Package Managers

Debian/Ubuntu (.deb)

Download the .deb for your architecture from the latest release and install with apt (it resolves the libpcap0.8 runtime dependency). The .deb needs glibc >= 2.36, i.e. Debian 12+ / Ubuntu 23.04+ -- on older releases use the static musl tarball above.

Download and install the amd64 (x86_64) package — replace <version> with the latest, e.g. 0.5.59:

# Run all of these, in order.
curl -LO https://github.com/NormB/sipnab/releases/latest/download/sipnab_<version>_amd64.deb
sudo apt install ./sipnab_<version>_amd64.deb

On an arm64 (aarch64) host, take the arm64 package instead — installing the wrong-architecture .deb over the right one leaves you with a binary that will not run:

# Run all of these, in order.
curl -LO https://github.com/NormB/sipnab/releases/latest/download/sipnab_<version>_arm64.deb
sudo apt install ./sipnab_<version>_arm64.deb

The package installs /usr/bin/sipnab, the man page, and a systemd unit, and creates a sipnab system user for privilege dropping. On Ubuntu 24.04+ the dependency is satisfied by libpcap0.8t64.

The standard package ships the audio playback plugin and therefore Recommends libasound2, which apt installs by default — pulling the ALSA stack (~500 kB) onto the system. For headless servers, each release also publishes a -noaudio package with no plugin and no ALSA dependency (everything else — WAV export included — works the same; only live playback in the TUI is unavailable).

The headless amd64 (x86_64) package:

# Run all of these, in order.
curl -LO https://github.com/NormB/sipnab/releases/latest/download/sipnab_<version>_amd64-noaudio.deb
sudo apt install ./sipnab_<version>_amd64-noaudio.deb

The headless arm64 (aarch64) package, for arm64 hosts:

# Run all of these, in order.
curl -LO https://github.com/NormB/sipnab/releases/latest/download/sipnab_<version>_arm64-noaudio.deb
sudo apt install ./sipnab_<version>_arm64-noaudio.deb

Alternatively, install the standard package with sudo apt install --no-install-recommends ./sipnab_<version>_amd64.deb to skip the ALSA packages while keeping the plugin on disk (playback then works as soon as libasound2 is installed).

RHEL/Fedora (.rpm)

.rpm packages ship per release for x86_64 and aarch64, each in a standard and a -noaudio variant (no audio plugin, no alsa-lib weak dependency — for headless servers, mirroring the .deb variants).

The standard package on an x86_64 host:

sudo rpm -i sipnab-0.5.59-1.x86_64.rpm

The headless / no-ALSA variant on the same architecture:

sudo rpm -i sipnab-0.5.59-1.x86_64-noaudio.rpm

The standard package on an aarch64 (arm64) host — pick the variant matching uname -m:

sudo rpm -i sipnab-0.5.59-1.aarch64.rpm

Homebrew (macOS)

brew install sipnab

Building from Source

Install from a checkout, with capabilities

cargo install has no post-install hook, so a source install leaves you to run --setup-caps yourself. scripts/install-from-source.sh does both:

# Run all of these, in order.
git clone https://github.com/NormB/sipnab.git
cd sipnab
./scripts/install-from-source.sh --features full

It runs cargo install --path . --bin sipnab (forwarding any arguments), then on Linux invokes the binary's own --setup-caps so live capture works without sudo. Non-Linux platforms skip the capability step and are told to use sudo.

This is a source install and is distinct from the one-line installer at https://www.sipnab.com/install.sh, which downloads a prebuilt release binary and compiles nothing.

Basic build (TUI only, default features)

# Run all of these, in order.
git clone https://github.com/NormB/sipnab.git
cd sipnab
cargo build --release
sudo cp target/release/sipnab /usr/local/bin/

Full-features build

cargo build --release --features full

Debug build with logging

SIPNAB_LOG=trace cargo run -- -N -I test.pcap

Verifying a Download

Every release artifact is checksummed, signed with sigstore build provenance, and accompanied by a CycloneDX SBOM. The installer script verifies the sha256 for you; these steps are for manual downloads, mirrors, and anything that reached you by a route you did not choose.

Checksum. SHA256SUMS.txt covers every tarball, .deb, .rpm, and SBOM in the release:

sha256sum -c SHA256SUMS.txt --ignore-missing

Provenance. A checksum only proves the file matches the list; it says nothing about who produced the list. The attestation is cryptographic proof the artifact was built by sipnab's own release workflow, from a specific commit:

gh attestation verify sipnab-<version>-x86_64-unknown-linux-gnu.tar.gz \
    --repo NormB/sipnab

This is what detects a rehosted or tampered copy, including one served with a matching checksum file.

This needs gh 2.49 or newer — check with gh --version. The subcommand did not exist before then, and distributions lag: Ubuntu 24.04 ships 2.45, where the command prints unknown command "attestation" followed by the general help text and still exits 0. Piped or scripted, that reads as success while verifying nothing. Install a current gh from https://github.com/cli/cli/releases rather than trusting a silent pass.

Dependencies. Two CycloneDX SBOMs ship with each release:

File Covers
sipnab-<version>.cdx.json the sipnab binary
sipnab-audio-<version>.cdx.json libsipnab_audio.so, the playback plugin

There are two because the plugin is a separate crate loaded at runtime with dlopen, and it brings in dependencies — alsa, cpal, rodio among them — that appear nowhere in the binary's own graph. Scanning only the first would quietly miss them. Feed either to any CycloneDX-aware scanner:

grype sbom:sipnab-<version>.cdx.json      # or trivy sbom, osv-scanner, ...

The binary SBOM is generated with all features enabled, so it is a superset of what any single published binary contains — it will never under-report.

Live Capture Permissions

Reading a pcap file needs no special permissions at all. Live capture (sipnab -d <iface> or the default any device) needs libpcap and raw-socket access. Rather than running the whole TUI as root, grant the binary the Linux capabilities once and then run it as your normal user:

sudo sipnab --setup-caps
# equivalent to: sudo setcap cap_net_raw,cap_net_admin+ep $(command -v sipnab)

--setup-caps runs setcap on the sipnab binary (re-invoking through sudo itself when not already root) and exits. After that, run sipnab without sudo:

sipnab            # live capture works; no sudo needed

Prefer this to sudo sipnab. When started as root, sipnab opens the capture device and then drops privileges to an unprivileged user (nobody by default, or --user <name>). That dropped user usually cannot read your home directory, so the in-TUI file browser (O) comes up empty — it will show a "run without sudo" message explaining why. Running unprivileged with capabilities avoids this entirely. (Re-running --setup-caps is needed after each reinstall, since replacing the file clears its capabilities.)

macOS and other non-Linux platforms have no file capabilities; run live capture under sudo there.

Feature Flags

sipnab uses Cargo feature flags to control optional functionality. The default build includes native, tui, audio, and metrics.

Feature Description Dependencies
native Live capture, file capture, output writers, signal handling, CLI parser. Required (directly or transitively) by tui, hep, metrics, api, mcp, and mcp-http; not required by tls, audio, or wasm. Included by default. pcap, clap, crossbeam-channel, libc, pcap-file, tracing-subscriber, tracing-log
tui Interactive terminal UI (ratatui + crossterm). Included by default. native, ratatui, crossterm, unicode-width
audio RTP audio playback in the TUI + WAV export. Included by default. Builds the separate sipnab-audio plugin (libsipnab_audio.so) that the binary dlopens lazily; the binary itself does not link libasound.so.2. libloading, libc (plugin: rodio)
tls TLS/DTLS decryption and SRTP key extraction (pure Rust) ring, rustls, aes, cbc, zeroize
hep HEP v3 send + v2/v3 receive (Homer Encapsulation Protocol) native
api REST API + Prometheus metrics endpoint native, axum, tokio
mcp Model Context Protocol server, stdio transport. Lets an AI agent (Claude Code, Claude Desktop, …) drive sipnab. native, tokio, rmcp
mcp-http MCP server over HTTP (Streamable-HTTP). Adds the --mcp-transport http option. mcp, api, rmcp/transport-streamable-http-server
metrics Standalone Prometheus /metrics server: a raw TCP listener and plain threads, no axum/tokio, so scraping does not drag in the api feature or its async runtime. Included by default. native, base64
full Everything: native + tui + audio + tls + hep + api + mcp + mcp-http + metrics all
wasm WebAssembly target for in-browser pcap analysis wasm-bindgen toolchain

Build with specific features. For the TUI plus TLS decryption and nothing else:

cargo build --release --features tui,tls

For a headless capture host — HEP listener, REST API, and MCP over HTTP, with no TUI and no audio:

cargo build --release --no-default-features --features native,hep,api,mcp,mcp-http

For everything:

cargo build --release --features full

libasound.so.2 is now an optional runtime dependency. The audio feature builds a separate plugin, libsipnab_audio.so, installed to /usr/lib/sipnab/ by the .deb (or placed next to the binary in dev builds). The sipnab binary dlopens this plugin only when you actually play a stream, so an audio-enabled binary starts fine on a host without libasound. If libasound (or the plugin) is missing, playback returns a clear error and you can still export the stream to a WAV file (F2). On Debian/Ubuntu libasound2 is shipped as a Recommends of the package; install it for live playback. Only libpcap0.8 is a hard dependency. For a fully audio-free build, drop the audio feature and the plugin is not built.

Enabling MCP

To run sipnab as a Model Context Protocol server for an AI agent (Claude Code, Claude Desktop, …), see mcp.md, which documents building with the mcp/mcp-http features and the runtime configuration, including token-file generation and the systemd unit pattern.

Release Profile

The release build uses LTO, single codegen unit, and symbol stripping for a small binary:

[profile.release]
lto = true
codegen-units = 1
strip = true

Target binary size (musl, stripped): <= 10 MB. Enforced against the real artifact by the "Enforce published binary size" step in release.yml.

Cross-Compilation

sipnab uses cross for cross-compilation. Supported targets are configured in Cross.toml.

cross is a separate binary, so install it first:

cargo install cross

With that in place, build for aarch64 Linux:

cross build --release --features full --target aarch64-unknown-linux-gnu

Or for x86_64 Linux:

cross build --release --features full --target x86_64-unknown-linux-gnu

The cross images automatically install the required libpcap-dev headers for the target architecture.

Docker

Run from pre-built image

docker run --rm --net=host ghcr.io/normb/sipnab:latest -N -d eth0

--net=host is required for live capture. For reading pcap files, mount the file into the container:

docker run --rm -v /path/to/capture.pcap:/data/capture.pcap \
  ghcr.io/normb/sipnab:latest -N -I /data/capture.pcap

Build the Docker image locally

docker build -t sipnab .

The multi-stage Dockerfile uses rust:1.97-slim-trixie for the build stage and debian:trixie-slim for the runtime image. The runtime image includes only libpcap0.8t64 and runs as a non-root sipnab user.

Platform Notes

Linux

Full functionality. Live capture requires CAP_NET_RAW capability or root. Privilege dropping (--user) uses setuid/setgid after opening capture devices.

macOS

TUI and pcap file analysis work fully. Live capture requires root or BPF device access. Install libpcap headers via Xcode Command Line Tools (included by default) or Homebrew.

FreeBSD / Other

Should build and run. Live capture support depends on platform pcap implementation. Not regularly tested.

Verify Installation

After installing, confirm sipnab is working. Print the version, which also names the features the binary was compiled with:

sipnab --version

Print the full help, which lists every flag this build accepts:

sipnab --help

Open a capture file in the TUI, which is the quickest end-to-end test:

sipnab -I /path/to/capture.pcap

Or read the same file in CLI mode — non-interactive, first 5 dialogs:

sipnab -N -I /path/to/capture.pcap | head -5

Dump the effective config, which confirms the feature flags in a form you can paste into a bug report:

sipnab -D

--version lists the Cargo features compiled into the binary, e.g.

sipnab 0.5.59 (<hash>) features: native,tui,audio,tls,hep,api,mcp,mcp-http,metrics

This is the fastest way to confirm a build was produced with the feature set you expected (e.g. that mcp-http is present on a server build).

A first non-interactive run against a capture looks like this:

$ sipnab -N -I demo.pcap | head -3
INVITE alice -> bob  192.0.2.1:5060 -> 192.0.2.2:5060 InCall PDD=847ms
REGISTER admin -> --  192.0.2.5:5060 -> 192.0.2.1:5060 Registered
INVITE +15551234 -> +15559876  192.0.2.6:5060 -> 192.0.2.7:5060 Failed 408 Request Timeout

Next steps

Clone this wiki locally