From faaf5d513fb03b6171d0d61aa76247ad40d884db Mon Sep 17 00:00:00 2001 From: Simone Rossetto Date: Fri, 28 Apr 2023 19:18:39 +0200 Subject: [PATCH 1/5] Set default allowed ip/mask to device own address ip/mask Previously the default allowed ip and mask were set to 'any host'. --- src/esp_wireguard.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/esp_wireguard.c b/src/esp_wireguard.c index f92f74a..2335c92 100644 --- a/src/esp_wireguard.c +++ b/src/esp_wireguard.c @@ -98,12 +98,19 @@ static esp_err_t esp_wireguard_peer_init(const wireguard_config_t *config, struc } peer->keep_alive = config->persistent_keepalive; - /* Allow all IPs through tunnel */ + /* Allow source address/netmask through tunnel */ { - ip_addr_t allowed_ip = IPADDR4_INIT_BYTES(0, 0, 0, 0); - peer->allowed_ip = allowed_ip; - ip_addr_t allowed_mask = IPADDR4_INIT_BYTES(0, 0, 0, 0); - peer->allowed_mask = allowed_mask; + if(ipaddr_aton(config->allowed_ip, &(peer->allowed_ip)) != 1) { + ESP_LOGE(TAG, "peer_init: invalid allowed_ip: `%s`", config->allowed_ip); + err = ESP_ERR_INVALID_ARG; + goto fail; + } + + if(ipaddr_aton(config->allowed_ip_mask, &(peer->allowed_mask)) != 1) { + ESP_LOGE(TAG, "peer_init: invalid allowed_ip_mask: `%s`", config->allowed_ip_mask); + err = ESP_ERR_INVALID_ARG; + goto fail; + } } /* resolve peer name or IP address */ @@ -166,15 +173,15 @@ static esp_err_t esp_wireguard_netif_create(const wireguard_config_t *config) wg.listen_port = config->listen_port; wg.bind_netif = NULL; - ESP_LOGI(TAG, "allowed_ip: %s", config->allowed_ip); + //ESP_LOGI(TAG, "allowed_ip: %s", config->allowed_ip); if (ipaddr_aton(config->allowed_ip, &ip_addr) != 1) { - ESP_LOGE(TAG, "ipaddr_aton: invalid allowed_ip: `%s`", config->allowed_ip); + ESP_LOGE(TAG, "netif_create: invalid allowed_ip: `%s`", config->allowed_ip); err = ESP_ERR_INVALID_ARG; goto fail; } if (ipaddr_aton(config->allowed_ip_mask, &netmask) != 1) { - ESP_LOGE(TAG, "ipaddr_aton: invalid allowed_ip_mask: `%s`", config->allowed_ip_mask); + ESP_LOGE(TAG, "netif_create: invalid allowed_ip_mask: `%s`", config->allowed_ip_mask); err = ESP_ERR_INVALID_ARG; goto fail; } From 2b063c0ac74560a60585df436623350bea294cbd Mon Sep 17 00:00:00 2001 From: Simone Rossetto Date: Wed, 17 May 2023 07:14:26 +0200 Subject: [PATCH 2/5] Add lower level function to add ip/mask to the allowed list --- library.json | 2 +- src/wireguardif.c | 14 ++++++++++++++ src/wireguardif.h | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/library.json b/library.json index 215907c..f776e34 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "esp_wireguard", - "version": "0.1.0", + "version": "0.2.0-aip1", "description": "WireGuard implementation for ESPHome", "keywords":[ "communication", diff --git a/src/wireguardif.c b/src/wireguardif.c index 2ddc678..30b04f6 100644 --- a/src/wireguardif.c +++ b/src/wireguardif.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2021 Daniel Hope (www.floorsense.nz) * Copyright (c) 2021 Kenta Ida (fuga@fugafuga.org) + * Copyright (c) 2023 Simone Rossetto * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -731,6 +732,19 @@ time_t wireguardif_latest_handshake(struct netif *netif, u8_t peer_index) { return result; } +err_t wireguardif_add_allowed_ip(struct netif *netif, u8_t peer_index, ip_addr_t ip, ip_addr_t mask) { + struct wireguard_peer *peer; + err_t result = wireguardif_lookup_peer(netif, peer_index, &peer); + if (result == ERR_OK) { + if(peer_add_ip(peer, ip, mask)) { + result = ERR_OK; + } else { + result = ERR_MEM; + } + } + return result; +} + err_t wireguardif_remove_peer(struct netif *netif, u8_t peer_index) { struct wireguard_peer *peer; err_t result = wireguardif_lookup_peer(netif, peer_index, &peer); diff --git a/src/wireguardif.h b/src/wireguardif.h index 1f8284e..b011863 100644 --- a/src/wireguardif.h +++ b/src/wireguardif.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Daniel Hope (www.floorsense.nz) + * Copyright (c) 2023 Simone Rossetto * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -139,6 +140,9 @@ err_t wireguardif_peer_is_up(struct netif *netif, u8_t peer_index, ip_addr_t *cu // Return 0 if no handshake already done or in case of errors time_t wireguardif_latest_handshake(struct netif *netif, u8_t peer_index); +// Add ip/mask to the list of allowed ips of the given peer +err_t wireguardif_add_allowed_ip(struct netif *netif, u8_t peer_index, ip_addr_t ip, ip_addr_t mask); + #ifdef __cplusplus } #endif From dbb079572bcb07ec825f80f8112fbb8a2aa11f8d Mon Sep 17 00:00:00 2001 From: Simone Rossetto Date: Wed, 17 May 2023 20:03:06 +0200 Subject: [PATCH 3/5] Add higher level function to add ip/mask to the allowed list --- include/esp_wireguard.h | 14 +++++++++++++ library.json | 2 +- src/esp_wireguard.c | 46 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/include/esp_wireguard.h b/include/esp_wireguard.h index baeee96..e27123a 100644 --- a/include/esp_wireguard.h +++ b/include/esp_wireguard.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2022 Tomoyuki Sakurai + * Copyright (c) 2023 Simone Rossetto * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -145,6 +146,19 @@ esp_err_t esp_wireguardif_peer_is_up(const wireguard_ctx_t *ctx); */ esp_err_t esp_wireguard_latest_handshake(const wireguard_ctx_t *ctx, time_t *result); +/** + * @brief Add new allowed IP/mask to the list of allowed ip/mask + * @param ctx Context of WireGuard + * @param allowed_ip The new IP to be allowed through tunnel + * @param allowed_ip_mask The mask of the new IP + * @return + * - ESP_OK on success + * - ESP_FAIL if the adding failed + * - ESP_ERR_INVALID_ARG if ctx, allowed_ip or allowed_ip_mask are invalid or empty + * - ESP_ERR_INVALID_STATE if data inside ctx is not valid + */ +esp_err_t esp_wireguard_add_allowed_ip(const wireguard_ctx_t *ctx, const char *allowed_ip, const char *allowed_ip_mask); + /** * @brief Disconnect from the peer * diff --git a/library.json b/library.json index f776e34..de6e106 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "esp_wireguard", - "version": "0.2.0-aip1", + "version": "0.2.0-aip2", "description": "WireGuard implementation for ESPHome", "keywords":[ "communication", diff --git a/src/esp_wireguard.c b/src/esp_wireguard.c index 2335c92..2ac347f 100644 --- a/src/esp_wireguard.c +++ b/src/esp_wireguard.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2022 Tomoyuki Sakurai + * Copyright (c) 2023 Simone Rossetto * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -49,6 +50,7 @@ #define TAG "esp_wireguard" #define WG_KEY_LEN (32) #define WG_B64_KEY_LEN (4 * ((WG_KEY_LEN + 2) / 3)) + #if defined(CONFIG_LWIP_IPV6) #define WG_ADDRSTRLEN INET6_ADDRSTRLEN #else @@ -98,7 +100,7 @@ static esp_err_t esp_wireguard_peer_init(const wireguard_config_t *config, struc } peer->keep_alive = config->persistent_keepalive; - /* Allow source address/netmask through tunnel */ + /* Allow device address/netmask through tunnel */ { if(ipaddr_aton(config->allowed_ip, &(peer->allowed_ip)) != 1) { ESP_LOGE(TAG, "peer_init: invalid allowed_ip: `%s`", config->allowed_ip); @@ -173,8 +175,6 @@ static esp_err_t esp_wireguard_netif_create(const wireguard_config_t *config) wg.listen_port = config->listen_port; wg.bind_netif = NULL; - //ESP_LOGI(TAG, "allowed_ip: %s", config->allowed_ip); - if (ipaddr_aton(config->allowed_ip, &ip_addr) != 1) { ESP_LOGE(TAG, "netif_create: invalid allowed_ip: `%s`", config->allowed_ip); err = ESP_ERR_INVALID_ARG; @@ -186,6 +186,8 @@ static esp_err_t esp_wireguard_netif_create(const wireguard_config_t *config) goto fail; } + ESP_LOGI(TAG, "default allowed_ip: %s/%s", config->allowed_ip, config->allowed_ip_mask); + /* Register the new WireGuard network interface with lwIP */ wg_netif = netif_add( &wg_netif_struct, @@ -367,6 +369,44 @@ esp_err_t esp_wireguard_latest_handshake(const wireguard_ctx_t *ctx, time_t *res *result = wireguardif_latest_handshake(ctx->netif, wireguard_peer_index); err = (*result > 0) ? ESP_OK : ESP_FAIL; +fail: + return err; +} + +esp_err_t esp_wireguard_add_allowed_ip(const wireguard_ctx_t *ctx, const char *allowed_ip, const char *allowed_ip_mask) +{ + esp_err_t err; + err_t lwip_err; + + ip_addr_t ip_addr; + ip_addr_t netmask; + + if (!ctx || !allowed_ip || !allowed_ip_mask) { + err = ESP_ERR_INVALID_ARG; + goto fail; + } + + if (!ctx->netif) { + err = ESP_ERR_INVALID_STATE; + goto fail; + } + + if (ipaddr_aton(allowed_ip, &ip_addr) != 1) { + ESP_LOGE(TAG, "add_allowed_ip: invalid allowed_ip: `%s`", allowed_ip); + err = ESP_ERR_INVALID_ARG; + goto fail; + } + + if (ipaddr_aton(allowed_ip_mask, &netmask) != 1) { + ESP_LOGE(TAG, "add_allowed_ip: invalid allowed_ip_mask: `%s`", allowed_ip_mask); + err = ESP_ERR_INVALID_ARG; + goto fail; + } + + ESP_LOGI(TAG, "add allowed_ip: %s/%s", allowed_ip, allowed_ip_mask); + lwip_err = wireguardif_add_allowed_ip(ctx->netif, wireguard_peer_index, ip_addr, netmask); + err = (lwip_err == ERR_OK ? ESP_OK : ESP_FAIL); + fail: return err; } From 774464f8272f845b010f907e8001c4c7dfe0ea1e Mon Sep 17 00:00:00 2001 From: Simone Rossetto Date: Fri, 19 May 2023 21:07:23 +0200 Subject: [PATCH 4/5] Set default config defines inside code to allow external override The CONFIG_* build flags can now be set directly in ESPHome components. --- library.json | 9 ++------- src/wireguard-platform.h | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/library.json b/library.json index de6e106..b905234 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "esp_wireguard", - "version": "0.2.0-aip2", + "version": "0.2.0-aip3b", "description": "WireGuard implementation for ESPHome", "keywords":[ "communication", @@ -57,11 +57,6 @@ }, "build":{ "includeDir": "include", - "srcDir": "src", - "flags": [ - "-DCONFIG_WIREGUARD_MAX_PEERS=1", - "-DCONFIG_WIREGUARD_MAX_SRC_IPS=1", - "-DCONFIG_MAX_INITIATIONS_PER_SECOND=2" - ] + "srcDir": "src" } } diff --git a/src/wireguard-platform.h b/src/wireguard-platform.h index 5c0a13b..5a9341d 100644 --- a/src/wireguard-platform.h +++ b/src/wireguard-platform.h @@ -44,11 +44,24 @@ extern "C" { #include "esp_err.h" // Peers are allocated statically inside the device structure to avoid malloc -#define WIREGUARD_MAX_PEERS (CONFIG_WIREGUARD_MAX_PEERS) -#define WIREGUARD_MAX_SRC_IPS (CONFIG_WIREGUARD_MAX_SRC_IPS) +#ifdef CONFIG_WIREGUARD_MAX_PEERS + #define WIREGUARD_MAX_PEERS (CONFIG_WIREGUARD_MAX_PEERS) +#else + #define WIREGUARD_MAX_PEERS (1) +#endif + +#ifdef CONFIG_WIREGUARD_MAX_SRC_IPS + #define WIREGUARD_MAX_SRC_IPS (CONFIG_WIREGUARD_MAX_SRC_IPS) +#else + #define WIREGUARD_MAX_SRC_IPS (1) +#endif // Per device limit on accepting (valid) initiation requests - per peer -#define MAX_INITIATIONS_PER_SECOND (CONFIG_MAX_INITIATIONS_PER_SECOND) +#ifdef CONFIG_WIREGUARD_MAX_INIT_PER_SECOND + #define MAX_INITIATIONS_PER_SECOND (CONFIG_WIREGUARD_MAX_INIT_PER_SECOND) +#else + #define MAX_INITIATIONS_PER_SECOND (2) +#endif // Initialize crypto backend (return ESP_OK on success) esp_err_t wireguard_platform_init(); From e70aebfda9da7f5c3773b322c57e281efb9ab4a7 Mon Sep 17 00:00:00 2001 From: Simone Rossetto Date: Sat, 20 May 2023 08:27:12 +0200 Subject: [PATCH 5/5] Update readme and library for version 0.2.0 --- README.md | 17 +++++++++++++---- library.json | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cb3c0e4..1db51b9 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ for `esp-idf` only but it seems to work on `Arduino` too. ## Usage -Add the following configuration to your `yaml` file: +Add the following configuration to your ESPHome `yaml` file: ```yaml # Define wireguard external source @@ -55,9 +55,9 @@ time: # Setup WireGuard wireguard: address: x.y.z.w - private_key: !secret wg_privkey + private_key: private_key= peer_endpoint: wg.server.example - peer_public_key: !secret wg_peer_pubkey + peer_public_key: public_key= # optional netmask (this is the default if omitted) netmask: 255.255.255.255 @@ -66,10 +66,19 @@ wireguard: peer_port: 51820 # optional pre-shared key - peer_preshared_key: !secret wg_peer_shrdkey + peer_preshared_key: shared_key= # optional keepalive in seconds (disabled by default) peer_persistent_keepalive: 25 + + # optional list of allowed ip/mask (the default is to allow any host if omitted) + peer_allowed_ips: + - x.y.z.0/24 + - l.m.n.o/32 # the /32 can be omitted for single host + - [...] + + # reboot the board if remote peer in unreachable (default to 15min, set to 0s to disable) + reboot_timeout: 15min ``` ### Sensors diff --git a/library.json b/library.json index b905234..8a50684 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "esp_wireguard", - "version": "0.2.0-aip3b", + "version": "0.2.0", "description": "WireGuard implementation for ESPHome", "keywords":[ "communication",