QEMU Test VMs for Protocol Testing
Overview
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.
Available VMs
Location
All VMs are in: /home/matt/Git/VoE/qemu-vms/
VM Images
- •
Alpine Linux VMs (lightweight, fast boot)
- •
alpine-base.qcow2- Base Alpine image - •
aoe-server.qcow2- Alpine configured as server - •
aoe-client.qcow2- Alpine configured as client
- •
- •
Debian Linux VMs (full-featured, standard tools)
- •
debian-12-generic-amd64.qcow2- Base Debian 12 image - •
debian-aoe-client.qcow2- Debian configured as client
- •
Quick Start
Starting a Single VM
Alpine 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 \ -nographic
Starting Server + Client Pair
Use the provided script:
cd /home/matt/Git/VoE/qemu-vms ./start-vms.sh
This starts:
- •Server VM on SSH port 2222
- •Client VM on SSH port 2223
- •Shared network on socket :8010
VM Access
Alpine VMs
Console Login:
- •Username:
root - •Password: (blank - just press Enter)
SSH Login:
- •Username:
claude - •Password:
alpine - •Port: 2222 (server) or 2223 (client)
ssh -p 2222 claude@localhost
Debian VMs
Console Login:
- •Username:
debian - •Password:
debian
SSH Login:
- •Username:
debian - •Password:
debian - •Port: 2224 (default)
ssh -p 2224 debian@localhost
Network Configuration
Network Modes
1. User Mode (NAT) - Internet Access
-netdev user,id=net0,hostfwd=tcp::2222-:22 -device e1000,netdev=net0
- •VM gets DHCP address (usually 10.0.2.15)
- •Can access internet through host NAT
- •Host can access VM via port forwarding
- •VM cannot be accessed from other VMs
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
- •Direct VM-to-VM networking
- •No internet on this interface
- •Use for protocol testing between VMs
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
- •eth0: Internet access + host SSH
- •eth1: VM-to-VM communication
Port Forwarding
Forward additional ports to VM:
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::3260-:3260,hostfwd=tcp::3000-:3000
This example forwards:
- •Host 2222 → VM 22 (SSH)
- •Host 3260 → VM 3260 (iSCSI)
- •Host 3000 → VM 3000 (HTTP/CAS)
Common Use Cases
1. Testing Network Protocol Server
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
2. Protocol Fuzzing (Client in VM, Server on Host)
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.
3. VM-to-VM Protocol Testing
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
4. Packet Capture for Protocol Analysis
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 ./
5. Fuzzing with Boofuzz
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.
VM Management
Exiting QEMU
From Console:
- •Press
Ctrl-AthenXto quit QEMU - •Or:
Ctrl-AthenCfor QEMU monitor, then typequit
From SSH:
- •Just logout:
exit - •Stop VM from monitor:
Ctrl-A Cthenquit
Resetting VM to Clean State
# 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
Taking Snapshots
# 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
Installing Tools in VMs
Alpine Linux
# 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
Debian Linux
# 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
Tips and Tricks
Copying Files to/from VMs
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
Sharing Files Between VMs
Use host as intermediary:
# VM1 → Host scp -P 2222 claude@localhost:/tmp/file.txt ./ # Host → VM2 scp -P 2223 file.txt claude@localhost:/tmp/
Running Commands Without Login
# 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
Multiple VMs on Different Ports
# 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 &
Troubleshooting
VM Won't Start
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
Can't SSH to VM
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
VM-to-VM Network Not Working
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
Safety Notes
- •VMs are isolated from host by default
- •Crashes in VM don't affect host system
- •Use VMs for testing potentially dangerous code
- •Network mode
userprevents VM from directly accessing host network - •For production testing, use proper network isolation (bridges, VLANs)
Common Patterns
Pattern: Fuzzing Server Protocol
- •Start VM with port forwarding
- •Run target server in VM
- •Run fuzzer from host against forwarded port
- •Monitor with tcpdump/wireshark
- •If VM crashes, restart clean image
Pattern: Testing Client/Server
- •Start two VMs with socket network
- •Configure static IPs on socket interface
- •Run server on VM1, client on VM2
- •Use host SSH to control both
- •Capture traffic with tcpdump
Pattern: Protocol Development
- •Develop on host (fast compile, full IDE)
- •Copy binary to VM via SCP
- •Test in VM (isolated environment)
- •Iterate quickly
Reference
QEMU Network Options
- •QEMU Networking Documentation
- •User mode:
-netdev user,... - •Socket mode:
-netdev socket,... - •Port forwarding:
hostfwd=tcp::HOST_PORT-:VM_PORT
VM Images
- •Alpine: Minimal, fast, 200MB disk
- •Debian: Full-featured, 500MB+ disk
- •Choose Alpine for speed, Debian for tools
Typical Resource Allocation
- •Alpine: 512MB RAM sufficient
- •Debian: 1024MB RAM recommended
- •Disk: Images grow dynamically (qcow2)
Last Updated: 2025-12-05
Location: /home/matt/Git/VoE/qemu-vms/
Script: ./start-vms.sh for quick two-VM setup