What does the debug output show if you watch it from the console when you send a WoL packet?pfSense is on vmbr2. i have modified the script with both the interfaces (vmbr0 and vmbr2) but no success. also use port 40000 instead of 9. if you look at the script it basically does a lookup for the mac address you are sending the wol packet to, and then attempts to start the vm which has that "virtual" nic with that mac address. so not sure if the interface (vmbr0 or vmbr2) should really matter, as long you have one of them to route your packet to the mac address. i could be wrong though.
so the udp port needs to be 9 and not 40000....doh!What does the debug output show if you watch it from the console when you send a WoL packet?
#!/bin/bash
#Define bridge device in use on your system!
# E.G: vmbr0 or vmbr1
vmbr="vmbr0"
#We will use UDP port 9
portnr="9"
# fix: 10-12-24 Can now besides starting also "unpause/resume vm's" (also via Moonlight I tested)
# I will give "NO support" nor "emply" that is this code deemed fit for use!
# Use at your own risk! (people should use API instead)
while true; do
sleep 5
wake_mac=$(tcpdump -c 1 -UlnXi ${vmbr} ether proto 0x0842 or udp port ${portnr} 2>/dev/null |\
sed -nE 's/^.*20: (ffff|.... ....) (..)(..) (..)(..) (..)(..).*$/\2:\3:\4:\5:\6:\7/p')
echo "Captured magic packet for address: \"${wake_mac}\""
echo -n "Looking for existing VM: "
matches=($(grep -il ${wake_mac} /etc/pve/qemu-server/*))
if [[ ${#matches[*]} -eq 0 ]]; then
echo "${#matches[*]} found"
echo -n "Looking for existing LXC: "
matches=($(grep -il ${wake_mac} /etc/pve/lxc/*))
if [[ ${#matches[*]} -eq 0 ]]; then
echo "${#matches[*]} found"
continue
elif [[ ${#matches[*]} -gt 1 ]]; then
echo "${#matches[*]} found, using first found"
else
echo "${#matches[*]} found"
fi
vm_file=$(basename ${matches[0]})
vm_id=${vm_file%.*}
details=$(pct status ${vm_id} -verbose | egrep "^name|^status")
name=$(echo ${details} | awk '{print $2}')
status=$(echo ${details} | awk '{print $4}')
if [[ "${status}" != "stopped" ]]; then
echo "SKIPPED CONTAINER ${vm_id} : ${name} is ${status}"
else
echo "STARTING CONTAINER ${vm_id} : ${name} is ${status}"
pct start ${vm_id}
fi
continue
elif [[ ${#matches[*]} -gt 1 ]]; then
echo "${#matches[*]} found, using first found"
else
echo "${#matches[*]} found"
fi
vm_file=$(basename ${matches[0]})
vm_id=${vm_file%.*}
# (Due to 'bug/odd feature' in qm): qm status ${vm_id} -verbose
# will show paused and suspended vms as 'status: running')
# solution querying only name using 'qm status -verbose'
name=$(qm status ${vm_id} -verbose | egrep "^name" | awk '{print $2}')
# And querying the status using just 'qm status'
status=$(qm status ${vm_id} | awk '{print $2}')
#So now it is possible to start/resume stopped/paused/suspended vms!
if [[ "${status}" != "stopped" ]]; then
if [[ "${status}" == "suspended" ]] || [[ "${status}" == "paused" ]]; then
echo "Resuming VM ${vm_id} Status of ${name} was ${status}"
qm resume ${vm_id}
elif [[ "${status}" != "suspended" ]] || [[ "${status}" != "paused" ]]; then
echo "SKIPPED VM ${vm_id} because ${name} is ${status}"
fi
else
echo "STARTING VM ${vm_id} : ${name} is ${status}"
qm start ${vm_id}
fi
done
I've found some software that sends WOL sends it to subnet 255.255.255.255, but you need use 255.255.255.0 for this, so your proxmox host should see it. In my own testing and implementation of this, with UpSnap and some custom Ping and Shutdown commands, I have had to mess with all kinds of things. I have VM's and LXC's on their own isolated SDN's and can spin them up, so long as you are sending from an IP within the same range as the proxmox host IP, so like 192.168.1.0/24, versus 192.168.2.0/24 even while they are on a different numbering scheme entirely.My proxmox node has a dedicated interface on vmbr0 and all my vms and containers use vmbr2. ive tried wol_hack.sh with both interfaces and it wont capture incoming magic packets from any client (moonlight in my case). no error messages either. having said that my pfsense instance (on the same node) can send wol packets successfully to vms and wakes them up in 2 secs.
any ideas?
#!/bin/bash
# Define bridge device in use on your system!
# E.G: vmbr0 or vmbr1
vmbr="vmbr0"
# We will use UDP port 9
portnr="9"
# Function to invert MAC address (reverse byte order)
invert_mac_address() {
local mac=$1
# Split the MAC address into parts
IFS=':' read -ra PARTS <<< "$mac"
# Reverse the order of the parts
local inverted="${PARTS[5]}:${PARTS[4]}:${PARTS[3]}:${PARTS[2]}:${PARTS[1]}:${PARTS[0]}"
echo "$inverted"
}
# Function to search for MAC address in VM or LXC files and return matches
search_mac_address() {
local mac_address=$1
local container_type=$2
local search_path=""
if [[ "${container_type}" == "vm" ]]; then
search_path="/etc/pve/qemu-server/*"
elif [[ "${container_type}" == "lxc" ]]; then
search_path="/etc/pve/lxc/*"
else
return 1
fi
local matches=($(grep -il ${mac_address} ${search_path}))
echo -n "Looking for existing ${container_type^^}: "
if [[ ${#matches[*]} -eq 0 ]]; then
echo "${#matches[*]} found"
return 1
elif [[ ${#matches[*]} -gt 1 ]]; then
echo "${#matches[*]} found, using first found"
else
echo "${#matches[*]} found"
fi
# Return the first match path
echo "__MATCH_PATH__:${matches[0]}"
return 0
}
# Function to manage VM operations
manage_vm() {
local vm_path=$1
local operation=$2 # "start" or "shutdown"
local vm_file=$(basename "${vm_path}")
local vm_id=${vm_file%.*}
# Get VM name
local name=$(qm status ${vm_id} -verbose | egrep "^name" | awk '{print $2}')
# Get VM status
local status=$(qm status ${vm_id} | awk '{print $2}')
if [[ "$operation" == "start" ]]; then
if [[ "${status}" != "stopped" ]]; then
if [[ "${status}" == "suspended" ]] || [[ "${status}" == "paused" ]]; then
echo "Resuming VM ${vm_id} Status of ${name} was ${status}"
qm resume ${vm_id}
else
echo "SKIPPED VM ${vm_id} because ${name} is ${status}"
fi
else
echo "STARTING VM ${vm_id} : ${name} is ${status}"
qm start ${vm_id}
fi
elif [[ "$operation" == "shutdown" ]]; then
if [[ "${status}" == "stopped" ]]; then
echo "SKIPPED VM ${vm_id} because ${name} is already ${status}"
else
echo "SHUTTING DOWN VM ${vm_id} : ${name} is ${status}"
qm shutdown ${vm_id} --forceStop
fi
fi
}
# Function to manage LXC operations
manage_lxc() {
local container_path=$1
local operation=$2 # "start" or "shutdown"
local container_file=$(basename "${container_path}")
local container_id=${container_file%.*}
local details=$(pct status ${container_id} -verbose | egrep "^name|^status")
local name=$(echo ${details} | awk '{print $2}')
local status=$(echo ${details} | awk '{print $4}')
if [[ "$operation" == "start" ]]; then
if [[ "${status}" != "stopped" ]]; then
echo "SKIPPED CONTAINER ${container_id} : ${name} is ${status}"
else
echo "STARTING CONTAINER ${container_id} : ${name} is ${status}"
pct start ${container_id}
fi
elif [[ "$operation" == "shutdown" ]]; then
if [[ "${status}" == "stopped" ]]; then
echo "SKIPPED CONTAINER ${container_id} : ${name} is already ${status}"
else
echo "SHUTTING DOWN CONTAINER ${container_id} : ${name} is ${status}"
pct shutdown ${container_id} --forceStop
fi
fi
}
# Main loop
# I will give "NO support" nor "emply" that is this code deemed fit for use!
# Use at your own risk! (people should use API instead)
while true; do
sleep 5
wake_mac=$(tcpdump -c 1 -UlnXi ${vmbr} ether proto 0x0842 or udp port ${portnr} 2>/dev/null |\
sed -nE 's/^.*20: (ffff|.... ....) (..)(..) (..)(..) (..)(..).*$/\2:\3:\4:\5:\6:\7/p')
echo "Captured magic packet for address: \"${wake_mac}\""
# Check if the MAC is inverted (for shutdown operation)
inverted_mac=$(invert_mac_address "${wake_mac}")
# First try to find the original MAC for start operation
# Capture the output in a variable
vm_output=$(search_mac_address ${wake_mac} "vm")
# Extract only the line with the path marker
vm_match=$(echo "$vm_output" | grep "__MATCH_PATH__:" | sed 's/__MATCH_PATH__://')
if [[ -n "${vm_match}" ]]; then
echo "Found VM with matching MAC, path: ${vm_match}"
manage_vm "${vm_match}" "start"
continue
fi
# Check for LXC next
lxc_output=$(search_mac_address ${wake_mac} "lxc")
# Extract only the line with the path marker
lxc_match=$(echo "$lxc_output" | grep "__MATCH_PATH__:" | sed 's/__MATCH_PATH__://')
if [[ -n "${lxc_match}" ]]; then
echo "Found LXC with matching MAC, path: ${lxc_match}"
manage_lxc "${lxc_match}" "start"
continue
fi
# If no match found for original MAC, check for inverted MAC (shutdown operation)
echo "Checking for inverted MAC address: ${inverted_mac} (for shutdown)"
# Check for VM with inverted MAC
vm_output=$(search_mac_address ${inverted_mac} "vm")
# Extract only the line with the path marker
vm_match=$(echo "$vm_output" | grep "__MATCH_PATH__:" | sed 's/__MATCH_PATH__://')
if [[ -n "${vm_match}" ]]; then
echo "Found VM with matching inverted MAC, path: ${vm_match}"
manage_vm "${vm_match}" "shutdown"
continue
fi
# Check for LXC with inverted MAC
lxc_output=$(search_mac_address ${inverted_mac} "lxc")
# Extract only the line with the path marker
lxc_match=$(echo "$lxc_output" | grep "__MATCH_PATH__:" | sed 's/__MATCH_PATH__://')
if [[ -n "${lxc_match}" ]]; then
echo "Found LXC with matching inverted MAC, path: ${lxc_match}"
manage_lxc "${lxc_match}" "shutdown"
continue
fi
echo "No matching VM or container found for MAC: ${wake_mac} or inverted MAC: ${inverted_mac}"
done
Captured magic packet for address: "bc:24:11:6b:40:7d"
Found VM with matching MAC, path: /etc/pve/qemu-server/103.conf
STARTING VM 103 : Win11-1-Osiris is stopped
swtpm_setup: Not overwriting existing state file.
Captured magic packet for address: "7d:40:6b:11:24:bc"
Checking for inverted MAC address: bc:24:11:6b:40:7d (for shutdown)
Found VM with matching inverted MAC, path: /etc/pve/qemu-server/103.conf
SHUTTING DOWN VM 103 : Win11-1-Osiris is running
Captured magic packet for address: "bc:24:11:a7:1c:62"
Found LXC with matching MAC, path: /etc/pve/lxc/101.conf
SKIPPED CONTAINER 101 : coolify is running
Captured magic packet for address: "62:1c:a7:11:24:bc"
Checking for inverted MAC address: bc:24:11:a7:1c:62 (for shutdown)
Found LXC with matching inverted MAC, path: /etc/pve/lxc/101.conf
SHUTTING DOWN CONTAINER 101 : coolify is running
Captured magic packet for address: "bc:24:11:a7:1c:62"
Found LXC with matching MAC, path: /etc/pve/lxc/101.conf
STARTING CONTAINER 101 : coolify is stopped
You need enable the skill for your Alexa, and then yes it could send packets you've set up. https://www.amazon.com/Oscar-Penelo-Wake-Lan-WoL/dp/B07PGKK416I could implement this to make alexa start a vm?
We use essential cookies to make this site work, and optional cookies to enhance your experience.