Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WireGuard VPN usermod #3270

Merged
merged 4 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
11 changes: 11 additions & 0 deletions usermods/wireguard/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 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.


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

#include <WireGuard-ESP32.h>

#include "wled.h"

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

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

void loop() {
struct tm timeinfo;
if (!is_enabled || !getLocalTime(&timeinfo, 0)) {
return;
}

if (wg.is_initialized() || !WLED_CONNECTED) {
return;
}

if (preshared_key.length() < 5) {
wg.begin(local_ip, private_key.c_str(), endpoint_address.c_str(), public_key.c_str(), endpoint_port, NULL);
acvigue marked this conversation as resolved.
Show resolved Hide resolved
} else {
wg.begin(local_ip, private_key.c_str(), endpoint_address.c_str(), public_key.c_str(), endpoint_port, preshared_key.c_str());
}
}

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

JsonArray infoArr = user.createNestedArray(F("WireGuard VPN"));
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 addToConfig(JsonObject& root) {
JsonObject top = root.createNestedObject(F("WireGuard VPN"));
top[F("Endpoint Address")] = endpoint_address;
acvigue marked this conversation as resolved.
Show resolved Hide resolved
top[F("Endpoint Port")] = endpoint_port;
top[F("Local IP")] = local_ip_buf;
top[F("PSK")] = preshared_key;
top[F("Private Key")] = private_key;
top[F("Public Key")] = public_key;
top[F("POSIX Timezone")] = posix_tz;
}

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

bool configComplete = !top.isNull();

configComplete &= getJsonValue(top[F("Endpoint Address")], endpoint_address);
configComplete &= getJsonValue(top[F("Endpoint Port")], endpoint_port);
configComplete &= getJsonValue(top[F("Local IP")], local_ip_buf);
configComplete &= getJsonValue(top[F("Private Key")], private_key);
configComplete &= getJsonValue(top[F("Public Key")], public_key);
configComplete &= getJsonValue(top[F("POSIX Timezone")], posix_tz);
getJsonValue(top[F("PSK")], preshared_key);

local_ip.fromString(local_ip_buf);

is_enabled = configComplete;

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

return configComplete;
}

uint16_t getId() { return USERMOD_ID_WIREGUARD; }

private:
WireGuard wg;
String preshared_key; // [Interface] PrivateKey
acvigue marked this conversation as resolved.
Show resolved Hide resolved
String private_key; // [Interface] PrivateKey
String local_ip_buf;
IPAddress local_ip;
String public_key; // [Peer] PublicKey
String endpoint_address; // [Peer] Endpoint
String posix_tz;
int endpoint_port = 0; // [Peer] Endpoint
bool is_enabled = false;
};
1 change: 1 addition & 0 deletions wled00/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,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