https://github.com/elmodo7/wakeonlan-web-api
A web panel + REST API for monitoring and powering on and off devices from in and outside of your local network. Better used in conjunction with a VPN or my Tunnel Manager app.
https://github.com/elmodo7/wakeonlan-web-api
api api-rest java rest-api spring spring-boot wake-on-lan wake-on-wan wakeonwan web wol
Last synced: 3 months ago
JSON representation
A web panel + REST API for monitoring and powering on and off devices from in and outside of your local network. Better used in conjunction with a VPN or my Tunnel Manager app.
- Host: GitHub
- URL: https://github.com/elmodo7/wakeonlan-web-api
- Owner: elModo7
- License: mit
- Created: 2024-09-17T13:10:34.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2024-12-04T11:32:31.000Z (7 months ago)
- Last Synced: 2025-03-28T09:11:15.105Z (4 months ago)
- Topics: api, api-rest, java, rest-api, spring, spring-boot, wake-on-lan, wake-on-wan, wakeonwan, web, wol
- Language: Java
- Homepage: https://www.linkedin.com/pulse/wake-lan-steroids-your-homelab-v%C3%ADctor-santiago-mart%C3%ADnez-picardo-s8qje/
- Size: 2.97 MB
- Stars: 6
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Wake on LAN on steroids for your HomeLab
This tool will allow you to deploy your own **Web Panel + REST API** for managing your **devices's power status**.
You can expose it using _port-forwarding, VPN_ or _tunneling_ to allow for **Wake on Wan** capabilities.> If you found this to be useful for you, a ⭐**STAR** to the repo would be awesome.
### Remote Shutdown
From version *0.0.8* onwards, this API is compatible with this project **[Remote Shutdown API Service](https://github.com/elModo7/Remote-Shutdown-API)**.This tool will allow you to deploy a **REST API** for **remotely shutting down your devices**.
## A bit of context
Today, we are creating an _interactive web panel_ for **waking up your devices** but with a grain of salt.
While we always talk about _WoL_, we normally don't talk about what happens when you are **outside your network**.
The so-called "**Wake on Wan**" is something I have been doing for quite some while now via different methods like _SSH snippets and Amazon Alexa_.

I have built a **desktop app** similar to **electron based** GUIs. I have no repo for it, but if someone is interested in it *just ask me about it*.
----------
### Alternatives
> While [_Amazon Alexa's WoL tool_](https://www.amazon.com/Oscar-Penelo-Wake-Lan-WoL/dp/B07PGKK416) is quite convenient, it's a **paid option** _once you reach a specific amount of devices or for some extra functions._
I have it and still plan to use it from time to time, but adding new devices is a _bit of a hassle_, it requires **two third-party services** to be up and let's be honest, for the "I control my devices" kind of user, it's not a viable option at all.
_JuiceSSH_ is also a very convenient way of executing a "**wol.sh**" script, but again, snippets are a _paid feature_.
While **cloud** is getting more and more common, having solutions for us that we have our own **on-premise HomeLab** is always a pro, since we really "**own**" our infrastructure.
----------
## Deploying our Application
> In this section, we are going to **expose** a **Spring Boot application** written in **Java 1.8** (for _legacy support_), deploy, containerize and secure its access.
### What we need
- **~~Linux\*~~** Any computer capable of running Java (I am using an [ODROID-XU4](https://wiki.odroid.com/odroid-xu4/odroid-xu4))
- [Java JDK/JRE 1.8 or above](https://www.oracle.com/es/java/technologies/javase/javase8u211-later-archive-downloads.html)
> \* Since version 0.1.2 a *Windows* computer should also be able to send WoL packets using this tool.
### Recommended but not mandatory
- [IntelliJ IDEA](https://www.jetbrains.com/idea/)
- **Wakeonlan** packet installed *(optional since 0.1.2)*
- **Sreeen**, **NoHup** or **Tmux** packet installed
- Ability to **port-forward** and open up ports
- Ability to **VPN or Tunnel** your connection
- **Docker**
- **Certificate or OpenSSL Self-Signed Certificate**
- **Maven**
### Let's start with a basic setup (we will secure, dockerize... later)
We are going to first **build** our project and generate our jar file using **maven**.
Make sure to have **maven in your PATH**.
We will possition ourselves at the **root of our project** and run:> mvn clean install -DskipTests
Then we will copy our generated "**wol.jar"** file to a folder in our Linux box and switch to that folder

WinSSH File Transfer

Let's make sure that we are running a **compatible Java VM** and that we have it added to _PATH_:

Let's start a **background process** with our Spring Boot application, since I'm running SSH, I need the app to _stay deployed once the SSH session is terminated_. I will use **screen** package for this.
So we run "**screen"** command and skip the documentation by pressing **Enter** or **Space**.
Once _inside a screen session_ we run our ***.jar** file:

> sudo java -jar wol.jar
By accessing our **device's ip** using **port 7800** (_default_) using our favourite web browser, we will be presented with this landing login page:

Configuration for this login page can be located in our **application.properties:**

Once we successfully log in, we will see our configured machines and their online status:

We can then turn on our devices by clicking on the power button of each machine, we will be prompted before turning them on to prevent accidentally powering on a device.

> Once our device **turns on** and is **visible network-wise** to our web server, we will see that the **icon will automatically change to a green-bar signal icon.**
### Adding new devices

There is a file in resources called "**_devices.json_**" where you can _add, edit or delete devices_.
The file follows this structure, we can omit the _status_ value but I am adding it for coherence:
```
[ {
"description": "ARM Linux Server",
"id": 3,
"ip": "192.168.12.140",
"mac": "00:1e:06:32:1b:9e",
"name": "ODROID-XU4",
"status": false
} ]
```> We are **all done** here, we learned how to _deploy, change user/password, manage devices_ and have our service _running in the background_.
----------
## Some Extras
----------
### Port-Forwarding
> In order to access our device from outside our network, which is the main attractive of our webapp, we will need to expose this port to the internet.
> No worries as those tech savvy will be able to implement a tunnel to their internal network so as to not expose this web panel unless you tunnel in!
The first step here is to get the **local IP** of the device running our **WoL Web Service**:

We have to **add a rule on our router** targeting our **internal device's IP** address:

> Then, if everything went well and the _service is up_, by using our **external IP** address we should be able to **_access our Wake on Lan (Wan), web panel_**.
----------
### VPN / Tunneling the Connection
One of the ways we can secure our connection is by using a **VPN client** or an **SSH Tunnel**.
In this example I am going to be using **_yet another one of my tools_, SSH Tunnel Manager**.
I have a user set up **only for proxying** on my **ODROID-XU4**, I will be showing an example on _how to do it with my current setup_, but since this is a bit more complex **_it's a bit out of scope for this article_**. You can _find more info_ on the **project's GitHub** pinned here or on my **web portfolio's** _personal project's section_:
[https://elmodo7.github.io/](https://elmodo7.github.io/)
So, since I have a connection already configured to the same device I am deploying this tool to, I can just create a **local tunnel** with this _simple configuration_:

I will just click on **Run Tunnel** to establish a tunnel that **secures the connection** towards the WoL Web Panel:

Now, by accessing [localhost](http://localhost/), via the **port 8888** we are actually accessing our device's **internal IP** at **port 7800**. So we are essentially **redirecting** our traffic **securely via SSH.**
> Notice, that the URL doesn't say HTTP, but **HTTPS**. In the next steps we will be learning how to add self-signed certificates to our Spring Boot application to further encrypt our transfered data.
----------
### Adding HTTPS to your Spring Boot Web app via OPENSSL's Self-Signed Certificate
We won't get too much into the details here on **creating a self-signed certificate** since that is _not the scope of this article_, but you can follow [this _great guide_ on **_how to create your own self-signed certificate_**](https://www.baeldung.com/openssl-self-signed-cert).
In order to **_add our newly created certificate to our Spring Boot application_** we will add this configuration to our [**application.properties**](http://application.properties/):
> Yes, it really was that _simple_ to **add HTTPS** to our **Web Panel**.
----------
### Dockerizing our Spring Boot Application
In order to **containerize and deploy** this tool, with *docker engine installed* you can **create this two files**:
**File**: dockerfile
FROM openjdk:17-jdk-slim
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} wol.jar
ENTRYPOINT ["java","-jar","/wol.jar"]**File**: deploy.sh
docker build -t "wol_api" .
docker run -d --name "WoL_API" -p 7800:7800/tcp "wol_api"Create a *new folder* called **target**, and put inside your generated **wol.jar**.
You should have a structure similar to this one:

Add **permission** to deploy.sh to run it:
sudo chmod 755 deploy.sh
Then just **run** the deploy script:
. deploy.sh
You should now have a *running container* called **WoL_API** and endpoint **https://0.0.0.0:7800/** should now be accessible.
## Remote Shutdown API Service
From version *0.0.8* onwards, this API is compatible with this project **[Remote Shutdown API Service](https://github.com/elModo7/Remote-Shutdown-API)**.
This tool will allow you to deploy a **REST API** for **remotely shutting down your devices**.
> You can run this **remote shutdown** service on your devices for allowing the web panel to shut down other devices on your network.It is compatible with theese hosts:
- Windows
- Unix
- MacOS
- Solaris## Code diagram
```mermaid
flowchart TD
%% Top Level: Client
B["Browser (Web Panel)"]:::client%% Web Client Layer Subgraph
subgraph "Web Client Layer"
HT["HTML Templates"]:::client
SR["Static Resources"]:::client
end%% Application Server Container Node
SBA["Spring Boot Application (Container)"]:::backend%% Backend Layers Subgraph
subgraph "Controller Layer"
HC["HomeController"]:::controller
LC["LoginController"]:::controller
DC["DevicesController"]:::controller
endsubgraph "Service Layer"
WS["WakeService"]:::service
WSI["WakeServiceImpl"]:::service
PS["PingService"]:::service
endsubgraph "Configuration Components"
AC["AppConfiguration"]:::config
HC2["HttpsConfig"]:::config
WC["WebConfig"]:::config
end%% Data/Configuration Storage Subgraph
subgraph "Data & Configuration Storage"
AP["Application Properties"]:::data
DEV["Devices Configuration"]:::data
end%% External Integration Components Subgraph
subgraph "External Integration"
RD["Remote Shutdown API Service"]:::external
RU["RestUtils"]:::external
end%% Deployment Artifacts Subgraph
subgraph "Deployment Artifacts"
MB["Maven Build File"]:::deployment
LS["Linux Service Template"]:::deployment
end%% Data Flow Arrows
B -->|"HTTP/HTTPS"| LC
B -->|"HTTP/HTTPS"| DC
HT --- B
SR --- B%% Controllers delegating to Service Layer
LC -->|"delegate"| WS
DC -->|"delegate"| WS
HC -->|"render view"| HT%% Service Layer relationships
WS -->|"uses"| WSI
WSI -->|"reads"| AP
WSI -->|"reads"| DEV
WS -->|"triggers"| RD
RD --> RU%% Controllers & Service access Configuration Components
HC2 --- WS
AC --- WS
WC --- LC%% Deployment arrow from Spring Boot App Container
SBA --- MB
SBA --- LS%% Link the Backend Container with its internal layers
SBA --- HC
SBA --- LC
SBA --- DC
SBA --- WS
SBA --- WSI
SBA --- PS
SBA --- AC
SBA --- HC2
SBA --- WC%% Styles
classDef client fill:#f9e79f,stroke:#000,stroke-width:2px;
classDef controller fill:#aed6f1,stroke:#000,stroke-width:2px;
classDef service fill:#d5f5e3,stroke:#000,stroke-width:2px;
classDef config fill:#f5b7b1,stroke:#000,stroke-width:2px;
classDef data fill:#d6eaf8,stroke:#000,stroke-width:2px;
classDef external fill:#f0b27a,stroke:#000,stroke-width:2px;
classDef deployment fill:#e8daef,stroke:#000,stroke-width:2px;
classDef backend fill:#fad7a0,stroke:#000,stroke-width:2px;%% Click Events for Web Client Layer
click HT "https://github.com/elmodo7/wakeonlan-web-api/tree/main/src/main/resources/templates"
click SR "https://github.com/elmodo7/wakeonlan-web-api/tree/main/src/main/resources/static"%% Click Events for Controller Layer
click HC "https://github.com/elmodo7/wakeonlan-web-api/blob/main/src/main/java/com/em7/wol/controller/HomeController.java"
click LC "https://github.com/elmodo7/wakeonlan-web-api/blob/main/src/main/java/com/em7/wol/controller/LoginController.java"
click DC "https://github.com/elmodo7/wakeonlan-web-api/blob/main/src/main/java/com/em7/wol/controller/devices/DevicesController.java"%% Click Events for Service Layer
click WS "https://github.com/elmodo7/wakeonlan-web-api/blob/main/src/main/java/com/em7/wol/service/WakeService.java"
click WSI "https://github.com/elmodo7/wakeonlan-web-api/blob/main/src/main/java/com/em7/wol/service/WakeServiceImpl.java"
click PS "https://github.com/elmodo7/wakeonlan-web-api/blob/main/src/main/java/com/em7/wol/service/PingService.java"%% Click Events for Configuration Components
click AC "https://github.com/elmodo7/wakeonlan-web-api/blob/main/src/main/java/com/em7/wol/config/AppConfiguration.java"
click HC2 "https://github.com/elmodo7/wakeonlan-web-api/blob/main/src/main/java/com/em7/wol/config/HttpsConfig.java"
click WC "https://github.com/elmodo7/wakeonlan-web-api/blob/main/src/main/java/com/em7/wol/config/WebConfig.java"%% Click Events for Data/Configuration Storage
click AP "https://github.com/elmodo7/wakeonlan-web-api/blob/main/src/main/resources/application.properties"
click DEV "https://github.com/elmodo7/wakeonlan-web-api/blob/main/src/main/resources/devices.json"%% Click Event for External Integration Component
click RU "https://github.com/elmodo7/wakeonlan-web-api/blob/main/src/main/java/com/em7/wol/util/RestUtils.java"%% Click Events for Deployment Artifacts
click MB "https://github.com/elmodo7/wakeonlan-web-api/blob/main/pom.xml"
click LS "https://github.com/elmodo7/wakeonlan-web-api/tree/main/wolapi_linux_service_template"
```## Add WoL_API as startup service for Unix
Position yourself at the **init.d** folder:
cd /etc/init.d/
Paste the contents of the file in this repo named **wolapi_linux_service_template** into a file named **wolapi**.
Execute the following commands as **root**:
chmod +x wolapi
chown root wolapi
chgrp root wolapi
update-rc.d wolapi defaults
systemctl daemon-reloadYou should now have a service called **wolapi** running that will start on boot.
## Final Thoughts
> There are may be **many ways** to power on your devices when you are not at home, but we developed **our own solution** for this task that just works and **_provides a high security while having full control over it_**.
## Sources & Inspirations
Native Java WoL packets *(0.1.2)* based on: https://github.com/Cyecize/Remote-Wake-On-Lan-Web