Wireguard component (#4256)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
Co-authored-by: Simone Rossetto <simros85@gmail.com>
Co-authored-by: Thomas Bernard <thomas0bernard@gmail.com>
This commit is contained in:
Lubos Horacek 2023-09-11 21:13:24 +02:00 committed by GitHub
parent d2648657fb
commit b107948c47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 648 additions and 1 deletions

View File

@ -232,7 +232,7 @@ jobs:
fail-fast: false
max-parallel: 2
matrix:
file: [1, 2, 3, 3.1, 4, 5, 6, 7, 8]
file: [1, 2, 3, 3.1, 4, 5, 6, 7, 8, 10]
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4

6
.gitignore vendored
View File

@ -13,6 +13,12 @@ __pycache__/
# Intellij Idea
.idea
# Eclipse
.project
.cproject
.pydevproject
.settings/
# Vim
*.swp

View File

@ -333,6 +333,7 @@ esphome/components/web_server_idf/* @dentra
esphome/components/whirlpool/* @glmnet
esphome/components/whynter/* @aeonsablaze
esphome/components/wiegand/* @ssieb
esphome/components/wireguard/* @droscy @lhoracek @thomas0bernard
esphome/components/wl_134/* @hobbypunk90
esphome/components/x9c/* @EtienneMD
esphome/components/xiaomi_lywsd03mmc/* @ahpohl

View File

@ -0,0 +1,113 @@
import re
import ipaddress
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.const import (
CONF_ID,
CONF_TIME_ID,
CONF_ADDRESS,
CONF_REBOOT_TIMEOUT,
)
from esphome.components import time
CONF_NETMASK = "netmask"
CONF_PRIVATE_KEY = "private_key"
CONF_PEER_ENDPOINT = "peer_endpoint"
CONF_PEER_PUBLIC_KEY = "peer_public_key"
CONF_PEER_PORT = "peer_port"
CONF_PEER_PRESHARED_KEY = "peer_preshared_key"
CONF_PEER_ALLOWED_IPS = "peer_allowed_ips"
CONF_PEER_PERSISTENT_KEEPALIVE = "peer_persistent_keepalive"
CONF_REQUIRE_CONNECTION_TO_PROCEED = "require_connection_to_proceed"
DEPENDENCIES = ["time", "esp32"]
CODEOWNERS = ["@lhoracek", "@droscy", "@thomas0bernard"]
# The key validation regex has been described by Jason Donenfeld himself
# url: https://lists.zx2c4.com/pipermail/wireguard/2020-December/006222.html
_WG_KEY_REGEX = re.compile(r"^[A-Za-z0-9+/]{42}[AEIMQUYcgkosw480]=$")
wireguard_ns = cg.esphome_ns.namespace("wireguard")
Wireguard = wireguard_ns.class_("Wireguard", cg.Component, cg.PollingComponent)
def _wireguard_key(value):
if _WG_KEY_REGEX.match(cv.string(value)) is not None:
return value
raise cv.Invalid(f"Invalid WireGuard key: {value}")
def _cidr_network(value):
try:
ipaddress.ip_network(value, strict=False)
except ValueError as err:
raise cv.Invalid(f"Invalid network in CIDR notation: {err}")
return value
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(Wireguard),
cv.GenerateID(CONF_TIME_ID): cv.use_id(time.RealTimeClock),
cv.Required(CONF_ADDRESS): cv.ipv4,
cv.Optional(CONF_NETMASK, default="255.255.255.255"): cv.ipv4,
cv.Required(CONF_PRIVATE_KEY): _wireguard_key,
cv.Required(CONF_PEER_ENDPOINT): cv.string,
cv.Required(CONF_PEER_PUBLIC_KEY): _wireguard_key,
cv.Optional(CONF_PEER_PORT, default=51820): cv.port,
cv.Optional(CONF_PEER_PRESHARED_KEY): _wireguard_key,
cv.Optional(CONF_PEER_ALLOWED_IPS, default=["0.0.0.0/0"]): cv.ensure_list(
_cidr_network
),
cv.Optional(CONF_PEER_PERSISTENT_KEEPALIVE, default=0): cv.Any(
cv.positive_time_period_seconds,
cv.uint16_t,
),
cv.Optional(
CONF_REBOOT_TIMEOUT, default="15min"
): cv.positive_time_period_milliseconds,
cv.Optional(CONF_REQUIRE_CONNECTION_TO_PROCEED, default=False): cv.boolean,
}
).extend(cv.polling_component_schema("10s"))
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
cg.add(var.set_address(str(config[CONF_ADDRESS])))
cg.add(var.set_netmask(str(config[CONF_NETMASK])))
cg.add(var.set_private_key(config[CONF_PRIVATE_KEY]))
cg.add(var.set_peer_endpoint(config[CONF_PEER_ENDPOINT]))
cg.add(var.set_peer_public_key(config[CONF_PEER_PUBLIC_KEY]))
cg.add(var.set_peer_port(config[CONF_PEER_PORT]))
cg.add(var.set_keepalive(config[CONF_PEER_PERSISTENT_KEEPALIVE]))
cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
if CONF_PEER_PRESHARED_KEY in config:
cg.add(var.set_preshared_key(config[CONF_PEER_PRESHARED_KEY]))
allowed_ips = list(
ipaddress.collapse_addresses(
[
ipaddress.ip_network(ip, strict=False)
for ip in config[CONF_PEER_ALLOWED_IPS]
]
)
)
for ip in allowed_ips:
cg.add(var.add_allowed_ip(str(ip.network_address), str(ip.netmask)))
cg.add(var.set_srctime(await cg.get_variable(config[CONF_TIME_ID])))
if config[CONF_REQUIRE_CONNECTION_TO_PROCEED]:
cg.add(var.disable_auto_proceed())
# This flag is added here because the esp_wireguard library statically
# set the size of its allowed_ips list at compile time using this value;
# the '+1' modifier is relative to the device's own address that will
# be automatically added to the provided list.
cg.add_build_flag(f"-DCONFIG_WIREGUARD_MAX_SRC_IPS={len(allowed_ips) + 1}")
cg.add_library("droscy/esp_wireguard", "0.3.2")
await cg.register_component(var, config)

View File

@ -0,0 +1,28 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import binary_sensor
from esphome.const import (
CONF_STATUS,
DEVICE_CLASS_CONNECTIVITY,
)
from . import Wireguard
CONF_WIREGUARD_ID = "wireguard_id"
DEPENDENCIES = ["wireguard"]
CONFIG_SCHEMA = {
cv.GenerateID(CONF_WIREGUARD_ID): cv.use_id(Wireguard),
cv.Optional(CONF_STATUS): binary_sensor.binary_sensor_schema(
device_class=DEVICE_CLASS_CONNECTIVITY,
),
}
async def to_code(config):
parent = await cg.get_variable(config[CONF_WIREGUARD_ID])
if status_config := config.get(CONF_STATUS):
sens = await binary_sensor.new_binary_sensor(status_config)
cg.add(parent.set_status_sensor(sens))

View File

@ -0,0 +1,30 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
from esphome.const import (
DEVICE_CLASS_TIMESTAMP,
ENTITY_CATEGORY_DIAGNOSTIC,
)
from . import Wireguard
CONF_WIREGUARD_ID = "wireguard_id"
CONF_LATEST_HANDSHAKE = "latest_handshake"
DEPENDENCIES = ["wireguard"]
CONFIG_SCHEMA = {
cv.GenerateID(CONF_WIREGUARD_ID): cv.use_id(Wireguard),
cv.Optional(CONF_LATEST_HANDSHAKE): sensor.sensor_schema(
device_class=DEVICE_CLASS_TIMESTAMP,
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
}
async def to_code(config):
parent = await cg.get_variable(config[CONF_WIREGUARD_ID])
if latest_handshake_config := config.get(CONF_LATEST_HANDSHAKE):
sens = await sensor.new_sensor(latest_handshake_config)
cg.add(parent.set_handshake_sensor(sens))

View File

@ -0,0 +1,296 @@
#include "wireguard.h"
#ifdef USE_ESP32
#include <ctime>
#include <functional>
#include "esphome/core/application.h"
#include "esphome/core/log.h"
#include "esphome/core/time.h"
#include "esphome/components/network/util.h"
#include <esp_err.h>
#include <esp_wireguard.h>
// includes for resume/suspend wdt
#if defined(USE_ESP_IDF)
#include <esp_task_wdt.h>
#if ESP_IDF_VERSION_MAJOR >= 5
#include <spi_flash_mmap.h>
#endif
#elif defined(USE_ARDUINO)
#include <esp32-hal.h>
#endif
namespace esphome {
namespace wireguard {
static const char *const TAG = "wireguard";
static const char *const LOGMSG_PEER_STATUS = "WireGuard remote peer is %s (latest handshake %s)";
static const char *const LOGMSG_ONLINE = "online";
static const char *const LOGMSG_OFFLINE = "offline";
void Wireguard::setup() {
ESP_LOGD(TAG, "initializing WireGuard...");
this->wg_config_.address = this->address_.c_str();
this->wg_config_.private_key = this->private_key_.c_str();
this->wg_config_.endpoint = this->peer_endpoint_.c_str();
this->wg_config_.public_key = this->peer_public_key_.c_str();
this->wg_config_.port = this->peer_port_;
this->wg_config_.netmask = this->netmask_.c_str();
this->wg_config_.persistent_keepalive = this->keepalive_;
if (this->preshared_key_.length() > 0)
this->wg_config_.preshared_key = this->preshared_key_.c_str();
this->wg_initialized_ = esp_wireguard_init(&(this->wg_config_), &(this->wg_ctx_));
if (this->wg_initialized_ == ESP_OK) {
ESP_LOGI(TAG, "WireGuard initialized");
this->wg_peer_offline_time_ = millis();
this->srctime_->add_on_time_sync_callback(std::bind(&Wireguard::start_connection_, this));
this->defer(std::bind(&Wireguard::start_connection_, this)); // defer to avoid blocking setup
} else {
ESP_LOGE(TAG, "cannot initialize WireGuard, error code %d", this->wg_initialized_);
this->mark_failed();
}
}
void Wireguard::loop() {
if ((this->wg_initialized_ == ESP_OK) && (this->wg_connected_ == ESP_OK) && (!network::is_connected())) {
ESP_LOGV(TAG, "local network connection has been lost, stopping WireGuard...");
this->stop_connection_();
}
}
void Wireguard::update() {
bool peer_up = this->is_peer_up();
time_t lhs = this->get_latest_handshake();
bool lhs_updated = (lhs > this->latest_saved_handshake_);
ESP_LOGV(TAG, "handshake: latest=%.0f, saved=%.0f, updated=%d", (double) lhs, (double) this->latest_saved_handshake_,
(int) lhs_updated);
if (lhs_updated) {
this->latest_saved_handshake_ = lhs;
}
std::string latest_handshake =
(this->latest_saved_handshake_ > 0)
? ESPTime::from_epoch_local(this->latest_saved_handshake_).strftime("%Y-%m-%d %H:%M:%S %Z")
: "timestamp not available";
if (peer_up) {
if (this->wg_peer_offline_time_ != 0) {
ESP_LOGI(TAG, LOGMSG_PEER_STATUS, LOGMSG_ONLINE, latest_handshake.c_str());
this->wg_peer_offline_time_ = 0;
} else {
ESP_LOGD(TAG, LOGMSG_PEER_STATUS, LOGMSG_ONLINE, latest_handshake.c_str());
}
} else {
if (this->wg_peer_offline_time_ == 0) {
ESP_LOGW(TAG, LOGMSG_PEER_STATUS, LOGMSG_OFFLINE, latest_handshake.c_str());
this->wg_peer_offline_time_ = millis();
} else {
ESP_LOGD(TAG, LOGMSG_PEER_STATUS, LOGMSG_OFFLINE, latest_handshake.c_str());
this->start_connection_();
}
// check reboot timeout every time the peer is down
if (this->reboot_timeout_ > 0) {
if (millis() - this->wg_peer_offline_time_ > this->reboot_timeout_) {
ESP_LOGE(TAG, "WireGuard remote peer is unreachable, rebooting...");
App.reboot();
}
}
}
#ifdef USE_BINARY_SENSOR
if (this->status_sensor_ != nullptr) {
this->status_sensor_->publish_state(peer_up);
}
#endif
#ifdef USE_SENSOR
if (this->handshake_sensor_ != nullptr && lhs_updated) {
this->handshake_sensor_->publish_state((double) this->latest_saved_handshake_);
}
#endif
}
void Wireguard::dump_config() {
ESP_LOGCONFIG(TAG, "WireGuard:");
ESP_LOGCONFIG(TAG, " Address: %s", this->address_.c_str());
ESP_LOGCONFIG(TAG, " Netmask: %s", this->netmask_.c_str());
ESP_LOGCONFIG(TAG, " Private Key: " LOG_SECRET("%s"), mask_key(this->private_key_).c_str());
ESP_LOGCONFIG(TAG, " Peer Endpoint: " LOG_SECRET("%s"), this->peer_endpoint_.c_str());
ESP_LOGCONFIG(TAG, " Peer Port: " LOG_SECRET("%d"), this->peer_port_);
ESP_LOGCONFIG(TAG, " Peer Public Key: " LOG_SECRET("%s"), this->peer_public_key_.c_str());
ESP_LOGCONFIG(TAG, " Peer Pre-shared Key: " LOG_SECRET("%s"),
(this->preshared_key_.length() > 0 ? mask_key(this->preshared_key_).c_str() : "NOT IN USE"));
ESP_LOGCONFIG(TAG, " Peer Allowed IPs:");
for (auto &allowed_ip : this->allowed_ips_) {
ESP_LOGCONFIG(TAG, " - %s/%s", std::get<0>(allowed_ip).c_str(), std::get<1>(allowed_ip).c_str());
}
ESP_LOGCONFIG(TAG, " Peer Persistent Keepalive: %d%s", this->keepalive_,
(this->keepalive_ > 0 ? "s" : " (DISABLED)"));
ESP_LOGCONFIG(TAG, " Reboot Timeout: %d%s", (this->reboot_timeout_ / 1000),
(this->reboot_timeout_ != 0 ? "s" : " (DISABLED)"));
// be careful: if proceed_allowed_ is true, require connection is false
ESP_LOGCONFIG(TAG, " Require Connection to Proceed: %s", (this->proceed_allowed_ ? "NO" : "YES"));
LOG_UPDATE_INTERVAL(this);
}
void Wireguard::on_shutdown() { this->stop_connection_(); }
bool Wireguard::can_proceed() { return (this->proceed_allowed_ || this->is_peer_up()); }
bool Wireguard::is_peer_up() const {
return (this->wg_initialized_ == ESP_OK) && (this->wg_connected_ == ESP_OK) &&
(esp_wireguardif_peer_is_up(&(this->wg_ctx_)) == ESP_OK);
}
time_t Wireguard::get_latest_handshake() const {
time_t result;
if (esp_wireguard_latest_handshake(&(this->wg_ctx_), &result) != ESP_OK) {
result = 0;
}
return result;
}
void Wireguard::set_address(const std::string &address) { this->address_ = address; }
void Wireguard::set_netmask(const std::string &netmask) { this->netmask_ = netmask; }
void Wireguard::set_private_key(const std::string &key) { this->private_key_ = key; }
void Wireguard::set_peer_endpoint(const std::string &endpoint) { this->peer_endpoint_ = endpoint; }
void Wireguard::set_peer_public_key(const std::string &key) { this->peer_public_key_ = key; }
void Wireguard::set_peer_port(const uint16_t port) { this->peer_port_ = port; }
void Wireguard::set_preshared_key(const std::string &key) { this->preshared_key_ = key; }
void Wireguard::add_allowed_ip(const std::string &ip, const std::string &netmask) {
this->allowed_ips_.emplace_back(ip, netmask);
}
void Wireguard::set_keepalive(const uint16_t seconds) { this->keepalive_ = seconds; }
void Wireguard::set_reboot_timeout(const uint32_t seconds) { this->reboot_timeout_ = seconds; }
void Wireguard::set_srctime(time::RealTimeClock *srctime) { this->srctime_ = srctime; }
#ifdef USE_BINARY_SENSOR
void Wireguard::set_status_sensor(binary_sensor::BinarySensor *sensor) { this->status_sensor_ = sensor; }
#endif
#ifdef USE_SENSOR
void Wireguard::set_handshake_sensor(sensor::Sensor *sensor) { this->handshake_sensor_ = sensor; }
#endif
void Wireguard::disable_auto_proceed() { this->proceed_allowed_ = false; }
void Wireguard::start_connection_() {
if (this->wg_initialized_ != ESP_OK) {
ESP_LOGE(TAG, "cannot start WireGuard, initialization in error with code %d", this->wg_initialized_);
return;
}
if (!network::is_connected()) {
ESP_LOGD(TAG, "WireGuard is waiting for local network connection to be available");
return;
}
if (!this->srctime_->now().is_valid()) {
ESP_LOGD(TAG, "WireGuard is waiting for system time to be synchronized");
return;
}
if (this->wg_connected_ == ESP_OK) {
ESP_LOGV(TAG, "WireGuard connection already started");
return;
}
ESP_LOGD(TAG, "starting WireGuard connection...");
/*
* The function esp_wireguard_connect() contains a DNS resolution
* that could trigger the watchdog, so before it we suspend (or
* increase the time, it depends on the platform) the wdt and
* then we resume the normal timeout.
*/
suspend_wdt();
ESP_LOGV(TAG, "executing esp_wireguard_connect");
this->wg_connected_ = esp_wireguard_connect(&(this->wg_ctx_));
resume_wdt();
if (this->wg_connected_ == ESP_OK) {
ESP_LOGI(TAG, "WireGuard connection started");
} else {
ESP_LOGW(TAG, "cannot start WireGuard connection, error code %d", this->wg_connected_);
return;
}
ESP_LOGD(TAG, "configuring WireGuard allowed IPs list...");
bool allowed_ips_ok = true;
for (std::tuple<std::string, std::string> ip : this->allowed_ips_) {
allowed_ips_ok &=
(esp_wireguard_add_allowed_ip(&(this->wg_ctx_), std::get<0>(ip).c_str(), std::get<1>(ip).c_str()) == ESP_OK);
}
if (allowed_ips_ok) {
ESP_LOGD(TAG, "allowed IPs list configured correctly");
} else {
ESP_LOGE(TAG, "cannot configure WireGuard allowed IPs list, aborting...");
this->stop_connection_();
this->mark_failed();
}
}
void Wireguard::stop_connection_() {
if (this->wg_initialized_ == ESP_OK && this->wg_connected_ == ESP_OK) {
ESP_LOGD(TAG, "stopping WireGuard connection...");
esp_wireguard_disconnect(&(this->wg_ctx_));
this->wg_connected_ = ESP_FAIL;
}
}
void suspend_wdt() {
#if defined(USE_ESP_IDF)
#if ESP_IDF_VERSION_MAJOR >= 5
ESP_LOGV(TAG, "temporarily increasing wdt timeout to 15000 ms");
esp_task_wdt_config_t wdtc;
wdtc.timeout_ms = 15000;
wdtc.idle_core_mask = 0;
wdtc.trigger_panic = false;
esp_task_wdt_reconfigure(&wdtc);
#else
ESP_LOGV(TAG, "temporarily increasing wdt timeout to 15 seconds");
esp_task_wdt_init(15, false);
#endif
#elif defined(USE_ARDUINO)
ESP_LOGV(TAG, "temporarily disabling the wdt");
disableLoopWDT();
#endif
}
void resume_wdt() {
#if defined(USE_ESP_IDF)
#if ESP_IDF_VERSION_MAJOR >= 5
wdtc.timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000;
esp_task_wdt_reconfigure(&wdtc);
ESP_LOGV(TAG, "wdt resumed with %d ms timeout", wdtc.timeout_ms);
#else
esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, false);
ESP_LOGV(TAG, "wdt resumed with %d seconds timeout", CONFIG_ESP_TASK_WDT_TIMEOUT_S);
#endif
#elif defined(USE_ARDUINO)
enableLoopWDT();
ESP_LOGV(TAG, "wdt resumed");
#endif
}
std::string mask_key(const std::string &key) { return (key.substr(0, 5) + "[...]="); }
} // namespace wireguard
} // namespace esphome
#endif // USE_ESP32

View File

@ -0,0 +1,122 @@
#pragma once
#ifdef USE_ESP32
#include <ctime>
#include <vector>
#include <tuple>
#include "esphome/core/component.h"
#include "esphome/components/time/real_time_clock.h"
#ifdef USE_BINARY_SENSOR
#include "esphome/components/binary_sensor/binary_sensor.h"
#endif
#ifdef USE_SENSOR
#include "esphome/components/sensor/sensor.h"
#endif
#include <esp_wireguard.h>
namespace esphome {
namespace wireguard {
class Wireguard : public PollingComponent {
public:
void setup() override;
void loop() override;
void update() override;
void dump_config() override;
void on_shutdown() override;
bool can_proceed() override;
float get_setup_priority() const override { return esphome::setup_priority::BEFORE_CONNECTION; }
void set_address(const std::string &address);
void set_netmask(const std::string &netmask);
void set_private_key(const std::string &key);
void set_peer_endpoint(const std::string &endpoint);
void set_peer_public_key(const std::string &key);
void set_peer_port(uint16_t port);
void set_preshared_key(const std::string &key);
void add_allowed_ip(const std::string &ip, const std::string &netmask);
void set_keepalive(uint16_t seconds);
void set_reboot_timeout(uint32_t seconds);
void set_srctime(time::RealTimeClock *srctime);
#ifdef USE_BINARY_SENSOR
void set_status_sensor(binary_sensor::BinarySensor *sensor);
#endif
#ifdef USE_SENSOR
void set_handshake_sensor(sensor::Sensor *sensor);
#endif
/// Block the setup step until peer is connected.
void disable_auto_proceed();
bool is_peer_up() const;
time_t get_latest_handshake() const;
protected:
std::string address_;
std::string netmask_;
std::string private_key_;
std::string peer_endpoint_;
std::string peer_public_key_;
std::string preshared_key_;
std::vector<std::tuple<std::string, std::string>> allowed_ips_;
uint16_t peer_port_;
uint16_t keepalive_;
uint32_t reboot_timeout_;
time::RealTimeClock *srctime_;
#ifdef USE_BINARY_SENSOR
binary_sensor::BinarySensor *status_sensor_ = nullptr;
#endif
#ifdef USE_SENSOR
sensor::Sensor *handshake_sensor_ = nullptr;
#endif
/// Set to false to block the setup step until peer is connected.
bool proceed_allowed_ = true;
wireguard_config_t wg_config_ = ESP_WIREGUARD_CONFIG_DEFAULT();
wireguard_ctx_t wg_ctx_ = ESP_WIREGUARD_CONTEXT_DEFAULT();
esp_err_t wg_initialized_ = ESP_FAIL;
esp_err_t wg_connected_ = ESP_FAIL;
/// The last time the remote peer become offline.
uint32_t wg_peer_offline_time_ = 0;
/** \brief The latest saved handshake.
*
* This is used to save (and log) the latest completed handshake even
* after a full refresh of the wireguard keys (for example after a
* stop/start connection cycle).
*/
time_t latest_saved_handshake_ = 0;
void start_connection_();
void stop_connection_();
};
// These are used for possibly long DNS resolution to temporarily suspend the watchdog
void suspend_wdt();
void resume_wdt();
/// Strip most part of the key only for secure printing
std::string mask_key(const std::string &key);
} // namespace wireguard
} // namespace esphome
#endif // USE_ESP32

View File

@ -123,6 +123,7 @@ lib_deps =
DNSServer ; captive_portal (Arduino built-in)
esphome/ESP32-audioI2S@2.0.7 ; i2s_audio
crankyoldgit/IRremoteESP8266@2.7.12 ; heatpumpir
droscy/esp_wireguard@0.3.2 ; wireguard
build_flags =
${common:arduino.build_flags}
-DUSE_ESP32
@ -141,6 +142,7 @@ framework = espidf
lib_deps =
${common:idf.lib_deps}
espressif/esp32-camera@1.0.0 ; esp32_camera
droscy/esp_wireguard@0.3.2 ; wireguard
build_flags =
${common:idf.build_flags}
-Wno-nonnull-compare

View File

@ -27,3 +27,4 @@ Current test_.yaml file contents.
| test6.yaml | RP2040 | wifi | N/A
| test7.yaml | ESP32-C3 | wifi | N/A
| test8.yaml | ESP32-S3 | wifi | None
| test10.yaml | ESP32 | wifi | None

48
tests/test10.yaml Normal file
View File

@ -0,0 +1,48 @@
---
esphome:
name: test10
build_path: build/test10
esp32:
board: esp32doit-devkit-v1
framework:
type: arduino
wifi:
ssid: "MySSID1"
password: "password1"
reboot_timeout: 3min
power_save_mode: high
logger:
level: VERBOSE
api:
reboot_timeout: 10min
time:
- platform: sntp
wireguard:
id: vpn
address: 172.16.34.100
netmask: 255.255.255.0
# NEVER use the following keys for your vpn, they are now public!
private_key: wPBMxtNYH3mChicrbpsRpZIasIdPq3yZuthn23FbGG8=
peer_public_key: Hs2JfikvYU03/Kv3YoAs1hrUIPPTEkpsZKSPUljE9yc=
peer_preshared_key: 20fjM5GRnSolGPC5SRj9ljgIUyQfruv0B0bvLl3Yt60=
peer_endpoint: wg.server.example
peer_persistent_keepalive: 25s
peer_allowed_ips:
- 172.16.34.0/24
- 192.168.4.0/24
binary_sensor:
- platform: wireguard
status:
name: 'WireGuard Status'
sensor:
- platform: wireguard
latest_handshake:
name: 'WireGuard Latest Handshake'