No description
  • Shell 59.5%
  • Python 22.7%
  • Dockerfile 14.5%
  • Makefile 3.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
TryAndErr0r e186b0b876 init
2026-07-23 07:01:49 +00:00
.devcontainer init 2026-07-23 07:01:49 +00:00
scripts init 2026-07-23 07:01:49 +00:00
tools init 2026-07-23 07:01:49 +00:00
.gitignore init 2026-07-23 07:01:49 +00:00
Makefile init 2026-07-23 07:01:49 +00:00
README.md init 2026-07-23 07:01:49 +00:00

wlan-recorder

Passive Wi-Fi survey and packet-recording lab for an Alfa AWUS036ACM on a Linux Docker host. It provides Kismet for environmental surveys, rotating pcapng recording with radiotap metadata, Wireshark/TShark analysis, and SQLite/CSV summaries.

The development container also includes airgeddon for interactive security audits in an isolated, explicitly authorized school lab. airgeddon is not a server; it is a root-run Bash interface which coordinates wireless auditing tools.

Only collect traffic where you own the equipment or have explicit permission. Captures can contain persistent device identifiers and private traffic even when payloads are encrypted.

Host prerequisites

  1. Install Docker and VS Code with the Dev Containers extension.

  2. Plug in the AWUS036ACM and confirm that the host sees it:

    lsusb
    iw dev
    

    The adapter normally uses the in-kernel mt76x2u driver. A common USB ID is 0e8d:7612, but hardware revisions can differ.

  3. Open this directory in VS Code and run Dev Containers: Reopen in Container.

  4. In the container, verify access:

    sudo check-adapter
    

The container installs Kismet, Wireshark/TShark/Dumpcap, Scapy, tcpdump, the Aircrack-ng utilities, airgeddon, SQLite, and the Linux wireless tools. Rebuild the container after pulling changes to the Dockerfile. Wireshark needs a graphical display forwarded into the container; TShark works in every terminal.

Quick start

The examples use the detected Alfa interface. Find the correct name with iw dev; never substitute the interface carrying your SSH or internet session.

export ALFA_IF=wlx00c0cabaa33f
make check INTERFACE="$ALFA_IF"

Start airgeddon in an authorized lab

Keep the computer online through Ethernet or its built-in Wi-Fi. airgeddon can change the selected adapter's mode and may stop processes which interfere with monitor mode, so select only the external Alfa adapter. Start its interactive menu with:

make check INTERFACE="$ALFA_IF"
make airgeddon

The image pins airgeddon v12.01 under /opt/airgeddon; rebuilding the container installs that known version. Use active features only against an isolated access point and clients owned by the project or covered by written permission. Do not test the school network itself unless the responsible administrator has explicitly approved the exact test and time window.

Survey the Wi-Fi environment

Kismet controls channel hopping, records device history, and normally exposes its UI at http://localhost:2501/. If that port is occupied, the survey picks the next available port and prints the URL. On first use, the UI asks you to create credentials; its home/configuration is retained under data/kismet/home/.

make survey INTERFACE="$ALFA_IF"

# Optionally request a different starting web port
make survey INTERFACE="$ALFA_IF" WEB_PORT=2601

Press Ctrl-C to stop. Logs are placed under data/kismet/. A hopping survey is good for discovering devices but cannot capture every frame because this radio listens to only one channel block at a time.

Make a detailed channel recording

This creates a temporary monitor interface, locks it to a 20 MHz channel, and writes a lossless radiotap pcapng. The MT7612U requires its original managed interface to be lowered while tuning; the script remembers and restores that interface's prior state afterward. It does not touch other Wi-Fi interfaces.

# Record channel 1 for 60 seconds
make record INTERFACE="$ALFA_IF" CHANNEL=1 DURATION=60

# Record channel 36 until Ctrl-C; files rotate at roughly 100 MB
make record INTERFACE="$ALFA_IF" CHANNEL=36 DURATION=0

Captures go to captures/. Regulatory restrictions are enforced by the kernel; the script fails if the requested channel cannot be selected. The initial recorder intentionally uses HT20 so channel selection is unambiguous. Wider 40/80 MHz capture can be added later with an explicit center frequency.

If a process is interrupted and leaves the temporary interface behind:

make clean-monitor INTERFACE="$ALFA_IF"

Analyze a recording

make analyze FILE=captures/20260722T120000Z_ch1.pcapng

This creates data/analysis/<capture-name>/ containing:

  • capture-info.txt: file duration, packet counts, rates, and encapsulation
  • beacons.csv: AP observations with time, SSID, BSSID, frequency, and RSSI
  • frames.csv: frame types, addresses, retries, frequency, and RSSI
  • observations.sqlite3: indexed tables plus a networks summary view
  • summary.txt: basic frame and network totals

Example queries:

sqlite3 -header -column data/analysis/*/observations.sqlite3 \
  'SELECT * FROM networks ORDER BY avg_signal_dbm DESC;'

tshark -r captures/example.pcapng -Y 'wlan.fc.retry == 1'
wireshark captures/example.pcapng

The CSV and SQLite exports retain MAC addresses. Sanitize them before sharing. The raw pcapng files, generated data, and Kismet databases are excluded by .gitignore.

AI coding CLIs

Codex and Claude Code are installed globally in the image. The host's ~/.codex/auth.json is bind-mounted into the container for the node user, so Codex uses the same login and can persist refreshed credentials. The source file must exist on the host before the container is created; running codex login on the host creates it.

Interactive Bash and Zsh shells define these aliases:

alias codex='command codex --dangerously-bypass-approvals-and-sandbox'
alias claude='command claude --dangerously-skip-permissions'

These flags disable the CLIs' permission protections. Combined with this container's privileged host access, either agent can modify the host and control attached devices without confirmation. Use only with trusted prompts and code.

Claude authentication is not shared from the host; run claude once inside the container and follow its login flow.

If the USB device is absent, unplug and reconnect it, then rebuild/reopen the container. If lsusb sees it but iw dev does not, inspect the host first with sudo dmesg --follow while reconnecting the adapter.

Why the container has broad access

The configuration uses --privileged so tools can control the USB device and wireless PHY, and --network=host because Linux Wi-Fi interfaces live in a network namespace. It also mounts the USB bus, udev database, and host kernel modules. This gives processes in the container extensive control over the host; only run code you trust in it.

The host and container share networking. NetworkManager or another host service may claim the adapter while you experiment. Check its state with:

nmcli device status

Disconnecting a Wi-Fi interface from NetworkManager can interrupt connectivity, so keep the machine's built-in Wi-Fi or Ethernet as the management connection.

Only capture or test networks and devices that you own or have explicit permission to assess.