Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
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.
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: 8 days ago
JSON representation
A web panel + REST API for monitoring and powering on and off devices from in and outside of your local network.
- Host: GitHub
- URL: https://github.com/elmodo7/wakeonlan-web-api
- Owner: elModo7
- License: mit
- Created: 2024-09-17T13:10:34.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2024-09-26T14:51:27.000Z (about 2 months ago)
- Last Synced: 2024-11-08T07:05:31.550Z (8 days 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.96 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
![enter image description here](https://media.licdn.com/dms/image/v2/D4E12AQF6AW53XmHJKQ/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1726568056394?e=1732147200&v=beta&t=ewBC8EpUBnNUM3v8IaNtCi9PfXQsgsXlUNNOoI1CrhI)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_.
![image](https://github.com/user-attachments/assets/04debbfd-25a7-426a-bbb1-f3b4da26321c)
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
![](https://media.licdn.com/dms/image/v2/D4E12AQGSZ3uBdJobKg/article-inline_image-shrink_400_744/article-inline_image-shrink_400_744/0/1726571623901?e=1732147200&v=beta&t=7EBZgbBgvYvj5J9ga7Slj2cH7-ZJuKTxwYi_Z2-Xkow)
WinSSH File Transfer
![](https://media.licdn.com/dms/image/v2/D4E12AQEkSV7th8jrIg/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1726570508467?e=1732147200&v=beta&t=A3o4PDFL-IOLdzYkEqq7pPJGhMiKBwRrvUa7tCsAlgA)
Let's make sure that we are running a **compatible Java VM** and that we have it added to _PATH_:
![](https://media.licdn.com/dms/image/v2/D4E12AQFTj4Nhld4kdw/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1726570454382?e=1732147200&v=beta&t=eFtbp4zzUu4pNcoYpjt5L-dt6EJpkwP-_7PoFlSlnhc)
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:
![](https://media.licdn.com/dms/image/v2/D4E12AQF94map9Ghwdg/article-inline_image-shrink_400_744/article-inline_image-shrink_400_744/0/1726571263123?e=1732147200&v=beta&t=Cz3FD8TXMfYN3C8QUaBpocWV7fjxGAkShkE_q24YH7A)
> 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:
![](https://media.licdn.com/dms/image/v2/D4E12AQH6-0LQ8Se0EQ/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1726571882500?e=1732147200&v=beta&t=6loJYVU6Cv43-4jJBii-SUH9sci_ci580zuRemskFt4)
Configuration for this login page can be located in our **application.properties:**
![](https://media.licdn.com/dms/image/v2/D4E12AQFdZPyEYv2hcg/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1726572017555?e=1732147200&v=beta&t=AGpRoIos6_7RT4tJGwOApmay36SYmGc31Vu2921OmEY)
Once we successfully log in, we will see our configured machines and their online status:
![Shutdown Enabled](https://github.com/user-attachments/assets/fe450184-f923-455e-b830-9ed1f77e7e4b)
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.
![](https://media.licdn.com/dms/image/v2/D4E12AQGLniESHr0kIw/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1726572339824?e=1732147200&v=beta&t=a2b-q_Zkwb3xRSstsSFwKLPlRB5IQ3DrmXCTJEqLfTc)
> 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
![](https://media.licdn.com/dms/image/v2/D4E12AQHCTnIlFNgfeQ/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1726572679395?e=1732147200&v=beta&t=WKxvsYZLVdLs4NO5WFA5AUJa9kRBoJNfD100RAEd84A)
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**:
![](https://media.licdn.com/dms/image/v2/D4E12AQGv2n0IQPXR3w/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1726573482244?e=1732147200&v=beta&t=b5FKYFHjmI-_RXnNKFL3jsGPxRy_wNxubzyo_Ltb3AI)
We have to **add a rule on our router** targeting our **internal device's IP** address:
![](https://media.licdn.com/dms/image/v2/D4E12AQEijWWCzca9xA/article-inline_image-shrink_400_744/article-inline_image-shrink_400_744/0/1726573691776?e=1732147200&v=beta&t=YpNAtpxLbBSAs-DZRWMen8Gz5TXUzdz8MA6KS7e4lvY)
> 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_:
![enter image description here](https://media.licdn.com/dms/image/v2/D4E12AQEBMXtbWk0HEA/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1726576749914?e=1732147200&v=beta&t=Uf9AIbtRgLvM1BFTdc1jXgFQLVmawqdEp7DDO4VQqDQ)![enter image description here](https://media.licdn.com/dms/image/v2/D4E12AQGQnkl1yvIRWQ/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1726576686635?e=1732147200&v=beta&t=UFr-WcVB3Y270kKTjHO0L5TNgGCV-Z7OUuxwBeCaboQ)
I will just click on **Run Tunnel** to establish a tunnel that **secures the connection** towards the WoL Web Panel:
![enter image description here](https://media.licdn.com/dms/image/v2/D4E12AQGiaxP14nGn0w/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1726576674745?e=1732147200&v=beta&t=yTXBwhiUqH1f1v4CVRz6fzAKavRZ6B6gHJ1qbvXkFa8)
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:
![imagen](https://github.com/user-attachments/assets/c1096623-9eb1-4ce9-b2bb-4727730c8b3a)
Add **permission** to deploy.sh to run it:
sudo chmod 755 deploy.sh
Then just **run** the deploy script:
. deploy.sh
![imagen](https://github.com/user-attachments/assets/9b983397-fbfa-4aef-9d5d-f7f190d79da9)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## 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