-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
037af3c
commit 4da94d6
Showing
14 changed files
with
729 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# docker build -t wolweb . | ||
FROM golang:buster AS builder | ||
|
||
LABEL org.label-schema.vcs-url="https://github.com/sameerdhoot/wolweb" \ | ||
org.label-schema.url="https://github.com/sameerdhoot/wolweb/blob/master/README.md" | ||
|
||
RUN mkdir /wolweb | ||
WORKDIR /wolweb | ||
|
||
# Install Dependecies | ||
RUN git clone https://github.com/sameerdhoot/wolweb . && \ | ||
go get -d github.com/gorilla/handlers && \ | ||
go get -d github.com/gorilla/mux && \ | ||
go get -d github.com/ilyakaznacheev/cleanenv | ||
|
||
# Build Source Files | ||
RUN go build -o wolweb . | ||
|
||
# Create 2nd Stage final image | ||
FROM debian | ||
WORKDIR /wolweb | ||
COPY --from=builder /wolweb/index.html . | ||
COPY --from=builder /wolweb/wolweb . | ||
COPY --from=builder /wolweb/devices.json . | ||
COPY --from=builder /wolweb/config.json . | ||
COPY --from=builder /wolweb/static ./static | ||
|
||
ARG WOLWEBPORT=8089 | ||
|
||
CMD ["/wolweb/wolweb"] | ||
|
||
EXPOSE ${WOLWEBPORT} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# docker build -t wolweb . | ||
FROM golang:alpine AS builder | ||
|
||
LABEL org.label-schema.vcs-url="https://github.com/sameerdhoot/wolweb" \ | ||
org.label-schema.url="https://github.com/sameerdhoot/wolweb/blob/master/README.md" | ||
|
||
RUN mkdir /wolweb | ||
WORKDIR /wolweb | ||
|
||
# Install Dependecies | ||
RUN apk update && apk upgrade && \ | ||
apk add --no-cache git && \ | ||
git clone https://github.com/sameerdhoot/wolweb . && \ | ||
go get -d github.com/gorilla/handlers && \ | ||
go get -d github.com/gorilla/mux && \ | ||
go get -d github.com/ilyakaznacheev/cleanenv | ||
|
||
# Build Source Files | ||
RUN go build -o wolweb . | ||
|
||
# Create 2nd Stage final image | ||
FROM alpine | ||
WORKDIR /wolweb | ||
COPY --from=builder /wolweb/index.html . | ||
COPY --from=builder /wolweb/wolweb . | ||
COPY --from=builder /wolweb/devices.json . | ||
COPY --from=builder /wolweb/config.json . | ||
COPY --from=builder /wolweb/static ./static | ||
|
||
ARG WOLWEBPORT=8089 | ||
|
||
CMD ["/wolweb/wolweb"] | ||
|
||
EXPOSE ${WOLWEBPORT} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,132 @@ | ||
# wolweb | ||
Web interface for sending Wake-on-lan (magic packet) | ||
# Web interface for sending Wake-on-lan (magic packet) | ||
|
||
A GoLang based HTTP server which will send a Wake-on-lan package (magic packet) on local network. The request can be send using web interface or directly using HTTP request with mapped device name in the URL. The only computing device I have running 24x7 is handy-dandy Raspberry Pi 4 (4gb) with docker containers. All other devices like server, laptop and NAS as powered only when I need them. I needed a way to easily turn them on specifically when trying to automate things like nightly builds. | ||
|
||
I use this application behind NGINX web proxy which is secured with HTTPS certificate. It has no authentication, but it is home network and the reason I built this was to have no authentication. I have the same functionality provided in my home router, but I have to login and go through several clicks. Also, this app runs as docker image so even if it is hacked, it reduces the attack surface. | ||
|
||
I have bookmarked direct link to device(s) on my browsers to wake them using single HTTP call for ease of access. | ||
|
||
Things I use this for: | ||
- to wake-up mu home laptop remotely. I use my home laptop remotely over RDP. | ||
- this is also helpful in building routines which will wake up my server and nightly builds and when it is all done, go back to sleep. I don't keep my home lab running 24x7 as it is a waste of energy. | ||
- to turn on my NAS and laptop to start the weekly backup from laptop to NAS. | ||
- to turn on NAS quickly when we are watching movies stored on NAS. | ||
|
||
> It was tricky to configure the wol feature on my Dell Laptop. NAS and Dell servers were easy to configure. Follow this article for [Dell laptop](https://www.dell.com/support/article/en-us/sln305365/how-to-setup-wake-on-lan-wol-on-your-dell-system?lang=en) | ||
## Bootstrap UI with JS Grid for editing data | ||
|
||
![Screenshot](wolweb_ui.png) | ||
|
||
### Wake-up directly using HTTP Request | ||
|
||
/wolweb/wake/**<hostname>** - Returns a JSON object | ||
|
||
```json | ||
{ | ||
"success":true, | ||
"message":"Sent magic packet to device Server with Mac 34:E6:D7:33:12:71 on Broadcast IP 192.168.1.255:9", | ||
"error":null | ||
} | ||
``` | ||
|
||
## Configure the app | ||
|
||
The application will use the following default values if they are not explicitly configured as explained in sections below. | ||
|
||
| Config | Description | Default | ||
| --- | --- | --- | | ||
| Port | Define the port on which the webserver will listen | **8089** | ||
| Virtual Directory | A virtual directory to mount this application under | **/wolweb** | ||
|
||
You can override the default application configuration by using a config file or by setting environment variables. The application will first load values from config file and look for environment variables and overwrites values from the file with the values which were found in the environment. | ||
|
||
**Using config.json:** | ||
|
||
```json | ||
{ | ||
"port": 8089, | ||
"vdir":"/wolweb" | ||
} | ||
``` | ||
**Using Environment Variables:** | ||
|
||
*Environment variables takes precedence over values in config.json file.* | ||
|
||
| Variable Name | Description | ||
| --- | --- | | ||
| WOLWEBPORT | Override for default HTTP port | ||
| WOLWEBVDIR | Override for default virtual directory | ||
|
||
## Devices (targets) - devices.json format | ||
```json | ||
{ | ||
"devices": [ | ||
{ | ||
"name": "Server", | ||
"mac": "34:E6:D7:33:12:71", | ||
"ip": "192.168.1.255:9" | ||
}, | ||
{ | ||
"name": "NAS", | ||
"mac": "28:C6:8E:36:DC:38", | ||
"ip": "192.168.1.255:9" | ||
}, | ||
{ | ||
"name": "Laptop", | ||
"mac": "18:1D:EA:70:A0:21", | ||
"ip": "192.168.1.255:9" | ||
} | ||
] | ||
} | ||
|
||
``` | ||
## Using with Docker Container | ||
|
||
This project includes [Dockerfile (based on Alpine)](./Dockerfile) and [docker-compose.yml](./docker-compose.yml) files which you can use to build the image for your platform and run it using the docker compose file. If interested, I also have alternate [Dockerfile (based on Debian)](.Debian_Dockerfile). Both of these Dockerfile are tested to run on Raspberry Pi Docker CE. If you want to use this applicaiton as-is, you will only need to download these two docker realted files to get started. The docker file will grab the code and compile it for your platform. | ||
|
||
**Build Docker Image:** | ||
|
||
``` | ||
docker build -t wolweb . | ||
``` | ||
**Run Docker Image:** | ||
|
||
``` | ||
docker-compose up -d | ||
``` | ||
**Extract the compiled application files from image:** | ||
|
||
``` | ||
docker cp wolweb:/wolweb - > wolweb.gz | ||
``` | ||
|
||
> I could not get this to run using Docker's bridged network. The only way I was able to make it work was to use host network for the docker container. See this [https://github.com/docker/for-linux/issues/637](https://github.com/docker/for-linux/issues/637) for details. | ||
## Build on Windows | ||
I use VS Code with Go extension. To build this project on windows | ||
``` | ||
go build -o wolweb.exe . | ||
``` | ||
|
||
## Build for ASUS Routers (ARM v5) | ||
I initially thought of running this application on my router, so I needed to build the application without having to install build tool on my router. I use the following **PowerShell** one liner to build targeting the ARM v5 platform on my Windows machine with VS Code: | ||
```powershell | ||
$Env:GOOS = "linux"; $Env:GOARCH = "arm"; $Env:GOARM = "5"; go build -o wolweb . | ||
``` | ||
Copy the file over to router and make it executable. | ||
```sh | ||
chmod +x wolweb | ||
``` | ||
## NGiNX Config | ||
|
||
I am already using NGiNX as web-proxy for accessing multiple services (web interfaces) from single IP and port 443 using free Let's Encrypt HTTPS certificate. For accessing this service, I just added the following configuration under my existing server node. | ||
``` | ||
location /wolweb { | ||
proxy_pass http://192.168.1.4:8089/wolweb; | ||
} | ||
``` | ||
> This is also the reason why I have an option in this application to use virtual directory **/wolweb** as I can easily map all requests for this application. My / is already occupied for other web application in my network. | ||
## Credits | ||
Thank you to David Baumann's project https://github.com/dabondi/go-rest-wol for providing the framework which I modified a little to work within constraints of environment. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"port": 8089, | ||
"vdir":"/wolweb" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"log" | ||
"net/http" | ||
"os" | ||
"strconv" | ||
) | ||
|
||
func loadData() { | ||
|
||
devicesFile, err := os.Open("devices.json") | ||
if err != nil { | ||
log.Fatalf("Error loading devices.json file. \"%s\"", err) | ||
} | ||
devicesDecoder := json.NewDecoder(devicesFile) | ||
err = devicesDecoder.Decode(&appData) | ||
if err != nil { | ||
log.Fatalf("Error decoding devices.json file. \"%s\"", err) | ||
} | ||
log.Printf("Application data loaded from devices.json") | ||
log.Println(" - devices defined in devices.json: ", len(appData.Devices)) | ||
|
||
} | ||
|
||
func saveData(w http.ResponseWriter, r *http.Request) { | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
var result HTTPResponseObject | ||
|
||
log.Printf("New Application data received for saving to disk") | ||
err := json.NewDecoder(r.Body).Decode(&appData) | ||
if err != nil { | ||
// http.Error(w, err.Error(), http.StatusBadRequest) | ||
result.Success = false | ||
result.Message = "Colud not save the data. " + err.Error() | ||
result.ErrorObject = err | ||
log.Printf(" - Issues decoding/saving application data") | ||
} else { | ||
file, _ := os.OpenFile("devices.json", os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.ModePerm) | ||
defer file.Close() | ||
|
||
encoder := json.NewEncoder(file) | ||
encoder.SetIndent("", " ") | ||
encoder.Encode(appData) | ||
|
||
result.Success = true | ||
result.Message = "devices data saved to devices.json file. There are now " + strconv.Itoa(len(appData.Devices)) + " device defined in the list." | ||
log.Printf(" - New application data saved to file devices.json") | ||
} | ||
json.NewEncoder(w).Encode(result) | ||
|
||
} | ||
|
||
func getData(w http.ResponseWriter, r *http.Request) { | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
json.NewEncoder(w).Encode(appData) | ||
log.Printf("Request for Application data served") | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"devices": [ | ||
{ | ||
"name": "Server", | ||
"mac": "34:E6:D7:33:12:71", | ||
"ip": "192.168.1.255:9" | ||
}, | ||
{ | ||
"name": "NAS", | ||
"mac": "28:C6:8E:36:DC:38", | ||
"ip": "192.168.1.255:9" | ||
}, | ||
{ | ||
"name": "Laptop", | ||
"mac": "18:1D:EA:70:A0:21", | ||
"ip": "192.168.1.255:9" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
version: "3" | ||
services: | ||
wolweb: | ||
container_name: wolweb | ||
image: "wolweb" | ||
|
||
# make sure that the file exists in local directory from where you are running the compose file | ||
# Or, initialize empty json file by running command "echo '{}' > devices.json" | ||
volumes: | ||
- ./devices.json:/wolweb/devices.json | ||
|
||
# Have to use host mode as bridge network has issues with UDP broadcast | ||
# https://github.com/docker/for-linux/issues/637 | ||
# ports: | ||
# - 12345:8089 | ||
network_mode: host | ||
|
||
# Use environment variable below to change port or virtual directory. | ||
#environment: | ||
#WOLWEBPORT: "8089" | ||
#WOLWEBVDIR: "/wolweb" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<html> | ||
|
||
<head> | ||
<title>Wake-on-lan Web</title> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"> | ||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css"> | ||
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css" /> | ||
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css" /> | ||
<link rel="stylesheet" href="static/wolweb.css"> | ||
</head> | ||
|
||
<body> | ||
<div class="container-fluid"> | ||
<div class="row"> | ||
<div class="col-12" role="main"> | ||
<h1 class="mb-4 mt-4"><span class="fas fa-power-off"></span> Wake-on-Lan Web Interface<small></h1> | ||
<div id="snackbar" class="alert hideMe"> | ||
Message comes here | ||
</div> | ||
<div id="GridDevices"></div> | ||
<hr> | ||
<p> | ||
<h3>Wake-up directly using HTTP Request</h3> | ||
<b>{{$.VDir}}/wake/<span class="text-info"><DeviceName></span></b> | ||
|
||
<b>Returns a JSON Object</b> | ||
<p> | ||
<pre> | ||
{ | ||
"success":true, | ||
"message":"Sent magic packet to device Server with Mac 34:E6:D7:33:12:71 on Broadcast IP 192.168.1.255:9", | ||
"error":null | ||
} | ||
</pre> | ||
</p> | ||
<dl class="dl-horizontal"> | ||
<dt>success</dt> | ||
<dd>True or False if the WakeOnLan Paket was send</dd> | ||
<dt>message</dt> | ||
<dd>Message as string what happen</dd> | ||
<dt>error</dt> | ||
<dd>Encoded Jsonobject from GOLANG Error Object</dd> | ||
</dl> | ||
</p> | ||
<hr> | ||
<p> | ||
<i class="fab fa-github"></i> Project Page: <a | ||
href="https://github.com/sameerdhoot/wolweb">https://github.com/sameerdhoot/wolweb</a> | ||
</p> | ||
<p class="m-0"> | ||
<small>Build with <span class="fa fa-heart text-danger" aria-hidden="true"></span> by Sameer Dhoot, <span | ||
class="fab fa-github"></span> <a href="https://github.com/dabondi">https://github.com/sameerdhoot</a></small> | ||
</p> | ||
<p class="m-0"> | ||
<small class="ml-2"><i class="fas fa-code-branch m-1"></i> from David Baumann's project <a href="https://github.com/dabondi/go-rest-wol">https://github.com/dabondi/go-rest-wol</a></small> | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<script> | ||
window.vDir = "{{$.VDir}}" | ||
</script> | ||
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script> | ||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script> | ||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js"></script> | ||
<script src="static/wolweb.js"></script> | ||
|
||
</body> | ||
|
||
</html> |
Oops, something went wrong.