원클릭으로
roo-vms
Alpine and Debian QEMU VMs for protocol testing, fuzzing, and network experiments
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Alpine and Debian QEMU VMs for protocol testing, fuzzing, and network experiments
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Anthropic API rate limit handling - retry logic, backoff, throttling for batch workloads against Claude models
Use when building an automated test → issue → fix loop with Claude Code and GitHub issues — overnight auto-fixing, regression loops, self-healing CI.
Use when creating, editing, publishing, or deleting posts on Cyril's Workshop blog or the steponnopets.net devblog.
Use when writing or contributing a boofuzz network-protocol fuzzer in this repo — layout, formatting rules, and reading results.
Use when a task needs real-time control of a connected browser via the Browser Bridge Broker — submit JS jobs over HTTP that browsers eval and return.
Use when training a character LoRA (Chroma/Flux or Pony/SDXL) on a RunPod GPU and wiring it into the ComfyUI + pony_web render stack.
| name | Roo-VMS |
| description | Alpine and Debian QEMU VMs for protocol testing, fuzzing, and network experiments |
| tags | ["qemu","vm","testing","networking","fuzzing"] |
This skill describes the QEMU virtual machines available for protocol testing, fuzzing, and network experiments. These VMs provide isolated, disposable environments for testing network protocols without risking the host system.
All VMs are in: /home/matt/Git/VoE/qemu-vms/
Alpine Linux VMs (lightweight, fast boot)
alpine-base.qcow2 - Base Alpine imageaoe-server.qcow2 - Alpine configured as serveraoe-client.qcow2 - Alpine configured as clientDebian Linux VMs (full-featured, standard tools)
debian-12-generic-amd64.qcow2 - Base Debian 12 imagedebian-aoe-client.qcow2 - Debian configured as clientAlpine VM:
cd /home/matt/Git/VoE/qemu-vms
qemu-system-x86_64 -name test-alpine -m 512 \
-hda alpine-base.qcow2 \
-netdev user,id=net0,hostfwd=tcp::2222-:22 -device e1000,netdev=net0 \
-nographic
Debian VM:
cd /home/matt/Git/VoE/qemu-vms
qemu-system-x86_64 -name test-debian -m 1024 \
-hda debian-12-generic-amd64.qcow2 \
-netdev user,id=net0,hostfwd=tcp::2224-:22 -device e1000,netdev=net0 \
-enable-kvm -cpu host \
-nographic
Important: Always include -enable-kvm -cpu host for hardware acceleration. This provides significant performance improvements by using KVM virtualization support.
Use the provided script:
cd /home/matt/Git/VoE/qemu-vms
./start-vms.sh
This starts:
Console Login:
rootSSH Login:
claudealpinessh -p 2222 claude@localhost
Console Login:
debiandebianSSH Login:
debiandebianssh -p 2224 debian@localhost
If a VM is configured for key-only SSH authentication (or you want to add your key without password login), you can manually inject the SSH key by mounting the disk image on the host:
# Load the nbd kernel module if not already loaded
sudo modprobe nbd max_part=8
# Connect the qcow2 image to a network block device
sudo qemu-nbd --connect=/dev/nbd0 /home/matt/Git/VoE/qemu-vms/debian-12-generic-amd64.qcow2
# Wait for the device to be ready
sudo partprobe /dev/nbd0
lsblk | grep nbd0
# Mount the root partition (usually /dev/nbd0p1)
sudo mkdir -p /mnt/debian
sudo mount /dev/nbd0p1 /mnt/debian
# Create .ssh directory if it doesn't exist
sudo mkdir -p /mnt/debian/home/debian/.ssh
# Add your public key
cat ~/.ssh/id_rsa.pub | sudo tee -a /mnt/debian/home/debian/.ssh/authorized_keys
# Set correct permissions (CRITICAL - SSH will reject wrong permissions)
sudo chmod 700 /mnt/debian/home/debian/.ssh
sudo chmod 600 /mnt/debian/home/debian/.ssh/authorized_keys
sudo chown -R 1000:1000 /mnt/debian/home/debian/.ssh # UID 1000 is typically the first user
# Unmount and disconnect
sudo umount /mnt/debian
sudo qemu-nbd --disconnect /dev/nbd0
Note: This technique is useful when:
1. User Mode (NAT) - Internet Access
-netdev user,id=net0,hostfwd=tcp::2222-:22 -device e1000,netdev=net0
2. Socket Mode - VM-to-VM Communication
# Server VM (listener)
-netdev socket,id=net1,listen=:8010 -device e1000,netdev=net1,mac=52:54:00:aa:bb:01
# Client VM (connector)
-netdev socket,id=net1,connect=localhost:8010 -device e1000,netdev=net1,mac=52:54:00:aa:bb:02
3. Combined - Both Networks
-netdev user,id=net0,hostfwd=tcp::2222-:22 -device e1000,netdev=net0 \
-netdev socket,id=net1,listen=:8010 -device e1000,netdev=net1
Forward additional ports to VM:
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::3260-:3260,hostfwd=tcp::3000-:3000
This example forwards:
Scenario: Test iSCSI/NBD/AoE server in VM
# Start VM with protocol port forwarded
qemu-system-x86_64 -m 1024 -hda debian-12-generic-amd64.qcow2 \
-netdev user,id=net0,hostfwd=tcp::2224-:22,hostfwd=tcp::3260-:3260 \
-device e1000,netdev=net0 -nographic
# SSH into VM
ssh -p 2224 debian@localhost
# Run your server in VM
./my-protocol-server --port 3260
# Test from host
./my-protocol-client --host localhost --port 3260
Scenario: Fuzz iSCSI server running on host
# On host - start your server
./iscsi-target --port 3260
# Start VM
qemu-system-x86_64 -m 1024 -hda alpine-base.qcow2 \
-netdev user,id=net0,hostfwd=tcp::2222-:22 -device e1000,netdev=net0 \
-nographic
# SSH into VM
ssh -p 2222 claude@localhost
# Run fuzzer in VM targeting host
# Host is reachable at 10.0.2.2 from VM
python3 fuzzer.py --target 10.0.2.2:3260
Key: From VM, host is always at 10.0.2.2 in user mode networking.
Scenario: Test client/server both in VMs
# Terminal 1 - Server VM
qemu-system-x86_64 -name server -m 512 -hda aoe-server.qcow2 \
-netdev user,id=net0,hostfwd=tcp::2222-:22 -device e1000,netdev=net0 \
-netdev socket,id=net1,listen=:8010 -device e1000,netdev=net1,mac=52:54:00:aa:bb:01 \
-nographic
# Terminal 2 - Client VM
qemu-system-x86_64 -name client -m 512 -hda aoe-client.qcow2 \
-netdev user,id=net0,hostfwd=tcp::2223-:22 -device e1000,netdev=net0 \
-netdev socket,id=net1,connect=localhost:8010 -device e1000,netdev=net1,mac=52:54:00:aa:bb:02 \
-nographic
# Configure static IPs on eth1 (socket network)
# In server VM:
ip addr add 192.168.100.1/24 dev eth1
ip link set eth1 up
# In client VM:
ip addr add 192.168.100.2/24 dev eth1
ip link set eth1 up
# Test connectivity
ping 192.168.100.1 # from client to server
On Host:
# Capture traffic to/from VM
sudo tcpdump -i any -w protocol-test.pcap port 3260
wireshark protocol-test.pcap
In VM:
# Capture traffic inside VM
tcpdump -i eth0 -w /tmp/capture.pcap
# Copy out via SSH
scp -P 2222 claude@localhost:/tmp/capture.pcap ./
Example Setup:
# Start server in VM
qemu-system-x86_64 -m 1024 -hda debian-12-generic-amd64.qcow2 \
-netdev user,id=net0,hostfwd=tcp::2224-:22,hostfwd=tcp::3260-:3260 \
-device e1000,netdev=net0 -nographic
# SSH and start target server
ssh -p 2224 debian@localhost
./vulnerable-iscsi-server --port 3260
# From host, run fuzzer
python3 boofuzz-iscsi.py --target localhost:3260
If server crashes, VM is isolated - just restart it.
From Console:
Ctrl-A then X to quit QEMUCtrl-A then C for QEMU monitor, then type quitFrom SSH:
exitCtrl-A C then quit# Copy base image over modified one
cd /home/matt/Git/VoE/qemu-vms
cp alpine-base.qcow2 test-vm.qcow2
Or use snapshot overlays:
# Create overlay (changes don't affect base)
qemu-img create -f qcow2 -b alpine-base.qcow2 -F qcow2 test-overlay.qcow2
# Use overlay
qemu-system-x86_64 -hda test-overlay.qcow2 ...
# Discard changes: just delete test-overlay.qcow2
# Create snapshot
qemu-img snapshot -c before-fuzzing test-vm.qcow2
# List snapshots
qemu-img snapshot -l test-vm.qcow2
# Restore snapshot
qemu-img snapshot -a before-fuzzing test-vm.qcow2
# Update package index
apk update
# Install common tools
apk add python3 py3-pip tcpdump wireshark-common curl wget netcat-openbsd
# Install development tools
apk add gcc musl-dev linux-headers
# Install boofuzz
apk add py3-pip
pip3 install boofuzz
# Update package index
sudo apt update
# Install common tools
sudo apt install -y python3 python3-pip tcpdump wireshark tshark curl wget netcat-openbsd
# Install development tools
sudo apt install -y build-essential
# Install boofuzz
pip3 install boofuzz
AddressSanitizer is a powerful memory error detector useful for fuzzing and security testing. Important: ASAN requires glibc and will NOT work on Alpine Linux (which uses musl libc).
| Distribution | libc | ASAN Support |
|---|---|---|
| Debian | glibc | ✅ Full support |
| Alpine | musl | ❌ Not supported |
Use Debian VMs for any ASAN-instrumented builds.
# SSH to Debian VM
ssh -p 2224 debian@localhost
# Install build dependencies
sudo apt update
sudo apt install -y git cmake ninja-build build-essential
# Clone without recursive submodules to save space
git clone https://github.com/nanomq/nanomq.git
cd nanomq
# Only initialize essential submodules
git submodule update --init --depth=1 nng
# Create build directory
mkdir build && cd build
# Configure with ASAN flags
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer -g -O1" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" \
-DNNG_ENABLE_TLS=OFF \
-DENABLE_JWT=OFF \
-DENABLE_QUIC=OFF
# Build
ninja
# Run with ASAN
ASAN_OPTIONS="detect_leaks=1:abort_on_error=0:halt_on_error=0:print_stats=1" \
./nanomq/nanomq start
# Recommended ASAN environment variables
export ASAN_OPTIONS="detect_leaks=1:abort_on_error=0:halt_on_error=0:print_stats=1"
detect_leaks=1 - Enable memory leak detectionabort_on_error=0 - Don't abort on first error (useful for fuzzing)halt_on_error=0 - Continue execution after detecting errorsprint_stats=1 - Print memory allocation statisticsVM disk images can fill up quickly when building large projects. Tips:
1. Clone without recursive submodules:
# Don't do this on small VMs:
git clone --recursive https://github.com/large-project/repo.git
# Instead:
git clone https://github.com/large-project/repo.git
cd repo
git submodule update --init --depth=1 essential-submodule
2. Check disk usage:
df -h
du -sh ~/project/*
3. Clean build artifacts:
# CMake projects
rm -rf build/
# Or just clean object files
find build/ -name "*.o" -delete
4. Expand VM disk if needed:
# On host - resize the qcow2 image
qemu-img resize vm.qcow2 +2G
# In VM - expand the filesystem
sudo growpart /dev/sda 1
sudo resize2fs /dev/sda1
Via SSH/SCP:
# Copy to VM
scp -P 2222 fuzzer.py claude@localhost:/home/claude/
# Copy from VM
scp -P 2222 claude@localhost:/tmp/results.txt ./
Via HTTP Server:
# On host
cd /home/matt/Git/VoE
python3 -m http.server 8000
# In VM (host is 10.0.2.2)
wget http://10.0.2.2:8000/fuzzer.py
Use host as intermediary:
# VM1 → Host
scp -P 2222 claude@localhost:/tmp/file.txt ./
# Host → VM2
scp -P 2223 file.txt claude@localhost:/tmp/
# Execute command via SSH
ssh -p 2222 claude@localhost 'ping -c 3 10.0.2.2'
# Run script
ssh -p 2222 claude@localhost 'bash -s' < local-script.sh
# VM1 on 2222
qemu-system-x86_64 -m 512 -hda vm1.qcow2 \
-netdev user,id=net0,hostfwd=tcp::2222-:22 -device e1000,netdev=net0 \
-nographic &
# VM2 on 2223
qemu-system-x86_64 -m 512 -hda vm2.qcow2 \
-netdev user,id=net0,hostfwd=tcp::2223-:22 -device e1000,netdev=net0 \
-nographic &
# VM3 on 2224
qemu-system-x86_64 -m 512 -hda vm3.qcow2 \
-netdev user,id=net0,hostfwd=tcp::2224-:22 -device e1000,netdev=net0 \
-nographic &
Check if port is in use:
ss -tlnp | grep 2222
# Kill conflicting process if needed
Check if previous QEMU is running:
ps aux | grep qemu
pkill qemu-system-x86_64
Wait for boot:
# Keep trying until SSH is up
while ! ssh -p 2222 -o ConnectTimeout=1 claude@localhost 'echo ready'; do
sleep 1
done
Check SSH service in VM:
# From console
rc-status # Alpine
systemctl status ssh # Debian
Check interface is up:
ip link show eth1
ip link set eth1 up
Check IP addresses:
ip addr show
Test connectivity:
ping -I eth1 192.168.100.1
user prevents VM from directly accessing host network-netdev user,...-netdev socket,...hostfwd=tcp::HOST_PORT-:VM_PORT2025-12-05 (v2):
2025-12-05 (v1):
Last Updated: 2025-12-05
Location: /home/matt/Git/VoE/qemu-vms/
Script: ./start-vms.sh for quick two-VM setup