Building a Secure Wake-on-LAN Server with an Old Android Phone and Cloudflare
Transform an old Android phone into an ultra-low-power jump server for secure remote Wake-on-LAN access using Termux and Cloudflare Tunnels, eliminating the need to leave your PC running 24/7.
Building a Secure Wake-on-LAN Server with an Old Android Phone and Cloudflare
I have a powerful desktop PC that I need to access remotely, but I hate leaving it on 24/7. It’s loud, consumes a lot of electricity, and feels wasteful. My goal was to find a way to turn it on from anywhere, securely, without opening any ports on my home router. The solution? Repurposing an old, forgotten Android phone into an ultra-low-power “jump server.”
This guide details how I turned an old Xiaomi phone into a secure Wake-on-LAN (WoL) server using Termux and Cloudflare Tunnels, allowing me to wake my main PC from a browser on any device.
The Big Picture: Our Architecture
The Target PC: My main Windows machine, connected to the router via Ethernet and configured for Wake-on-LAN. It remains off or asleep until needed.
The Jump Server: An old Android phone, always on and plugged in. It runs a Cloudflare Tunnel and an SSH server. Its only job is to receive my secure command and send the WoL “magic packet” to the Target PC.
Cloudflare: The secure bridge between me and my home network. It provides a public-facing, secure URL that connects to my phone, without me having to open any ports.
Step 1: Preparing the Target PC for Wake-on-LAN
First, I had to ensure my main PC would respond to the wake-up call.
Ethernet is Key: WoL is notoriously unreliable over Wi-Fi. I connected my PC directly to my router with an Ethernet cable.
BIOS/UEFI Settings: I restarted my PC and entered the BIOS setup. I had to find the “Power Management” section and enable a setting called “Wake on LAN” (sometimes called “Power On by PCIE device”).
Windows Settings: In Device Manager, I found my Ethernet adapter’s properties. Under the “Power Management” tab, I checked “Allow this device to wake the computer.” Under the “Advanced” tab, I enabled “Wake on Magic Packet.”
Get the MAC Address: In Command Prompt, I ran ipconfig /all and noted the “Physical Address” of my Ethernet adapter (e.g., AA-BB-CC-DD-EE-FF). This is the unique identifier the WoL packet needs.
Step 2: Setting Up the Android “Jump Server”
This is where the old phone comes into play.
Phone Prep: I did a factory reset, connected it to Wi-Fi, and plugged it into a permanent charger. A critical step was enabling Developer Options and turning on the “Stay awake” setting, which prevents the phone from sleeping while charging. I’m not entirely sure if this setting was actually necessary, but I enabled it just in case to ensure maximum reliability.
Disable Battery Optimizations: To prevent Android from killing Termux in the background, I went to Settings and disabled battery optimizations for Termux. This ensures the app can run continuously without being terminated by the system.
Enable Termux Wakelock: Inside Termux, I also enabled the wakelock feature by running termux-wake-lock. This prevents the device from entering deep sleep while Termux services are running. Again, I’m not certain this was strictly necessary, but I enabled it as an extra precaution.
Install Termux: The Google Play Store version of Termux is outdated. I installed the latest version from the F-Droid app store, which is highly recommended.
Install Tools: Inside Termux, I installed all the necessary packages:
pkg install termux-services openssh wol cloudflared
Set SSH Password: I ran the passwd command to set a secure password for logging into Termux.
Step 3: Creating the Secure Tunnel on the Phone
This part connects the phone to the outside world securely.
Cloudflare Login: In Termux, I ran cloudflared tunnel login.
Create Tunnel: I created a new tunnel:
cloudflared tunnel create phone-wol-tunnel
Configure Tunnel: I created a config.yml file in ~/.cloudflared/. This is a locally-managed tunnel, so this file defines its behavior. I used a unique subdomain, wake.yourdomain.com, to avoid conflicts.
tunnel: <YOUR-PHONE-TUNNEL-UUID>
credentials-file: /data/data/com.termux/files/home/.cloudflared/<YOUR-PHONE-TUNNEL-UUID>.json
ingress:
- hostname: wake.yourdomain.com
service: ssh://localhost:8022
- service: http_status:404
Route DNS: I linked the DNS record to the tunnel:
cloudflared tunnel route dns phone-wol-tunnel wake.yourdomain.com
Step 4: Making it Persistent and Convenient
For this to be a true server, it needed to run 24/7 and survive reboots.
termux-services: I created a custom service script to ensure cloudflared runs constantly. The script needed to use the correct Termux shell path: #!/data/data/com.termux/files/usr/bin/sh.
Termux:Boot: I installed the Termux:Boot app and created a simple script in ~/.termux/boot/ to automatically start all my services (sshd, cloudflared) when the phone reboots.
Wake-Up Script: To avoid typing the long MAC address every time, I created a wake.sh script in my Termux home directory:
#!/data/data/com.termux/files/usr/bin/sh
echo "Sending wake-up packet to the PC..."
wol -p 9 <YOUR-LAPTOPS-MAC-ADDRESS>
echo "Packet sent."
Step 5: Securing Everything with Cloudflare Access
This is the final, crucial step.
In the Cloudflare Zero Trust dashboard, I created a new Access Application.
I pointed it to wake.yourdomain.com.
Crucially, I enabled Browser Rendering for SSH. This allows me to access the Termux command line from any web browser, without needing an SSH client.
I created a simple policy to only allow my email address to access it and enabled the HttpOnly cookie attribute for extra security against script-based attacks.
Finally, I enabled “Show in App Launcher” for easy access.
Troubleshooting & Lessons Learned
DNS Failures in Termux: Initially, when attempting to use a manually downloaded cloudflared binary, I ran into persistent DNS errors on the old version of Android. The fix was to abandon the manual download and install cloudflared directly from the official Termux repository using pkg install cloudflared. The repository version correctly handles the necessary network configurations and dependencies.
WoL Packet Port: My biggest hurdle was that WoL packets weren’t being recognized. After running Wireshark on my PC, I discovered the wol command was sending packets to a random high port by default. The fix was to explicitly specify the standard port with the -p 9 flag in my wake.sh script.
With this setup, I can now log into my Cloudflare App Launcher from any browser, open a secure terminal to my phone, and run a single script to wake up my main PC.