Docs Read captures from archives

Read captures from archives

Read a compressed tar of captures or a password-protected ZIP or 7z where it is, give sipnab the password from a file, a password manager, a systemd credential or the terminal, and read what it skipped.

On this page

Captures often arrive packed: a .tgz of a ring buffer, a password-protected ZIP from a carrier, a 7z from an incident-response team. Point -I at the archive and sipnab reads every capture inside, in capture order, as if you had unpacked it into a directory. It leaves no decrypted copy behind.

Before you start

  • A build with archive for ZIP and 7z. Every release binary and package has it, the static musl tarballs and the -noaudio packages included. Check that archive is in the features: list of sipnab --version. tar, .tgz and gzip need no feature.
  • No privileges. Reading an archive is reading a file.
  • No change on any other system. sipnab reads the archive as it arrived.

What ran: every command and output on this page ran on 2026-11-03 with sipnab 0.5.232 built from source. GNU tar, Info-ZIP zip -e and 7-Zip 25.01 (7z a -tzip -mem=AES256, 7z a -mhe=on) made the archives from two captures: sample-call.pcap (see Triage a capture from the command line) and a second one-call capture, sip-call.pcap.

Read a tar or a .tgz

sipnab -N -I session.tgz --report --no-cli-print

Read the lines sipnab prints before the report. They account for every member:

WARN sipnab::capture::input_set: Skipping 'session.tgz/notes.txt': not a capture (starts with 63 61 6c 6c, which is not pcap or pcapng)
WARN sipnab::capture::input_set: Skipping 'session.tgz/evidence.zip/sample-call.pcap': encrypted, and no password was supplied (--archive-password-file, --archive-password-command, --archive-password-stdin, or the prompt)
WARN sipnab::capture::input_set: Skipping 'session.tgz/evidence.zip/sip-call.pcap': encrypted, and no password was supplied (--archive-password-file, --archive-password-command, --archive-password-stdin, or the prompt)
INFO sipnab::capture::input_set: 'session.tgz' unpacked (gzip > tar > gzip): 2 capture(s) to read, 3 member(s) not read, 1 directory entr(ies)
WARN sipnab::capture::input_set: -I resolved to 2 capture file(s), 3 archive member(s) not read (each named above with its reason)

This archive held a ring buffer of two captures, one of them gzip-compressed, a text note, and a password-protected ZIP:

  • The two captures joined the set, and sipnab read them in capture order, whatever their names.
  • gzip > tar > gzip names the layers sipnab unwrapped, outermost first. It goes up to four layers deep and recognizes each by its bytes, not its name.
  • sipnab names the note and the locked ZIP’s members with the reason it did not read them. The run went on with the rest.
  • --input-name reads only the members whose file name matches, as it does in a directory: --input-name 'a.pcap'.

Read a password-protected ZIP or 7z

Give sipnab the password, and it reads the members as it reads a tar’s. Keep the password off the command line: this section lists the sources best first.

From a file

The file holds one password per line. sipnab refuses a file that other users can read:

sipnab -N -I evidence.zip --archive-password-file pcaps.pw --report --no-cli-print
--archive-password-file 'pcaps.pw' can be read or written by other users (mode 0644); chmod 600 it

That run exited 2. After chmod 600 pcaps.pw, the same command read both members:

INFO sipnab::privilege: Core dumps disabled (decryption active)
INFO sipnab::capture::input_set: 'evidence.zip' unpacked (zip): 2 capture(s) to read, 0 member(s) not read, 0 directory entr(ies)
INFO sipnab::app::batch: sipnab: 640 packets captured, 40 SIP messages, 600 RTP packets across 2 streams

sipnab accepts a file another user owns, such as a Kubernetes secret mount. --archive-password-file <(pass show pcaps/lab) keeps the password off the disk.

From a password manager

sipnab runs the command without a shell and uses the first line it prints:

sipnab -N -I evidence.7z --archive-password-command 'pass show pcaps/lab' --report --no-cli-print

A run whose command printed the 7z’s password read both members:

INFO sipnab::capture::input_set: 'evidence.7z' unpacked (7z): 2 capture(s) to read, 0 member(s) not read, 0 directory entr(ies)

From stdin, for a CI job

printf '%s\n' "$PCAP_PW" | sipnab -N -I evidence.zip --archive-password-stdin --report --no-cli-print

From a systemd credential, for a service

When $CREDENTIALS_DIRECTORY/archive-password exists, sipnab reads it as a password file. In a unit, that is one line:

LoadCredential=archive-password:/etc/sipnab/pcaps.pw

The same setting on a transient unit read the ZIP with no password flag at all:

systemd-run --user --wait --pipe -p LoadCredential=archive-password:/etc/sipnab/pcaps.pw \
  sipnab -N -I /srv/captures/evidence.zip --no-password-prompt --report --no-cli-print
INFO sipnab::capture::input_set: '/srv/captures/evidence.zip' unpacked (zip): 2 capture(s) to read, 0 member(s) not read, 0 directory entr(ies)

From the environment, or the command line

SIPNAB_ARCHIVE_PASSWORD works, but every child process inherits it. --archive-password works too, and sipnab warns on every use, because other users can read it in ps:

WARN sipnab::capture::archive::password: WARNING! Using --archive-password on the command line is insecure: other local users can read it in `ps`, and it is saved in shell history. Use --archive-password-stdin, --archive-password-file or --archive-password-command.

At the terminal

With no password configured, or none that opens a member, sipnab asks on the terminal, three times per archive:

sipnab -N -I evidence.7z --report --no-cli-print
Password for evidence.7z (member (the archive), attempt 1 of 3):
Wrong password. Password for evidence.7z (member (the archive), attempt 2 of 3):
  • It reads /dev/tty, so it asks even with stdin redirected, and echoes nothing.
  • An empty entry skips that archive’s locked members. Ctrl-C stops the run with exit 130.
  • A 7z made with -mhe=on encrypts its member list too, so the prompt names the archive rather than a member.
  • With no terminal (cron, CI, an agent), or with --no-password-prompt, sipnab never asks and never waits.
  • The TUI asks in a popup instead (Archive password popup).

Over REST

A client of the REST API’s capture comparison may send a password for one request in a header. sipnab accepts it from a client on the same host only, unless you start sipnab with --api-accept-archive-passwords:

printf 'Sipnab-Archive-Password: %s\n' "$(pass show pcaps/lab)" \
  | curl -s -H @- "http://127.0.0.1:18080/v1/captures/compare?a=evidence.zip&b=sample-call.pcap" | jq .a
{"filename":"evidence.zip","packets":640,"dialogs":8,"streams":2,"dialogs_dropped":0}

Without the header, the same request answered that the archive had no readable capture, naming each member encrypted_no_password. GET /v1/captures/compare gives the rules. MCP takes no archive password on any tool: an agent’s open_capture uses the passwords the operator configured.

Check that it worked

  • The unpacked line counts what sipnab reads and what it does not.

  • Every member it did not read has its own Skipping line.

  • A run that read nothing from an archive named with -I exits 1, naming each member with its reason code:

    -I/--input: cannot read capture 'evidence.7z' named with -I: no readable capture in it (evidence.7z: encrypted_wrong_password)
    
  • A run that read some members exits 0. The closing -I resolved to line counts the rest.

When something does not work

What sipnab saysWhyWhat to do
encrypted, and no password was suppliedNo source gave a password, and there was no terminal to ask onAdd --archive-password-file or another source
encrypted, and no password supplied opens itEvery password tried was wrongCheck the password. For a ZIP from an old Windows tool, try --archive-password-encoding cp437
can be read or written by other users (mode 0644); chmod 600 it, exit 2The password file is not privatechmod 600 it
uses ZipCrypto, which does not protect its contentsThe ZIP uses the legacy cipher (Info-ZIP’s zip -e does)sipnab reads it. Ask the sender to re-encrypt with AES-256
xz data, which sipnab does not unwrap (or zstd, bzip2, LZ4)A compression sipnab does not readUnpack that member with its own tool, then point -I at the result
decompressing reached the N-byte ceilingThe archive inflates past --max-gunzip-bytes (1 GiB)For an archive you trust, raise it
could not be read past this point, INCOMPLETE RUN, exit 1The archive stops earlysipnab kept what arrived. Fetch the archive again
has link type N, which sipnab does not decodeA member is not an IP capture, such as an LTE MAC logNothing: its frames count as not decoded

Archives and Archives read like directories give every rule: nesting, member names, ceilings, and where the unpacked copies live while a run reads them.