13#include <esp_wireguard.h>
14#include <esp_wireguard_err.h>
18static const char *
const TAG =
"wireguard";
24#define LOGMSG_PEER_STATUS "Remote peer is %s (latest handshake %s)"
26static const char *
const LOGMSG_ONLINE =
"online";
27static const char *
const LOGMSG_OFFLINE =
"offline";
49 ESP_LOGI(TAG,
"Initialized");
60 ESP_LOGE(TAG,
"Cannot initialize: error code %d", this->
wg_initialized_);
71 ESP_LOGV(TAG,
"Local network connection has been lost, stopping");
81 ESP_LOGV(TAG,
"enabled=%d, connected=%d, peer_up=%d, handshake: current=%.0f latest=%.0f updated=%d",
86 this->latest_saved_handshake_ = lhs;
89 std::string latest_handshake =
90 (this->latest_saved_handshake_ > 0)
92 :
"timestamp not available";
96 ESP_LOGI(TAG, LOGMSG_PEER_STATUS, LOGMSG_ONLINE, latest_handshake.c_str());
99 ESP_LOGD(TAG, LOGMSG_PEER_STATUS, LOGMSG_ONLINE, latest_handshake.c_str());
103 ESP_LOGW(TAG, LOGMSG_PEER_STATUS, LOGMSG_OFFLINE, latest_handshake.c_str());
105 }
else if (this->enabled_) {
106 ESP_LOGD(TAG, LOGMSG_PEER_STATUS, LOGMSG_OFFLINE, latest_handshake.c_str());
113 ESP_LOGE(TAG,
"Remote peer is unreachable; rebooting");
119#ifdef USE_BINARY_SENSOR
133 char private_key_masked[MASK_KEY_BUFFER_SIZE];
134 char preshared_key_masked[MASK_KEY_BUFFER_SIZE];
143 " Private Key: " LOG_SECRET(
"%s")
"\n"
144 " Peer Endpoint: " LOG_SECRET(
"%s")
"\n"
145 " Peer Port: " LOG_SECRET(
"%d")
"\n"
146 " Peer Public Key: " LOG_SECRET(
"%s")
"\n"
147 " Peer Pre-shared Key: " LOG_SECRET(
"%s"),
150 (this->
preshared_key_ !=
nullptr ? preshared_key_masked :
"NOT IN USE"));
152 ESP_LOGCONFIG(TAG,
" Peer Allowed IPs:");
154 ESP_LOGCONFIG(TAG,
" - %s/%s", allowed_ip.ip, allowed_ip.netmask);
156 ESP_LOGCONFIG(TAG,
" Peer Persistent Keepalive: %d%s", this->
keepalive_,
157 (this->
keepalive_ > 0 ?
"s" :
" (DISABLED)"));
158 ESP_LOGCONFIG(TAG,
" Reboot Timeout: %" PRIu32
"%s", (this->
reboot_timeout_ / 1000),
161 ESP_LOGCONFIG(TAG,
" Require Connection to Proceed: %s", (this->
proceed_allowed_ ?
"NO" :
"YES"));
162 LOG_UPDATE_INTERVAL(
this);
171 (esp_wireguardif_peer_is_up(&(this->
wg_ctx_)) == ESP_OK);
176 if (esp_wireguard_latest_handshake(&(this->
wg_ctx_), &result) != ESP_OK) {
186#ifdef USE_BINARY_SENSOR
195#ifdef USE_TEXT_SENSOR
203 ESP_LOGI(TAG,
"Enabled");
210 ESP_LOGI(TAG,
"Disabled");
215#ifdef USE_BINARY_SENSOR
226 ESP_LOGV(TAG,
"Disabled, cannot start connection");
236 ESP_LOGD(TAG,
"Waiting for local network connection to be available");
241 ESP_LOGD(TAG,
"Waiting for system time to be synchronized");
246 ESP_LOGV(TAG,
"Connection already started");
250 ESP_LOGD(TAG,
"Starting connection");
257 ESP_LOGI(TAG,
"Connection started");
259 ESP_LOGD(TAG,
"Waiting for endpoint IP address to be available");
262 ESP_LOGW(TAG,
"Cannot start connection, error code %d", this->
wg_connected_);
266 ESP_LOGD(TAG,
"Configuring allowed IPs list");
267 bool allowed_ips_ok =
true;
269 allowed_ips_ok &= (esp_wireguard_add_allowed_ip(&(this->
wg_ctx_), ip.ip, ip.netmask) == ESP_OK);
272 if (allowed_ips_ok) {
273 ESP_LOGD(TAG,
"Allowed IPs list configured correctly");
275 ESP_LOGE(TAG,
"Cannot configure allowed IPs list, aborting");
283 ESP_LOGD(TAG,
"Stopping connection");
286 esp_wireguard_disconnect(&(this->
wg_ctx_));
294 if (
len < MASK_KEY_BUFFER_SIZE || key ==
nullptr) {
301 for (; i < 5 && key[i] !=
'\0'; ++i) {
305 const char *suffix =
"[...]=";
306 for (
size_t j = 0; suffix[j] !=
'\0' && (i + j) <
len - 1; ++j) {
307 buffer[i + j] = suffix[j];
309 buffer[i + 6] =
'\0';
virtual void mark_failed()
Mark this component as failed.
ESPDEPRECATED("Use const char* overload instead. Removed in 2026.7.0", "2026.1.0") void defer(const std voi defer)(const char *name, std::function< void()> &&f)
Defer a callback to the next loop() call.
Helper class to lock the lwIP TCPIP core when making lwIP API calls from non-TCPIP threads.
Base class for all binary_sensor-type classes.
void publish_state(bool new_state)
Publish a new state to the front-end.
Base-class for all sensors.
void publish_state(float state)
Publish a new state to the front-end.
void publish_state(const std::string &state)
The RealTimeClock class exposes common timekeeping functions via the device's local real-time clock.
void add_on_time_sync_callback(std::function< void()> &&callback)
ESPTime now()
Get the time in the currently defined timezone.
binary_sensor::BinarySensor * enabled_sensor_
FixedVector< AllowedIP > allowed_ips_
void set_keepalive(uint16_t seconds)
bool enabled_
When false the wireguard link will not be established.
binary_sensor::BinarySensor * status_sensor_
void set_status_sensor(binary_sensor::BinarySensor *sensor)
void set_srctime(time::RealTimeClock *srctime)
void publish_enabled_state()
Publish the enabled state if the enabled binary sensor is configured.
time_t get_latest_handshake() const
void on_shutdown() override
sensor::Sensor * handshake_sensor_
time::RealTimeClock * srctime_
bool proceed_allowed_
Set to false to block the setup step until peer is connected.
void dump_config() override
const char * private_key_
void set_reboot_timeout(uint32_t seconds)
void disable_auto_proceed()
Block the setup step until peer is connected.
bool can_proceed() override
void set_address_sensor(text_sensor::TextSensor *sensor)
text_sensor::TextSensor * address_sensor_
uint32_t wg_peer_offline_time_
The last time the remote peer become offline.
void disable()
Stop any running connection and disable the WireGuard component.
void set_enabled_sensor(binary_sensor::BinarySensor *sensor)
void set_handshake_sensor(sensor::Sensor *sensor)
esp_err_t wg_initialized_
bool is_enabled()
Return if the WireGuard component is or is not enabled.
const char * peer_public_key_
void enable()
Enable the WireGuard component.
const char * preshared_key_
const char * peer_endpoint_
time_t latest_saved_handshake_
The latest saved handshake.
wireguard_config_t wg_config_
bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
void mask_key_to(char *buffer, size_t len, const char *key)
Strip most part of the key only for secure printing.
uint32_t IRAM_ATTR HOT millis()
Application App
Global storage of Application pointer - only one Application can exist.
static ESPTime from_epoch_local(time_t epoch)
Convert an UTC epoch timestamp to a local time ESPTime instance.
size_t strftime(char *buffer, size_t buffer_len, const char *format)
Convert this ESPTime struct to a null-terminated c string buffer as specified by the format argument.
bool is_valid() const
Check if this ESPTime is valid (all fields in range and year is greater than 2018)
Allowed IP entry for WireGuard peer configuration.