REMOTE POWER // MAGIC PACKET PROTOCOL // POTATOSIPS

REMOTE WAKE-ON-LAN

▸ VPS · WIREGUARD · OPENWRT · NGINX · DARK MAGIC ◂
Your PC is off. You're at work, on a train, or in another country eating questionable food. You need your home machine running. Right now. This guide turns a URL into a defibrillator for your computer — no port forwarding, no exposed LAN, no praying to the networking gods. Just a magic packet fired over an encrypted tunnel like a responsible adult who still names their router.

00 What This Does

You visit a URL on your VPS. That URL triggers a chain of events that ends with your PC waking up from across the planet. No port forwarding on your home router. No exposing your LAN to the internet. Just encrypted tunnel magic and a 102-byte UDP packet that somehow brings hardware back from the dead.

BROWSER
your phone / laptop
VPS
public IP
NGINX
web server
FCGIWRAP
CGI runner
WAKE.SH
on VPS
SSH/WIREGUARD
encrypted tunnel
OPENWRT
router on LAN
PC WAKES
✓ finally
⬡ This design is intentional. WoL magic packets only work reliably from inside the LAN. OpenWrt fires the packet locally. The VPS just tells it when to pull the trigger.

01 Tested Example Values

Replace these with your own. Do not use these exact values unless you want to wake up a random stranger's PC — which is rude, and also probably impossible, but still rude.

THINGEXAMPLE VALUE
PC MAC addressxx:xx:xx:xx:xx:xx
VPS public IPv4xxx.xxx.xxx.xxx
WireGuard VPS tunnel IP10.100.0.1/24
WireGuard OpenWrt tunnel IP10.100.0.2/24
WireGuard UDP port51820

02 Prerequisites

COMPONENTDETAIL
VPSUbuntu or Debian — cloud provider of your choice
OpenWrt routerWith internet access and SSH enabled
IPv6 on OpenWrt WANRequired for the tunnel setup
PCConnected by Ethernet — Wi-Fi WoL is a myth and a lie
WoL in BIOS/UEFIMust be enabled. Every BIOS calls it something different. Good luck.
WoL in OSWindows: Device Manager → NIC → Power Management. Linux: ethtool
SSH accessTo both OpenWrt and the VPS
sudo on VPSOr you'll be crying into your terminal
☠ Using Wi-Fi? Wake-on-LAN over Wi-Fi is theoretically supported and practically useless. Plug in an Ethernet cable. This is non-negotiable. The spec says yes. Reality says no.

03 Step 1 — Confirm WoL Works Locally First

▲ Do not skip this. If WoL doesn't work from inside your own house, it will definitely not work from a VPS in another continent. Fix it locally first. Then feel smug about it.

▸ 1.1 Install WoL Tools on OpenWrt

SSH into OpenWrt and run:

OpenWrt SSH // INSTALL
opkg update
opkg install etherwake luci-app-wol

▸ 1.2 Test Wake from OpenWrt

OpenWrt SSH // TEST WoL
etherwake -i br-lan xx:xx:xx:xx:xx:xx

Not sure of your LAN interface name? Find it:

OpenWrt SSH
ip link
PC woke up? Good. Continue. PC did not wake up? Stop here. Fix your BIOS settings, your NIC power management, or your will to live — in that order.

04 Step 2 — Install WireGuard

▸ 2.1 On the VPS

VPS Bash // INSTALL WIREGUARD
sudo apt update
sudo apt install wireguard

If you use UFW:

VPS Bash // UFW
sudo ufw allow 51820/udp

▸ 2.2 On OpenWrt

OpenWrt SSH // INSTALL WIREGUARD
opkg update
opkg install wireguard-tools luci-proto-wireguard kmod-wireguard

05 Step 3 — Generate WireGuard Keys

▸ 3.1 On OpenWrt

OpenWrt SSH // KEYGEN
wg genkey | tee /etc/wireguard/privatekey | wg pubkey > /etc/wireguard/publickey
cat /etc/wireguard/publickey

▸ 3.2 On the VPS

VPS Bash // KEYGEN
wg genkey | tee privatekey | wg pubkey > publickey
cat publickey
☠ Never share private keys. Only public keys go into the opposite side's config. If you paste your private key somewhere public, generate new ones immediately and pretend this moment never happened. We won't judge you. Much.

06 Step 4 — Configure WireGuard on the VPS

VPS Bash // CREATE CONFIG
sudo nano /etc/wireguard/wg0.conf
/etc/wireguard/wg0.conf
wg0.conf // INI
[Interface]
PrivateKey = <VPS_PRIVATE_KEY>
Address    = 10.100.0.1/24
ListenPort = 51820

[Peer]
PublicKey  = <OPENWRT_PUBLIC_KEY>
AllowedIPs = 10.100.0.2/32

Get your VPS private key:

VPS Bash
cat privatekey

Enable and start WireGuard:

VPS Bash // ENABLE SERVICE
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
sudo wg

You should see interface wg0 listed. If you don't, the universe is testing you.

07 Step 5 — Configure WireGuard on OpenWrt

OpenWrt SSH // UCI CONFIG
uci set network.wg0=interface
uci set network.wg0.proto='wireguard'
uci set network.wg0.private_key='<OPENWRT_PRIVATE_KEY>'
uci set network.wg0.listen_port='51820'
uci add_list network.wg0.addresses='10.100.0.2/24'

uci add network wireguard_wg0
uci set network.@wireguard_wg0[-1].public_key='<VPS_PUBLIC_KEY>'
uci set network.@wireguard_wg0[-1].endpoint_host='xxx.xxx.xxx.xxx'
uci set network.@wireguard_wg0[-1].endpoint_port='51820'
uci set network.@wireguard_wg0[-1].persistent_keepalive='25'
uci add_list network.@wireguard_wg0[-1].allowed_ips='10.100.0.1/32'

uci commit network
/etc/init.d/network restart

Get your OpenWrt private key:

OpenWrt SSH
cat /etc/wireguard/privatekey

08 Step 6 — OpenWrt Firewall Rules

▲ Don't skip the firewall zone. Traffic arriving on wg0 will be silently dropped without it. You'll spend an hour wondering why everything looks correct but nothing works. We've been there. It's not fun.

▸ 6.1 Allow Incoming WireGuard on WAN

OpenWrt SSH // FIREWALL
uci add firewall rule
uci set firewall.@rule[-1].name='Allow-WireGuard'
uci set firewall.@rule[-1].src='wan'
uci set firewall.@rule[-1].dest_port='51820'
uci set firewall.@rule[-1].proto='udp'
uci set firewall.@rule[-1].target='ACCEPT'

▸ 6.2 Create WireGuard Firewall Zone

OpenWrt SSH // ZONE
uci add firewall zone
uci set firewall.@zone[-1].name='wg'
uci set firewall.@zone[-1].network='wg0'
uci set firewall.@zone[-1].input='ACCEPT'
uci set firewall.@zone[-1].forward='ACCEPT'
uci set firewall.@zone[-1].output='ACCEPT'

▸ 6.3 Allow Forwarding from WireGuard to LAN

OpenWrt SSH // FORWARDING
uci add firewall forwarding
uci set firewall.@forwarding[-1].src='wg'
uci set firewall.@forwarding[-1].dest='lan'

▸ 6.4 Apply Changes

OpenWrt SSH // APPLY
uci commit firewall
/etc/init.d/firewall restart

09 Step 7 — Test the WireGuard Tunnel

▸ From the VPS

VPS Bash // PING
ping 10.100.0.2

▸ From OpenWrt

OpenWrt SSH // PING
ping 10.100.0.1

▸ Check Handshake

VPS Bash // WG STATUS
sudo wg

You want to see the OpenWrt peer listed, a recent handshake, and bytes transferred in both directions.

☠ Do not continue until both sides can ping each other and the handshake shows up. Proceeding without a working tunnel is like wiring a detonator to a lamp and wondering why the lights don't work.

10 Step 8 — Create Wake Script on OpenWrt

OpenWrt SSH // CREATE SCRIPT
nano /root/wake.sh
/root/wake.sh
wake.sh // SHELL
#!/bin/sh
etherwake -i br-lan xx:xx:xx:xx:xx:xx
OpenWrt SSH // CHMOD + TEST
chmod +x /root/wake.sh
/root/wake.sh
PC woke? Good. This script is the one true source of truth. Everything else is just infrastructure to run it.

11 Step 9 — SSH Key Auth from VPS to OpenWrt

The web-triggered script runs as www-data. It cannot type a password. We need passwordless SSH from VPS → OpenWrt over the WireGuard tunnel.

▸ 9.1 Generate SSH Key on the VPS

VPS Bash // KEYGEN
ssh-keygen -t ed25519 -f ~/oracle_emochii

This creates ~/oracle_emochii (private) and ~/oracle_emochii.pub (public).

▸ 9.2 Add Public Key to OpenWrt

OpenWrt SSH // AUTHORIZED KEYS
mkdir -p /etc/dropbear
nano /etc/dropbear/authorized_keys

Paste the contents of:

VPS Bash // SHOW PUBKEY
cat ~/oracle_emochii.pub

Fix permissions:

OpenWrt SSH // CHMOD
chmod 600 /etc/dropbear/authorized_keys

▸ 9.3 Test SSH from VPS

VPS Bash // TEST SSH
ssh -i ~/oracle_emochii root@10.100.0.2

▸ 9.4 Test Remote Wake Command

VPS Bash // REMOTE WAKE TEST
ssh -i ~/oracle_emochii root@10.100.0.2 "/root/wake.sh"
☠ Still asking for a password? Check the key was pasted correctly, permissions are 600, and you're using the right key pair. Do not continue until this works passwordlessly. The web trigger cannot type passwords. It has no hands.

12 Step 10 — Install Nginx and fcgiwrap

VPS Bash // INSTALL
sudo apt install nginx fcgiwrap
sudo systemctl enable nginx
sudo systemctl enable fcgiwrap
sudo systemctl start nginx
sudo systemctl start fcgiwrap

Allow HTTP through UFW:

VPS Bash // UFW
sudo ufw allow 80/tcp

13 Step 11 — Create Wake Script on the VPS

VPS Bash // MKDIR + CREATE
sudo mkdir -p /usr/local/lib/wake
sudo nano /usr/local/lib/wake/wake.sh
/usr/local/lib/wake/wake.sh
wake.sh // BASH CGI SCRIPT
#!/bin/bash
echo "Content-Type: text/plain"
echo ""

/usr/bin/ssh \
  -i /usr/local/lib/wake/oracle_emochii \
  -o BatchMode=yes \
  -o StrictHostKeyChecking=no \
  -o UserKnownHostsFile=/dev/null \
  root@10.100.0.2 "/root/wake.sh"

rc=$?
echo "ssh exit code: $rc"

if [ "$rc" -eq 0 ]; then
  echo "wake sent"
else
  echo "wake failed"
fi
VPS Bash // PERMISSIONS
sudo chown root:root /usr/local/lib/wake/wake.sh
sudo chmod 755 /usr/local/lib/wake/wake.sh

14 Step 12 — Make SSH Key Available to the Web Script

The script runs as www-data. It can't read your home directory's private key. Copy it somewhere accessible — but not world-readable, because we're not animals.

VPS Bash // COPY KEY
sudo cp ~/oracle_emochii /usr/local/lib/wake/oracle_emochii
sudo chown root:www-data /usr/local/lib/wake/oracle_emochii
sudo chmod 640 /usr/local/lib/wake/oracle_emochii
sudo chmod 755 /usr/local/lib/wake

15 Step 13 — Configure Nginx

VPS Bash // EDIT NGINX SITE
sudo nano /etc/nginx/sites-available/default
/etc/nginx/sites-available/default
nginx.conf // NGINX
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
        try_files $uri $uri/ =404;
    }

    # Use a long random path — don't just use /wake
    location /wake-9f3a7c1b2e {
        include fastcgi_params;
        fastcgi_pass unix:/run/fcgiwrap.socket;
        fastcgi_param SCRIPT_FILENAME /usr/local/lib/wake/wake.sh;
    }
}
▲ The location /wake-... block must be inside the server {} block. Putting it outside the closing } is the #1 mistake that breaks Nginx. Nginx's error message will be cryptic. Your frustration will not be.

Your final wake URL will be:

http://xxx.xxx.xxx.xxx/wake-9f3a7c1b2e

16 Step 14 — Validate and Reload Nginx

VPS Bash // VALIDATE + RELOAD
sudo nginx -t
sudo systemctl restart nginx
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

17 Step 15 — Test the Whole Chain

▸ 15.1 Test Script as www-data First

This is the most important debugging step. If this works, the web trigger will work.

VPS Bash // TEST AS WWW-DATA
sudo -u www-data /usr/bin/ssh \
  -i /usr/local/lib/wake/oracle_emochii \
  -o BatchMode=yes \
  -o StrictHostKeyChecking=no \
  -o UserKnownHostsFile=/dev/null \
  root@10.100.0.2 "/root/wake.sh"

▸ 15.2 Test the Local Web Endpoint

VPS Bash // CURL TEST
curl -i http://127.0.0.1/wake-9f3a7c1b2e
ssh exit code: 0 wake sent

▸ 15.3 Test from Browser or Phone

http://xxx.xxx.xxx.xxx/wake-9f3a7c1b2e
PC woke up from a URL on your phone? You're done. You are now the kind of person who can wake their home computer from an airport lounge at 2 AM. Use this power wisely.

18 Step 16 — Service Checks

VPS Bash // STATUS CHECK
sudo systemctl is-active nginx
sudo systemctl is-active fcgiwrap
sudo systemctl is-active wg-quick@wg0
active active active

Three times active. Anything else means something is broken and you have a date with journalctl.

19 Troubleshooting

▸ Nginx Fails to Restart

VPS Bash // DIAGNOSE NGINX
sudo nginx -t
sudo systemctl status nginx
sudo journalctl -xeu nginx.service

Usual culprit: the location block is outside the server {} block. Classic.

▸ Browser Shows 403 Forbidden

Possible causes: wrong script path, fcgiwrap can't execute the script, or the key isn't readable by www-data.

VPS Bash // DIAGNOSE 403
ls -ld /usr/local /usr/local/lib /usr/local/lib/wake
ls -l /usr/local/lib/wake
sudo tail -n 50 /var/log/nginx/error.log
sudo journalctl -u fcgiwrap --no-pager -n 50

▸ Page Says "wake sent" but PC Doesn't Wake

The script in this guide prints the actual SSH exit code. If it says ssh exit code: 0 but the PC doesn't wake, the problem is WoL itself — BIOS settings, NIC config, or a switch that drops magic packets. Test directly:

VPS Bash // DIRECT TEST
sudo -u www-data /usr/bin/ssh \
  -i /usr/local/lib/wake/oracle_emochii \
  -o BatchMode=yes \
  -o StrictHostKeyChecking=no \
  -o UserKnownHostsFile=/dev/null \
  root@10.100.0.2 "/root/wake.sh"
☠ If the SSH succeeds but the PC still won't wake, that's a hardware problem. Go into BIOS and re-enable Wake-on-LAN. Then do it again after the next BIOS update resets it. This is just how it is. We're sorry.

20 What You Now Have

CAPABILITYSTATUS
Wake PC from anywhere on Earth✓ OPERATIONAL
No home port forwarding✓ CLEAN
WireGuard-encrypted communication✓ SECURED
WoL packet sent from inside LAN✓ RELIABLE
One-click trigger from browser/phone✓ DEPLOYED
Your home network exposed to internet✗ NONE
⬡ Your PC is now just a URL away from consciousness. Treat it with respect. It didn't ask to be woken up at 3 AM either.