Asp.Net Http server to enable wake on lan for computers behind a firewall. It also allows for port forwarding configuration.
- .NET 8 runtime
Download the zip file from the release tab.
Unzip the contents into a website. Ensure that the dotnet hosting runtime 8 is installed.
- Unzip the contents into a folder
-
dotnet Rstolsmark.WakeOnLanServer.dll
- To host on a different port specify urls:
dotnet Rstolsmark.WakeOnLanServer.dll --urls "http://*:8080;https://*:8081"
- Add
appsettings.Production.json
to the root of the site
The WakeOnLan server supports authentication using Azure AD. Follow this guide for setup:
- Create an app registration in Azure.
- Add a redirect URI of type web to the app registration. Set the following URI:
https://appurl.com/signin-oidc
. - Add a front-channel logout URL in this format:
https://appurl.com/signout-oidc
. - Add the following to
appsetings.Production.json
:
{
"AzureAD": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "your organization domain in azure",
"ClientId": "The client id of your app registration",
"TenantId": "Your Azure tenant id"
}
}
Now only users which are allowed to log on to your app in Azure will be allowed to access the application. To configure which users this are you need to find the application in the Enterprise Applications section of the Azure portal. Here you can set if users must be assigned to be allowed to sign in. (Assignment required?) You can also add users to roles for use with authorization.
It is possible to configure authorization with Azure AD. You can then limit a user's access to the WakeOnLanServer to either the WakeOnLan section or the port forwarding section.
Add the roles you want to define for authorization in the App roles tab of your app registration.
In the example configuration we have used the roles with display names: Port forwarder
and Wake on lan server
.
They will have the values portforwarder
and wakeonlanserver
respectively.
It is the values we will use when configuring role authorization in the application.
Add the following to appsettings.Production.json
:
{
"WakeOnLanRole": "wakeonlanserver"
}
Add the following to appsettings.Production.json
:
{
"PortForwarding": {
"PortForwardingRole": "portforwarder"
}
}
- Generate a salted hashed password using Rstolsmark.PasswordHashTool
-
dotnet tool install -g Rstolsmark.PasswordHashTool
-
passwordhasher yourpassword
-
- Add the following content to
appsettings.Production.json
:
{
"PasswordAuthenticationOptions":{
"Realm": "Wake on lan server",
"HashedPassword": "A hashed password generated by Rstolsmark.PasswordHashTool"
}
}
The WakeOnLanServer supports configuring port forwarding on routers. Currently the only supported backend is the Unifi controller.
- Add a local user account to the Unifi Controller with administrator permission on the Unifi Network. This will be used as a service account by the wakeonlanserver.
- Add the following to
appsettings.Production.json
:
{
"PortForwarding": {
"UnifiClientOptions": {
"BaseUrl": "https://ipOrDomainOfUnifiController",
"AllowInvalidCertificate": true,
"Credentials": {
"UserName": "username of unifi user",
"Password": "password of unifi user"
},
"DefaultInterface": "name of network that should be configured e.g.: wan",
"TimeoutSeconds": 2
},
"Backend": "Unifi"
}
}
Unifi comes with a self-signed certificate by default. Setting AllowInvalidCertificate to true will make the WakeOnLanServer accept this certificate. Otherwise the self-signed certificate will need to be installed as a trusted certificate by the machine running the WakeOnLanServer.
TimeoutSeconds gives the number of seconds before the WakeOnLanServer concludes the Unifi backend must be down.
For testing purposes a mock backend exists. Add the following to appsettings.Development.json
to enable the mock:
{
"PortForwarding": {
"Backend": "Mock"
}
}
By default the application has no logging. It supports logging to console and files.
Add the following content to appsettings.Production.json
:
{
"Serilog": {
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {RequestId} {Username} {ClientIp} {Message:lj}{NewLine}{Exception}"
}
}
]
}
}
Add the following content to appsettings.Production.json
:
{
"Serilog": {
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "logs/log.txt",
"rollingInterval": "Day",
"rollOnFileSizeLimit": true,
"fileSizeLimitBytes": 1048576,
"retainedFileCountLimit": 10,
"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {RequestId} {Username} {ClientIp} {Message:lj}{NewLine}{Exception}"
}
}
]
}
}
The example above logs to a subfolder called logs.
- The app pool / user account running the wakeonlanserver needs read / write / delete files access to this folder.
- It creates a new file per day.
- It creates a new file if the file size exceeds 1 MB.
- It retains 10 files.
Both the console and file sink supports changing the output template. See the specific sections for how to set it.
RequestId
: This is an identifier that is displayed on the error page the user is served in production when unhandled errors occured. This can then be used to find the corresponding error in the logs.Username
: This is the username of the logged on user.ClientIp
: The IP address of the client issuing a request
The wakeonlanserver supports Serilog request logging. To enable this feature add the following to appsettings.Production.json
:
{
"UseRequestLogging": true
}
If you are running the wakeonlanserver behind a reverse proxy or on IIS it is recommended to use forwarded headers to get the correct client IP.
The client IP and protocol (http or https) will then be based on the request headers X-Forwarded-For and X-Forwarded-Proto that are meant to be set by the reverse proxy.
To activate this feature add the following to appsettings.Production.json
:
{
"UseForwardedHeaders": true
}
The WakeOnLanServer supports storing configuration secrets in Azure KeyVault. The client application needs GET and LIST permissions to the secrets in the key vault.
Default Azure Credentials are supported. An example would be to set the following environment variables:
AZURE_TENANT_ID
: The tenant ID of the key vault.AZURE_CLIENT_ID
: The client ID of the application that has access to the key vault.AZURE_CLIENT_SECRET
: A client secret configured on the application
Add the following to appsettings.Production.json
to use default credentials:
{
"AzureKeyVault": {
"Credentials": "Default",
"KeyVaultName": "nameofkeyvault"
}
}
For more information see:
- https://docs.microsoft.com/en-us/dotnet/api/azure.identity.environmentcredential
- https://docs.microsoft.com/en-us/dotnet/api/overview/azure/identity-readme#defaultazurecredential
Connecting with a client certificate stored in the windows certificate store is supported.
Enable this by adding the following to appsettings.Production.json
:
{
"AzureKeyVault": {
"Credentials": "ClientCertificate",
"KeyVaultName": "nameofkeyvault",
"ClientCertificateSettings": {
"StoreLocation": "CurrentUser|LocalMachine",
"CertificateThumbprint": "Thumbprint of certificate",
"ValidOnly" : true,
"TenantId": "The tenant id of the key vault",
"ClientId": "The client id of the application with access to the key vault"
}
}
}
ValidOnly
sets whether to only accept valid certificates found in the certificate store.
For more information and how to generate a certificate see:
If you want a self-signed certificate to be valid on the server that is hosting the WakeOnLanServer you need to add it to both the local machine / current user Personal store as well as to the list of Trusted Root Certificates.
To store a secret that should be applied to a setting somewhere deep down in the configuration hierarchy,
the name of the secret needs to contain --
between each hierarchy level.
Here is an example of a name that sets the Unifi password:
PortForwarding--UnifiClientOptions--Credentials--Password
The WakeOnLanServer ships with an API. It is disabled by default.
To enable the API add the following to appsettings.Production.json
{
"EnableApi": true"
}
The API uses the same authentication and authorization scheme as the rest of the application.
The server app registration created as part of the normal Azure AD authentication setup must expose an API.
- Go to the app registration page.
- If it shows an Application ID URI, you are all set. If not you must add an application ID URI:
- Click "Add an Application ID URI".
- On the new page click "Add"
- Accept the standard URI of "api://{Your Application ID}"
To be able to obtain an access token for the API you must first register a client application (app registration). This app registration is different from the one used by the app it self. It can be considered as the "user" identifying the client calling the API.
- Create an app registration in Azure.
- Under certificates and secrets add a certificate or client secret based on how you want your client to authenticate.
If you use role-based authorization for your WakeOnLanServer you will need to add your client app registration to the roles in your server app registration. You will be able to do this in Azure just like you would a normal user.
This example illustrates how to obtain an access token and call the API using Azure AD with a client secret.
Send a POST request to https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/token
where you replace {tenantid}
with the ID of your Azure AD tenant. The content-type should be application/x-www-form-urlencoded
. The form should contain the following values:
client_id
The Application ID of your client app registrationscope
Your server's app registration application ID URI postfixed with/.default
. E. g.:api://c21f21d8-5f8a-472c-90e1-25f0453e1754/.default
client_secret
Your client secret.grant_type
client_credentials
The token you receive from Azure AD needs to be sent as a bearer token in the Authorization header with api requests to the WakeOnLanServer:
Authorization: Bearer <Token>
As an example of how to use the API from PowerShell the wakeonlan.psm1
module contains a few important functions:
The function Get-AccessToken
inside wakeonlan.psm1
gets an access token.
The functions Get-Computer
and Set-Computer
inside wakeonlan.psm1
shows how to do a GET and a PUT.
The OpenAPI specification of the WakeOnLanServer API is defined in openapi.yaml.