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

WireGuard Support for ESP32 #1444

Closed
davey opened this issue Oct 1, 2021 · 131 comments
Closed

WireGuard Support for ESP32 #1444

davey opened this issue Oct 1, 2021 · 131 comments

Comments

@davey
Copy link

davey commented Oct 1, 2021

Describe the problem you have/What new integration you would like

Please help me adding support for WireGuard to ESPHome on ESP32 boards.
WireGuard is an extremely simple yet fast and modern VP.

There already seems to be an Arduino library in Platformio for the ESP32.

Please describe your use case for this integration and alternatives you've tried:

I need to have a bidirectional, secure channel between multiple ESPHome/ESP32s at multiple locations and some remote backend server.
From these backend servers I want to be able to push e.g. OTA updates centrally to many different NATed locations (where a site2site VPN is not an option).
Also I'd like to reach all those different locations from one central HomeAssistant instance.
On the ESP side, only traffic to a specific remote subnet (the backend) needs be routed through Wireguard, all remaining network traffic should use the default gateway.

AFAIK there are no VPN alternatives available for ESPhome yet.

Additional context

Basically this is all about being able to directly reach (on IP level) multiple ESPHome boards at different locations/networks behind their NAT routers from some central place / VPN server / backend.

@davey
Copy link
Author

davey commented Oct 1, 2021

I've already tried to add the library by putting this in my ESPHome yaml config:
platformio_options: { lib_deps: "ciniml/WireGuard-ESP32" }
but I got this error:

Processing my_test (board: esp32dev; framework: arduino; platform: platformio/espressif32@3.2.0)
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
PACKAGES:
 - framework-arduinoespressif32 3.10006.210326 (1.0.6)
 - tool-esptoolpy 1.30000.201119 (3.0.0)
 - toolchain-xtensa32 2.50200.97 (5.2.0)
Dependency Graph
|-- <WireGuard-ESP32> 0.1.2
[......]
Compiling .pioenvs/my_test/libc96/WireGuard-ESP32/crypto/cortex/cortex_m0_mpy121666.s.o
xtensa-esp32-elf-as: unrecognized option '-x'
Compiling .pioenvs/my_test/libc96/WireGuard-ESP32/crypto/cortex/cortex_m0_reduce25519.s.o
xtensa-esp32-elf-as: unrecognized option '-x'
Compiling .pioenvs/my_test/libc96/WireGuard-ESP32/crypto/cortex/mul.s.o
xtensa-esp32-elf-as: unrecognized option '-x'
*** [.pioenvs/my_test/libc96/WireGuard-ESP32/crypto/cortex/cortex_m0_mpy121666.s.o] Error 1
*** [.pioenvs/my_test/libc96/WireGuard-ESP32/crypto/cortex/cortex_m0_reduce25519.s.o] Error 1
*** [.pioenvs/my_test/libc96/WireGuard-ESP32/crypto/cortex/mul.s.o] Error 1
Compiling .pioenvs/my_test/libc96/WireGuard-ESP32/crypto/cortex/scalarmult.c.o
================================================ [FAILED] Took 7.92 seconds ================================================

Any help / hint is much appreciated!

This was referenced Oct 1, 2021
@mrkeuz
Copy link

mrkeuz commented Oct 1, 2021

@davey Very cool solution. It is potentially will add ability to communicate with ESPHome from anywhere. Really impressive. I like idea, maybe it is even good alternative over MQTT.

I know one of embedded developer. Will try to consult with him. Also, will try to google problem to help you.

@mrkeuz
Copy link

mrkeuz commented Oct 2, 2021

Faced with same issue. I've even created fresh project to test. Same result. It tries to execute xtensa-esp32-elf-as -x assembler-with-cpp -mlongcalls ... assembler tool chain (in contrast GNU Assembler) to compile *.s files, but exactly xtensa-esp32-elf-as has not the options -x, -mlongcalls. (if I understand things correctly)

Here my test project and config:
https://github.com/mrkeuz/wg-esp32-test
Just in case, for prepare config (just with ESPHome is little hard to pass some parameters to pio config)

What I found and tried, options:

Summary: It is necessary to understand, how configure PlatformIO assembler tool chain for compile right in way.

Hope it helps somehow.

platformio.ini:

...
; Removes paramaters from ASFLAGS
build_unflags =
   -Wa,-x
   -Wa,assembler-with-cpp
   -Wa,-mlongcalls
...

Error from assembler after remove unsupported flags:

...
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_mpy121666.S:14: Error: unknown pseudo-op: `.cpu'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_mpy121666.S:15: Error: unknown pseudo-op: `.fpu'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_mpy121666.S:16: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_mpy121666.S:17: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_mpy121666.S:18: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_mpy121666.S:19: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_mpy121666.S:20: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_mpy121666.S:21: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_mpy121666.S:22: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_mpy121666.S:23: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_mpy121666.S:24: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_mpy121666.S:25: Error: unknown pseudo-op: `.code'
cortex_m0_reduce25519.S:33: Error: unknown pseudo-op: `.code'
cortex_m0_reduce25519.S:34: Error: unknown pseudo-op: `.thumb_func'
cortex_m0_reduce25519.S:38: Error: unknown opcode or format name 'push'
cortex_m0_reduce25519.S:39: Error: unknown opcode or format name 'ldr'
cortex_m0_reduce25519.S:40: Error: extra comma
cortex_m0_reduce25519.S:40: Error: syntax error
cortex_m0_reduce25519.S:41: Error: extra comma
cortex_m0_reduce25519.S:41: Error: syntax error
cortex_m0_reduce25519.S:42: Error: extra comma
cortex_m0_reduce25519.S:42: Error: syntax error
cortex_m0_reduce25519.S:43: Error: extra comma
cortex_m0_reduce25519.S:43: Error: syntax error
cortex_m0_reduce25519.S:44: Error: unknown opcode or format name 'uxth'
cortex_m0_reduce25519.S:45: Error: unknown opcode or format name 'mul'
cortex_m0_reduce25519.S:46: Error: unknown opcode or format name 'mul'
cortex_m0_reduce25519.S:47: Error: bad register name: r5
cortex_m0_reduce25519.S:47: Error: junk at end of line, first unrecognized character is `r'
cortex_m0_reduce25519.S:47: Internal error!
Assertion failure in ignore_rest_of_line at /builds/idf/crosstool-NG/.build/src/binutils-2.25.1/gas/read.c line 3694.
Please report this bug.
*** [.pio/build/esp-wrover-kit/libca3/WireGuard-ESP32/crypto/cortex/cortex_m0_mpy121666.S.o] Error 1
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S: Assembler messages:
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S:11: Error: unknown pseudo-op: `.cpu'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S:12: Error: unknown pseudo-op: `.fpu'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S:13: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S:14: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S:15: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S:16: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S:17: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S:18: Error: unknown pseudo-op: `.eabi_attribute'
-ardui.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S:19: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S:20: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S:21: Error: unknown pseudo-op: `.eabi_attribute'
.pio/libdeps/esp-wrover-kit/WireGuard-ESP32/src/crypto/cortex/cortex_m0_reduce25519.S:22: Error: unknown pseudo-op: `.code'
ncortex_m0_reduce25519.S:30: Error: unknown pseudo-op: `.code'
oespressif32/tools/sdk/include/coap -I/cortex_m0_reduce25519.S:31: Error: unknown pseudo-op: `.thumb_func'
home/petr/.platformio/cortex_m0_reduce25519.S:35: Error: unknown opcode or format name 'push'
cortex_m0_reduce25519.S:36: Error: extra comma
cortex_m0_reduce25519.S:36: Error: syntax error
cortex_m0_reduce25519.S:37: Error: extra comma
cortex_m0_reduce25519.S:37: Error: syntax error
cortex_m0_reduce25519.S:38: Error: unknown opcode or format name 'uxth'
cortex_m0_reduce25519.S:39: Error: extra comma
cortex_m0_reduce25519.S:39: Error: syntax error
cortex_m0_reduce25519.S:40: Error: unknown opcode or format name 'mul'
cortex_m0_reduce25519.S:41: Error: unknown opcode or format name 'mul'
cortex_m0_reduce25519.S:42: Error: extra comma
cortex_m0_reduce25519.S:42: Error: syntax error
cortex_m0_reduce25519.S:43: Error: extra comma
cortex_m0_reduce25519.S:43: Error: syntax error
cortex_m0_reduce25519.S:44: Error: extra comma
cortex_m0_reduce25519.S:44: Error: syntax error
cortex_m0_reduce25519.S:45: Error: extra comma
cortex_m0_reduce25519.S:45: Error: syntax error
cortex_m0_reduce25519.S:46: Error: bad register name: r4
cortex_m0_reduce25519.S:46: Error: junk at end of line, first unrecognized character is `r'
cortex_m0_reduce25519.S:46: Internal error!
Assertion failure in ignore_rest_of_line at /builds/idf/crosstool-NG/.build/src/binutils-2.25.1/gas/read.c line 3694.
Please report this bug.
...

@mrkeuz
Copy link

mrkeuz commented Oct 3, 2021

Solved. By exclude files in src/crypto/cortex from build.

In the end reveals that src/crypto/cortex is some platform-specific implementation of cryptography and even not used (call of asm implementation crypto_scalarmult_curve25519 is commented):

So it can safety exclude from build. One thing, I don't find easy way to exclude some lib files from build via platformio.ini flags, it can achieve little tricky via python script (extra_scipts = ... flag). But I decided just fork project and fix library.

So you can use lib_deps like

lib_deps = https://github.com/mrkeuz/WireGuard-ESP32-Arduino#a788ab8

Or fork you own repo (just delete src/crypto/cortex folder). It compiles successfully. But I don't tested exactly wg in on real hardware.

@jarno83
Copy link

jarno83 commented Oct 25, 2021

Hi, will it be added to esphome code? I want to connect esphome sensors from external network to home assistant api. Thanks

EDIT: I added libs_deps: lib_deps = https://github.com/mrkeuz/WireGuard-ESP32-Arduino#a788ab8 to platformio.ini of my esp32 project and it got compiled with some warnings. https://pastebin.com/fPbddrfq

If I flash it how and what commands can I configure it on project yaml? Thanks

@davey
Copy link
Author

davey commented Nov 10, 2021

I finally got a basic example setup working and would like to share that. 🚀

Thanks a lot for all those who contributed to this - this is great!

This is the content of my ESPhome config yaml (wireguard-test.yaml):

esphome:
  name: "wireguard-test"
  platform: esp32
  board: esp32dev
  arduino_version: latest
  platformio_options:
    lib_deps: "ciniml/WireGuard-ESP32"
  libraries: "WireGuard-ESP32"
  includes:
    - wireguard-test.wg.h

wifi:
  networks:
    - { ssid: "wifi-ssid-1", password: "xxxxxxxxxxxx" }
    - { ssid: "wifi-ssid-2", password: "yyyyyyyyyyyyy" }
  ap: { ssid: "wgtest-SETUP", password: "secretsetup" }

ota:
logger: { level: DEBUG, baud_rate: 115200}
web_server: { port: 80 }
time:
 - { platform: sntp, id: "sntp_time", timezone: "Europe/Berlin" }

custom_component:
- lambda: |-
    auto wireguard_component = new WireguardComponent();
    return {wireguard_component};

This is the content of my Wireguard config (wireguard-test.wg.h), which is mentioned in the file above:

#include "esphome.h"
#include "WireGuard-ESP32.h"

static WireGuard wg;

class WireguardComponent : public Component {
 public:

  // make sure we are starting LATE, after WIFI is initialized
  float get_setup_priority() const override { return esphome::setup_priority::LATE; }

  void setup() override {
    ESP_LOGD("custom", "wireguard setup: start ...");

    char private_key[] = "XXXXXXXXXXXXXXX="; // private key of the client (ESP)
    char public_key[]  = "YYYYYYYYYYYYYYYY="; // public key of the server (remote linux VPN server)
    IPAddress local_ip(192,168,99,123);           // VPN IP for this VPN client
    char endpoint_address[] = "vpn.example.com"; // VPN/Wireguard server hostname
    int endpoint_port = 51820;                   // VPN/Wireguard server port

    ESP_LOGD("custom", "wireguard setup: delay(5000) ...");
    delay( 5000 );
    ESP_LOGD("custom", "wireguard setup: begin ...");
    wg.begin(
        local_ip,
        private_key,
        endpoint_address,
        public_key,
        endpoint_port
    );
    ESP_LOGD("custom", "wireguard setup: end ...");
  }

  void loop() override {
    delay( 1000 );
    ESP_LOGD("custom", "wireguard loop ...");
  }
};

This is all that is needed on the ESP / EPShome side.

For completeness of this example, this is the essential part on the VPN/Wireguard server side (/etc/wireguard/wg0.conf on an Ubuntu server):

[Interface]
Address = 192.168.99.1/32
PrivateKey = PPPPPPPPPPPPPPPPPPP
ListenPort = 51820

## wireguard-test
[Peer]
PublicKey = VVVVVVVVVVVVVVVVVV
AllowedIPs = 192.168.99.123/32

I am sure there a a lot things that still need to be improved, e.g. properly waiting for the Wifi being established, making sure we reconnect in case the connection is lost and so on - I just wanted to share the earliest success to everyone waiting for it :-)

Next steps in my opinion would be to make the config more dynamic, e.g. being able to change the settings (server host, port, public and private keys and so on) or even generate a private key on the ESP itself, only showing/providing it's publickey part somewhere...

@CarlosGS
Copy link

Thanks for the great work! You can also make it run upon time sync, which simplifies things:

wireguard-test.yaml

esphome:
  name: wireguard-test
  platform: ESP32
  board: esp32dev
  libraries: ciniml/WireGuard-ESP32
  includes: wg-settings.h

wifi:
  networks:
    - { ssid: "wifi-ssid-1", password: "xxxxxxxxxxxx" }
  ap: { ssid: "wgtest-SETUP", password: "secretsetup" }

ota:
logger: { level: DEBUG, baud_rate: 115200}
web_server: { port: 80 }
time:
  - platform: sntp
    on_time_sync:
        then:
        - logger.log: "Starting wireguard..."
        - lambda: |
            wg.begin(local_ip,private_key,endpoint_address,public_key,endpoint_port);

wg-settings.h

#include <WireGuard-ESP32.h>
static WireGuard wg;

char private_key[] = "XXXXXXXXXXXXXXX="; // private key of the client (ESP)
char public_key[]  = "YYYYYYYYYYYYYYYY="; // public key of the server (remote linux VPN server)
IPAddress local_ip(192,168,99,123);           // VPN IP for this VPN client
char endpoint_address[] = "vpn.example.com"; // VPN/Wireguard server hostname
int endpoint_port = 51820;                   // VPN/Wireguard server port

The web server works, it's pretty amazing to have Wireguard running finally thanks a lot :D

However, I haven't been able to connect via OTA nor ESPHome API (adding api:). We must be missing some internal configuration.
Maybe we need to find a way to set up wireguard before api & ota. Almost there!

@CarlosGS
Copy link

CarlosGS commented Nov 21, 2021

OK, got it to work with Home Assistant & OTA! 😄

We were missing an IP route from the Home Assistant network to the Wireguard network (i.e. packets sent from HASS to the ESPHome node IP were being forwarded to the router, which dropped them). So neither HASS nor OTA could reach the nodes.
I've arranged these instructions to make it work:

  1. Set up the official Wireguard addon with the standard configuration, verify you can connect to HASS from your phone on data.
  2. Add the following to your Home Assistant's configuration.yaml. It creates a "command" sensor to periodically fetch the Wireguard addon's internal IP, and also configure the correct IP route.
sensor:
  - platform: command_line
    name: Wireguard addon internal IP # Creates the IP route to support ESPHome devices on Wireguard
    command: host_result=$(host a0d7b954-wireguard); addon_ip=${host_result##* }; ip route replace 172.27.66.0/24 via $addon_ip; echo $addon_ip
  1. Restart HASS, the new text sensor will take a couple minutes to settle into an IP like 172.30.33.2.
  2. Then note: To add the ESPHome nodes to Home Assistant you need to do it manually by going to Config->Integrations->Add->ESPHome and typing the node's specific wireguard IP. Make sure that you have the api: line in the yaml for each node. And for the ESPHome dashboard, remember to enable status_use_ping so the nodes are properly detected.

A bit tacky but at least we know it can work! Thanks @davey, @mrkeuz and @ciniml for making this possible! 🎉
Finally we can properly have remote ESPHome nodes :D

@mrkeuz
Copy link

mrkeuz commented Nov 23, 2021

@CarlosGS fantastic news!

I'm curious, did you try test connections exactly from ESPHome. I.e. try to connect to MQTT inside wg LAN. Seems wg in this case should start before MQTT component, right? And in general, will it be working at all. Just curious, how it works in core.

Honestly, exposed API via wg is already BIG DEAL and this really cool!
Hopefully sooner or later this will land to mainstream.

@CarlosGS, @davey 🚀🚀🚀

@CarlosGS
Copy link

Haven't tried MQTT yet, but it should work. Setup order shouldn't really matter as the Wireguard implementation overrides the default routing interface.

Hopefully sooner or later this will land to mainstream.

Indeed! And ESP8266 is also based on lwip - do you think it could be possible to port it, or does it depend on internal cipher functions of ESP32?

@mrkeuz
Copy link

mrkeuz commented Nov 23, 2021

ESP8266 is also based on lwip - do you think it could be possible to port it

Actually, I'm not "core" c/cpp developer. Just touching home automation a bit. And didn't dive into libraries/compatibility so deeply yet, especially with lwip.

I think it needs just try. The missing functions can be added and replaced via some #DEFINE magic. All the more wg uses modern ciphers and I don't think there will be any hardware restrictions or limitations in this area. Also, as described in original implementation, ciphers implemented in pure c, so don't think that here will be some problems. Just will be working little slowly.

Ah. Finally, found next discussion (see last comment). Seem it already worked on ESP8266. So just here a question how easily can be integrated into esphome.

@CarlosGS
Copy link

CarlosGS commented Dec 7, 2021

The other item that wasn't working "out of the box" was the API logger. Connecting with the remote logger would make the ESP32 fall into some sort of loop and stop responding.
Found a solution after some debugging: we simply need to remove/comment the ESP_LOG statements from the wireguard code, it seems they clash with ESPHome's internal logger. Doing that, everything works just fine 🎉

Also, for a complete official component we should consider enabling Wireguard in "OTA safe mode", this way remote nodes would be accessible even in the event of a reboot loop :)

🤔 It would be great if someone could get ESPHome+Wireguard running on ESP8266, that would really shape an official method to have remote ESPHome nodes. Any news or testing, make sure to post here!

@mrkeuz
Copy link

mrkeuz commented Dec 16, 2021

Just FYI.

Found easy instruction how link home-assistant container to WireGuard (without route magic):

https://www.pedrolamas.com/2020/11/20/how-to-connect-to-a-wireguard-vpn-server-from-a-docker-container/

Maybe it might be useful for somebody.

@vsurkov
Copy link

vsurkov commented Dec 22, 2021

Hello everyone, first of all, thanks a lot for your work, it's awesome!
I have an addition to the solution from @CarlosGS . Details are in this issue (ciniml/WireGuard-ESP32-Arduino#13). The correct configuration should be like this to avoid reboots every ~10 min:

time:
  - platform: sntp
    on_time_sync:
        then:
        - lambda: |
            static const char* TAG = "wireguard";
            ESP_LOGD(TAG, "Starting...");
            if( !wg.is_initialized() ) {
                        ESP_LOGD(TAG, "Initializing WG interface...");
                        if( !wg.begin(
                                local_ip,
                                private_key,
                                endpoint_address,
                                public_key,
                                endpoint_port) ) {
                            ESP_LOGD(TAG, "Failed to initialize WG interface.");
                        }
                    }

I hope this information will be useful and save someone a few nights of debugging :)

@trombik
Copy link

trombik commented Jan 6, 2022

Seem it already worked on ESP8266.

i did confirm that esp8266 works fine with the original implementation.

https://github.com/trombik/esp_wireguard

@shirou93
Copy link

This feature will be added to esphome?

@jarno83
Copy link

jarno83 commented Mar 1, 2022

Seem it already worked on ESP8266.

i did confirm that esp8266 works fine with the original implementation.

https://github.com/trombik/esp_wireguard

Hi, I tried to build that with platformIO but I get error, How did you do it?

Thanks.

.pio/libdeps/woodenbrick/esp_wireguard/src/crypto.c: In function 'crypto_equal': .pio/libdeps/woodenbrick/esp_wireguard/src/crypto.c:18:5: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith] a += 1; ^ .pio/libdeps/woodenbrick/esp_wireguard/src/crypto.c:19:5: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith] b += 1; ^ Compiling .pio/build/woodenbrick/libaf1/esp_wireguard/crypto/cortex/cortex_m0_mpy121666.s.o xtensa-lx106-elf-as: unrecognized option -x'
*** [.pio/build/woodenbrick/libaf1/esp_wireguard/crypto/cortex/cortex_m0_mpy121666.s.o] Error 1`

@trombik
Copy link

trombik commented Mar 1, 2022

as I don't use platformio, I don't know.

@fkoteam
Copy link

fkoteam commented Mar 14, 2022

@CarlosGS thank you (gracias!). I'm very close to make work oracle cloud+home assistant+wireguard+esphome. Only have and issue (the last?). I've made your magic with the command sensor. With those line wireguard works, but home assistant loses internet connection. any idea?
EDIT: I think I get it:
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf

@CarlosGS
Copy link

CarlosGS commented Mar 14, 2022 via email

@fkoteam
Copy link

fkoteam commented Mar 15, 2022

Hmm, do you mean your Home assistant is running in an external server? Mine runs in LAN, sorry, I'm not sure what would be needed to make it work like that 🤔

yes, it's working on an oracle cloud+wireguard (i think it's great). I'd to enable ip forward to make it work (see my previous post).
I'd issues also to install all together with motioneye (+ esp32cam). I think I will have to change cidr address on command sensor:
command: host_result=$(host a0d7b954-wireguard); addon_ip=${host_result##* }; ip route replace 172.27.66.0/12 via $addon_ip; echo $addon_ip

thank you!

@jarno83
Copy link

jarno83 commented Mar 15, 2022

Hi, can anyone make a little guide in one document, how novice users like me can get wiregurd working with esp32? Thanks :) I think it can help more people that me ;)

@fkoteam
Copy link

fkoteam commented Mar 16, 2022

Hi, can anyone make a little guide in one document, how novice users like me can get wiregurd working with esp32? Thanks :) I think it can help more people that me ;)

A quick and ugly guide. enjoy
EDIT: see this comment

@redstorm1
Copy link

Hi, can anyone make a little guide in one document, how novice users like me can get wiregurd working with esp32? Thanks :) I think it can help more people that me ;)

A quick and ugly guide. enjoy hass.docx

PSA this attachment is a virus.

@ssieb
Copy link
Member

ssieb commented Jun 13, 2022

Why do you think it's a virus? It's a document describing how to setup wireguard on an esphome device.

@droscy
Copy link

droscy commented Jun 27, 2023

I have a problem with the new feature - disabling WiFi. After enabling it, the VPN doesn't reconnect (?) and there is no connection to the server.

Hi @snechiporenko, I'm aware of that inconvenient behaviour, the same will happen if the device looses wifi connection and then reconnect, but currently I don't know how to fix it, probably it is something related to lower levels of network stack. That is why I introduced the reboot_timeout parameter: after a couple of minutes from a connection drop wireguard "understand" that the remote peer is offline and so the reboot_timeout countdown starts

A possible workaround could be to hook the wifi connection drop in order to refresh the wireguard interface but I didn't find a way to hook such event...

@droscy
Copy link

droscy commented Jun 28, 2023

Please @snechiporenko see comment on droscy/esphome#11

@droscy
Copy link

droscy commented Jul 2, 2023

Code updated, these are the changes:

  • restart wireguard link after local network connection loss
  • upgrade esp_wireguard to version 0.3.2
    • fix wrong latest handshake retrieval
    • add support for eth interface if wifi not available (thanks to @jpeletier)

@y1ann1s
Copy link

y1ann1s commented Jul 4, 2023

Hey there love it,
I setup everything on the local wifi , Wireguard connects successfully and works
When I move the esp in a different Wi-Fi of another network to connect over internet (NAT included)
I keep getting peer offline
I tested the same client configuration with my pc on the remote network and connects fine

I can't understand where the issue might be. Any help welcome

Thanks

@droscy
Copy link

droscy commented Jul 5, 2023

Hello @y1ann1s, could you please provide your configuration and logs of the esp when it is connected to the remote wifi?

@snechiporenko
Copy link

Hello.

When will the release be scheduled?

I have one more suggestion. If the device changes its point of connection (it can be either within a home network or outside), depending on its location, it should determine whether to use a VPN or not.

wifi:
  networks:
  - ssid: FirstNetworkToConnectTo
    password: VerySafePassword
  - ssid: SecondNetworkToConnectTo
    password: VerySafePassword

I use a VPN for a wearable device, like a watch :-)

@nagyrobi nagyrobi added this to the Top Requested milestone Jul 5, 2023
@jpeletier
Copy link

I have one more suggestion. If the device changes its point of connection (it can be either within a home network or outside), depending on its location, it should determine whether to use a VPN or not.

I would leave this logic to triggers/actions/scripts rather than a built in feature.

@y1ann1s
Copy link

y1ann1s commented Jul 5, 2023

@droscy ignore it, my bad F@#$ up firewall, working perfect now
Just a tip added
domain: .lan
in esphome and a static hostname in my router pointing to the wireguerd ip
So everything including building esphome and ota is working seamlessly

@BluetriX
Copy link

Thank you very much for this great extension!

I added a node locally with a configured wireguard block. Then I put the node to a remote location. I tried adding the remote ip (172.27.66.3) to ESPHome but it said "already exists". Everything works fine and it is connected.

The only thing wich does not work ist the online/offline state and viewing logs. It searches for "wireguard-watermeter.local" and cannot resolv the IP:
"WARNING Can't connect to ESPHome API for wireguard-watermeter.local: Error resolving IP address: [Errno -5] No address associated with hostname"

Is there any option to fix this? Or did I do something wrong?

Greetings :-)

@droscy
Copy link

droscy commented Jul 18, 2023

The addresses .local will not work for remote devices (unless you overwrite your custom DNS server o you add an entry to hosts file). However, if I understand correctly your problem, you can set the option use_address of the WiFi component to the wireguard IP of your remote device.

@BluetriX
Copy link

BluetriX commented Jul 18, 2023

@droscy Thank you very much! The use_address works for my case. I was missing that variable and thought is has to do with manual IP. This helps a lot! Now I can view the logs remotly.

@remcom
Copy link

remcom commented Aug 19, 2023

A quick question. I'm trying to establish a connection but i receive the following message:

WireGuard remote peer is offline (latest handshake timestamp not available)

The vpn server is operational because my phone can connect without issues. I use the following configuration:

wireguard:
  id: vpn
  address: 192.168.4.5
  peer_port: xxxxx
  private_key: xxxxx
  peer_public_key: xxxxx
  peer_endpoint: w.x.y.z (i'm using ip no hostname)
  peer_allowed_ips:
    - 192.168.4.1/32
    - 192.168.4.5/32
    - 0.0.0.0/0

Does someone have an idea what the issue could be?

@RoganDawes
Copy link

This worked perfectly, thank you! One tiny suggestion, to add the peer_port to the example, as it was not immediately obvious how to configure it, and I used the WireGuard method of host:port at first. Yes, I should have read the docs and I would have seen the option, but having in front and center in the example is that tiny bit less friction.

@droscy
Copy link

droscy commented Aug 20, 2023

I use the following configuration:

wireguard:
  peer_endpoint: w.x.y.z (i'm using ip no hostname)

Does someone have an idea what the issue could be?

I @remcom, I think I've never tested with an IP as endpoint so that could be the issue (and, in that case, also a bug). But currently I cannot do any test. Could you test with a hostname? Or, could anyone else here test with IP? I'll test myself as soon as I can.

  peer_allowed_ips:
   - 192.168.4.1/32
   - 192.168.4.5/32
   - 0.0.0.0/0

The entry 192.168.4.5/32 is unneeded because device's own IP is added by default among allowed IPs.
And the last entry 0.0.0.0/0 will overwrite all the others because it is "wider", unless you need to route the whole traffic thorugh the vpn link remove it.

@remcom
Copy link

remcom commented Aug 20, 2023

@droscy I tried this morning with a hostname and had the same results. Does "handshake timestamp not available" mean something specific? Or is it just a message that the vpn server isn't available?

@droscy
Copy link

droscy commented Aug 20, 2023

Could you please enable debug logs and post here the output for wireguard component?

Does "handshake timestamp not available" mean something specific? Or is it just a message that the vpn server isn't available?

It simply means that no handshake has ever succeded, otherwise it reports the timestamp of the latest handshake.

@remcom
Copy link

remcom commented Aug 20, 2023

It loops the following data:

21:12:56 | [V] | [wireguard:078] | handshake: latest=0, saved=0, updated=0
21:12:56 | [D] | [wireguard:101] | WireGuard remote peer is offline (latest handshake timestamp not available)
21:12:56 | [V] | [wireguard:211] | WireGuard connection already started
21:13:06 | [V] | [wireguard:078] | handshake: latest=0, saved=0, updated=0
21:13:06 | [D] | [wireguard:101] | WireGuard remote peer is offline (latest handshake timestamp not available)
21:13:06 | [V] | [wireguard:211] | WireGuard connection already started

@droscy
Copy link

droscy commented Aug 20, 2023

Please, post every log related to wireguard, not only the last repeated lines. I need to track any step from config lines till the loop. Thanks

@remcom
Copy link

remcom commented Aug 20, 2023

There is not a lot more:

21:26:50 | [V] | [wireguard:290] | wdt resumed
21:26:50 | [I] | [wireguard:229] | WireGuard connection started
21:26:50 | [D] | [wireguard:235] | configuring WireGuard allowed IPs list...
21:26:50 | [D] | [wireguard:243] | allowed IPs list configured correctly
21:26:53 | [V] | [wireguard:078] | handshake: latest=0, saved=0, updated=0
21:26:53 | [D] | [wireguard:101] | WireGuard remote peer is offline (latest handshake timestamp not available)
21:26:53 | [V] | [wireguard:211] | WireGuard connection already started
21:26:53 | [V] | [wireguard:211] | WireGuard connection already started
21:27:03 | [V] | [wireguard:078] | handshake: latest=0, saved=0, updated=0
21:27:03 | [D] | [wireguard:101] | WireGuard remote peer is offline (latest handshake timestamp not available)
21:27:03 | [V] | [wireguard:211] | WireGuard connection already started
21:27:13 | [V] | [wireguard:078] | handshake: latest=0, saved=0, updated=0
21:27:13 | [D] | [wireguard:101] | WireGuard remote peer is offline (latest handshake timestamp not available)
21:27:13 | [V] | [wireguard:211] | WireGuard connection already started

@droscy
Copy link

droscy commented Aug 21, 2023

You omitted many lines (including config log lines), I need them all in order to help you. If you don't want to paste everything here send them directly to me, just hide endpoint IP and port (keys are already partly masked).

I suspect misconfiguration or firewall issue.

  • public key of your remote peer is correct?
  • have you set on the remote peer the right public key for esp device?

@remcom
Copy link

remcom commented Aug 21, 2023

@droscy I found the issue. A restart of the dreammachine resolved the issue. So it probably was router/vpn-server related. Thnx for your time and making this integration possible

@victorclaessen
Copy link

victorclaessen commented Sep 11, 2023

Hi,

Thanks for the great work, this looks like a very very promising feature for remote i/o.

I'm trying to get this up and running, and thanks to your hard work it was very easy up to this point.

The API does not seem to be accepting connections on the wireguard IP. And, also, the node does not connect to my MQTT server.

I've followed the configuration from the latest comment #1444 (comment).

The esp is connected to a remote wifi network, and I have homeassistant (hassio) on a local network with the wireguard addon.

Things I know:

  • The esp boots, connects to remote wifi;
  • on the remote wifi network, I can access the esphome web port
  • I can see that the esphome sensors and logs indicate that wireguard is connected;
  • from within the the wireguard addon docker installation:
    • I can ping the wireguard remote ip address;
    • nmap shows that ports 80 and 3232 are open on the esp, but 6053 is closed;
    • I can connect to the esp port 80, and get the local web server;
    • I can use mosquitto_sub to connect succesfully to my MQTT server
  • esphome cannot open a connection to the API for the logs;
  • [EDIT, added]: esphome can succesfully OTA flash the device over the wireguard connection
  • home assistant cannot open a connection to the API to use the sensors
  • MQTT won't connect;
18:33:40	[VV	][esp-idf:000]	E (217264) TRANSPORT_BASE: Failed to open a new connection: 32774
18:33:40	[VV	][esp-idf:000]	E (217268) MQTT_CLIENT: Error transport connect
18:33:40	[V]	[mqtt.idf:109]	Event dispatched from event loop event_id=0
18:33:40	[E]	[mqtt.idf:150]	MQTT_EVENT_ERROR
18:33:40	[E]	[mqtt.idf:152]	Last error code reported from esp-tls: 0x8006
18:33:40	[E]	[mqtt.idf:153]	Last tls stack error number: 0x0
18:33:40	[E]	[mqtt.idf:155]	Last captured errno : 0 (Success)
18:33:40	[V]	[mqtt.idf:109]	Event dispatched from event loop event_id=2
18:33:40	[V]	[mqtt.idf:121]	MQTT_EVENT_DISCONNECTED
18:33:40	[W]	[mqtt:338]	MQTT Disconnected: TCP disconnected.
18:33:40	[I]	[mqtt:249]	Connecting to MQTT...

So there are two things I don't understand:

  1. Why is esphome not listening on port 6053? Does that work for everybody else? Relevant section of the config (to show that the port is not changed):
api:
  reboot_timeout: 0s
  1. Why can't esphome connect to the MQTT server, while it is definitely reachable from the wireguard-addon-docker?

[EDIT]:

  • for clarity I added that I can successfully OTA flash over wireguard
  • I just read the note in the docs that said to try setting the use_address parameter of the WiFi component. I just tried that, but that did not help the API port or MQTT problems. What did happen is that port 80 isn't open to the remote wifi anymore, but it is still open via wireguard.
  • Setting require_connection_to_proceed: true in the wireguard section did not help.

@droscy
Copy link

droscy commented Sep 12, 2023

Hi @victorclaessen could you please post your full configuration and the config log output? Hide sensitive data. If you want to hide your IPs please change them to be consistent, do not mix them or use always x.y.z.w.

nmap shows that ports 80 and 3232 are open on the esp, but 6053 is closed;

6053 is closed or unreachable? I mean, the connection timeouts if you test with telnet?
What nmap command have you used? I'll try it to one of my setup.

esphome cannot open a connection to the API for the logs;

Are you receiving a timeout?

Last error code reported from esp-tls: 0x8006

This should be a timeout from mqtt client.

@jesserockz
Copy link
Member

I am closing this as esphome/esphome#4256 has been merged and will be in the next release.
Please test the ESPHome dev version and create any issues in https://github.com/esphome/issues

@esphome esphome locked as resolved and limited conversation to collaborators Sep 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests