1. System Overview
This document details the configuration of a Raspberry Pi running Kali Linux to act as a resilient, continuous audio recording device. The system captures uncompressed WAV audio from a highly sensitive USB Lavalier microphone directly to an external exFAT/FAT32 USB drive.
Core Capabilities
- Power Resilience: Service waits for the USB mount, writes files in 10-minute chunks, and actively flushes RAM to disk to minimize data loss during sudden power outages.
- Storage Management: Automatically deletes the oldest recordings when the drive reaches 95% capacity.
- Easy Toggling: A master script easily engages or disengages the entire recording array (including cron jobs) with a single command.
2. Persistent Storage (fstab)
Because the USB drive is formatted as exFAT/FAT32, standard Linux file ownership cannot be applied per-folder. We force the mount to assign ownership to the kali user (UID 1000) globally on boot.
Identifying the Drive
The drive's unique identifier (UUID) was found using:
sudo blkid /dev/sda2
The fstab Configuration
The following line was added to /etc/fstab to guarantee the drive mounts at boot, even if unplugged (nofail), and grants full write access to the kali user.
UUID=68EE-53E1 /mnt/usb auto uid=1000,gid=1000,defaults,nofail 0 0
Why this matters
Without uid=1000,gid=1000, the drive defaults to root ownership, and our background service (running as kali) will fail to write audio files.
3. Audio Hardware Configuration
The USB Lavalier Microphone was identified using the ALSA recording hardware list:
arecord -l
The output indicated: card 2: Microphone... device 0.... This translates to the hardware ID plughw:2,0.
Microphone Sensitivity (Gain)
To capture all audio, the microphone gain was maximized using alsamixer. The state was saved so it persists across reboots using:
sudo alsactl store
4. The Background Service (systemd)
The recording loop is managed by a systemd service. It is designed to strictly wait for the USB drive to mount before attempting to record, preventing the internal SD card from filling up.
File location: /etc/systemd/system/audiorecorder.service
[Unit]
Description=Continuous USB Audio Recording
After=network.target local-fs.target
RequiresMountsFor=/mnt/usb
[Service]
Type=simple
User=kali
ExecStart=/usr/bin/arecord -D plughw:2,0 -f S16_LE -r 44100 -c 1 --max-file-time=600 --use-strftime /mnt/usb/audio_logs/audio-%%Y-%%m-%%d-%%H-%%M.wav
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Service Breakdown:
RequiresMountsFor=/mnt/usb: Halts execution until the OS confirms the USB is mounted.-D plughw:2,0: Targets our specific USB microphone.--max-file-time=600: Closes the current file and starts a new one every 10 minutes (600 seconds). This limits corruption to a maximum of 10 minutes if power is cut.
5. Automation & Resilience (crontab & cleanup)
The Cleanup Script
Because arecord does not manage disk space, a script checks disk usage and deletes the oldest .wav file if the drive hits 95% capacity.
File location: /home/kali/cleanup_audio.sh
#!/bin/bash
DIR="/mnt/usb/audio_logs"
MAX_USAGE=95
USAGE=$(df -h "$DIR" | awk 'NR==2 {print $5}' | sed 's/%//')
while [ "$USAGE" -ge "$MAX_USAGE" ]; do
OLDEST=$(ls -1tr "$DIR"/*.wav 2>/dev/null | head -n 1)
if [ -n "$OLDEST" ]; then
rm -f "$OLDEST"
USAGE=$(df -h "$DIR" | awk 'NR==2 {print $5}' | sed 's/%//')
else
break
fi
done
The Crontab Entries
Two entries are added to the kali user's crontab (crontab -e):
*/5 * * * * /home/kali/cleanup_audio.sh
* * * * * sync
The sync command is critical for power resilience: it forces the OS to flush any file data held in RAM directly to the physical USB drive every minute.
6. Master Toggle Script
To cleanly pause operations without leaving cron jobs running in the background, a toggle script is used. It modifies systemctl and safely comments/uncomments the crontab.
File location: /home/kali/toggle_record.sh
#!/bin/bash
if [ "$1" == "enable" ]; then
echo "🟢 Enabling continuous audio recording..."
sudo systemctl enable audiorecorder.service
sudo systemctl start audiorecorder.service
crontab -l | sed 's/^#* *\(.*cleanup_audio\.sh\)//' | sed 's/^#* *\(.*sync\)//' | crontab -
echo "✅ Enabled!"
elif [ "$1" == "disable" ]; then
echo "🔴 Disabling continuous audio recording..."
sudo systemctl stop audiorecorder.service
sudo systemctl disable audiorecorder.service
crontab -l | sed 's/^#* *\(.*cleanup_audio\.sh\)/# /' | sed 's/^#* *\(.*sync\)/# /' | crontab -
echo "❌ Disabled!"
else
echo "Usage: ./toggle_record.sh {enable|disable}"
fi
7. Troubleshooting Guide
If the system stops recording or behaves unexpectedly, use this checklist to diagnose the issue.
Symptom: No new audio files are being generated
1. Check Service Status & Logs
Run: sudo systemctl status audiorecorder.service
Run: sudo journalctl -u audiorecorder.service -n 50 --no-pager
Look for errors like "Device or resource busy" or "No such file or directory".
2. Verify Microphone ID
If the USB mic was plugged into a different port, Linux might have assigned it a new hardware ID. Run arecord -l. If it is no longer card 2, update the plughw:X,0 value in /etc/systemd/system/audiorecorder.service and run sudo systemctl daemon-reload.
3. Verify USB Mount
Run df -h. Ensure /dev/sda2 is mounted at /mnt/usb. If not, the service will refuse to start due to RequiresMountsFor. Try running sudo mount -a to force the fstab.
Symptom: Audio files exist, but size is 0 bytes or corrupted
1. Check Drive Format / Corruption
If power was lost during a write, the exFAT filesystem might have a dirty bit set. Plug the USB into a Windows/Mac machine and run a disk repair, or run sudo fsck.exfat /dev/sda2.
2. Check Permissions
Run ls -al /mnt/usb/audio_logs. The owner must be kali kali. If it says root root, unmount it and remount using the fstab configuration.
Symptom: Drive is filling up / Cleanup script failing
1. Verify Cron is active
Check your crontab using crontab -l. Ensure there are no # symbols in front of the cleanup script. Use ./toggle_record.sh enable to fix this.
2. Run Script Manually
Run /home/kali/cleanup_audio.sh manually in the terminal. If it throws permission errors, ensure the script is executable: chmod +x ~/cleanup_audio.sh.