Skip to content

Commit

Permalink
Add WireGuard VPN usermod (wled#3270)
Browse files Browse the repository at this point in the history
* added wireguard VPN usermod

* add example PIO override & edit readme

* add contact information and improve usermod performance
  • Loading branch information
acvigue authored Jul 27, 2023
1 parent b67235a commit 0ccadb2
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 0 deletions.
22 changes: 22 additions & 0 deletions usermods/wireguard/platformio_override.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Example PlatformIO Project Configuration Override for WireGuard
# ------------------------------------------------------------------------------
# Copy to platformio_override.ini to activate.
# ------------------------------------------------------------------------------
# Please visit documentation: https://docs.platformio.org/page/projectconf.html

[platformio]
default_envs = WLED_ESP32-WireGuard

[env:WLED_ESP32-WireGuard]
board = esp32dev
platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32}
-D WLED_RELEASE_NAME=ESP32-WireGuard
-D USERMOD_WIREGUARD
lib_deps = ${esp32.lib_deps}
https://github.com/kienvu58/WireGuard-ESP32-Arduino.git
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.default_partitions}
upload_speed = 921600
19 changes: 19 additions & 0 deletions usermods/wireguard/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# WireGuard VPN

This usermod will connect your WLED instance to a remote WireGuard subnet.

Configuration is performed via the Usermod menu. There are no parameters to set in code!

## Installation

Copy the `platformio_override.ini` file to the root project directory, review the build options, and select the `WLED_ESP32-WireGuard` environment.


## Author

Aiden Vigue [vigue.me](https://vigue.me)
[@acvigue](https://github.com/acvigue)
[email protected]



127 changes: 127 additions & 0 deletions usermods/wireguard/wireguard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#pragma once

#include <WireGuard-ESP32.h>

#include "wled.h"

class WireguardUsermod : public Usermod {
public:
void setup() { configTzTime(posix_tz, ntpServerName); }

void connected() {
if (wg.is_initialized()) {
wg.end();
}
}

void loop() {
if (millis() - lastTime > 5000) {
if (is_enabled && WLED_CONNECTED) {
if (!wg.is_initialized()) {
struct tm timeinfo;
if (getLocalTime(&timeinfo, 0)) {
if (strlen(preshared_key) < 1) {
wg.begin(local_ip, private_key, endpoint_address, public_key, endpoint_port, NULL);
} else {
wg.begin(local_ip, private_key, endpoint_address, public_key, endpoint_port, preshared_key);
}
}
}
}

lastTime = millis();
}
}

void addToJsonInfo(JsonObject& root) {
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");

JsonArray infoArr = user.createNestedArray(F("WireGuard"));
String uiDomString;

struct tm timeinfo;
if (!getLocalTime(&timeinfo, 0)) {
uiDomString = "Time out of sync!";
} else {
if (wg.is_initialized()) {
uiDomString = "netif up!";
} else {
uiDomString = "netif down :(";
}
}
if (is_enabled) infoArr.add(uiDomString);
}

void appendConfigData() {
oappend(SET_F("addInfo('WireGuard:host',1,'Server Hostname');")); // 0 is field type, 1 is actual field
oappend(SET_F("addInfo('WireGuard:port',1,'Server Port');")); // 0 is field type, 1 is actual field
oappend(SET_F("addInfo('WireGuard:ip',1,'Device IP');")); // 0 is field type, 1 is actual field
oappend(SET_F("addInfo('WireGuard:psk',1,'Pre Shared Key (optional)');")); // 0 is field type, 1 is actual field
oappend(SET_F("addInfo('WireGuard:pem',1,'Private Key');")); // 0 is field type, 1 is actual field
oappend(SET_F("addInfo('WireGuard:pub',1,'Public Key');")); // 0 is field type, 1 is actual field
oappend(SET_F("addInfo('WireGuard:tz',1,'POSIX timezone string');")); // 0 is field type, 1 is actual field
}

void addToConfig(JsonObject& root) {
JsonObject top = root.createNestedObject(F("WireGuard"));
top[F("host")] = endpoint_address;
top[F("port")] = endpoint_port;
top[F("ip")] = local_ip.toString();
top[F("psk")] = preshared_key;
top[F("pem")] = private_key;
top[F("pub")] = public_key;
top[F("tz")] = posix_tz;
}

bool readFromConfig(JsonObject& root) {
JsonObject top = root[F("WireGuard")];

if (top["host"].isNull() || top["port"].isNull() || top["ip"].isNull() || top["pem"].isNull() || top["pub"].isNull() || top["tz"].isNull()) {
is_enabled = false;
return false;
} else {
const char* host = top["host"];
strncpy(endpoint_address, host, 100);

const char* ip_s = top["ip"];
uint8_t ip[4];
sscanf(ip_s, "%u.%u.%u.%u", &ip[0], &ip[1], &ip[2], &ip[3]);
local_ip = IPAddress(ip[0], ip[1], ip[2], ip[3]);

const char* pem = top["pem"];
strncpy(private_key, pem, 45);

const char* pub = top["pub"];
strncpy(public_key, pub, 45);

const char* tz = top["tz"];
strncpy(posix_tz, tz, 150);

endpoint_port = top["port"];

if (!top["psk"].isNull()) {
const char* psk = top["psk"];
strncpy(preshared_key, psk, 45);
}

is_enabled = true;
}

return is_enabled;
}

uint16_t getId() { return USERMOD_ID_WIREGUARD; }

private:
WireGuard wg;
char preshared_key[45];
char private_key[45];
IPAddress local_ip;
char public_key[45];
char endpoint_address[100];
char posix_tz[150];
int endpoint_port = 0;
bool is_enabled = false;
unsigned long lastTime = 0;
};
1 change: 1 addition & 0 deletions wled00/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
#define USERMOD_ID_PWM_OUTPUTS 38 //Usermod "usermod_pwm_outputs.h
#define USERMOD_ID_SHT 39 //Usermod "usermod_sht.h
#define USERMOD_ID_KLIPPER 40 // Usermod Klipper percentage
#define USERMOD_ID_WIREGUARD 41 //Usermod "wireguard.h"

//Access point behavior
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
Expand Down
8 changes: 8 additions & 0 deletions wled00/usermods_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@
#include "../usermods/wizlights/wizlights.h"
#endif

#ifdef USERMOD_WIREGUARD
#include "../usermods/wireguard/wireguard.h"
#endif

#ifdef USERMOD_WORDCLOCK
#include "../usermods/usermod_v2_word_clock/usermod_v2_word_clock.h"
#endif
Expand Down Expand Up @@ -306,6 +310,10 @@ void registerUsermods()
usermods.add(new WizLightsUsermod());
#endif

#ifdef USERMOD_WIREGUARD
usermods.add(new WireguardUsermod());
#endif

#ifdef USERMOD_WORDCLOCK
usermods.add(new WordClockUsermod());
#endif
Expand Down

0 comments on commit 0ccadb2

Please sign in to comment.