ciniml / WireGuard-ESP32-Arduino

WireGuard implementation for ESP32 Arduino
Other
782 stars 60 forks source link

Cannot connect to wireguard server by following readme instructions #21

Open delthia opened 2 years ago

delthia commented 2 years ago

Hi,

I'm working on a project where I have an esp32 as a prometheus endpoint serving the data of a sensor, and in the long term setup, the raspberry pi containing the prometheus and grafana containers will be in a separate network as the esp, both behind a NAT. I was about to install a raspberry pi zero w as a sort of wireguard gateway, I found this library.

I don't get an error when trying to connect to the wireguard server, but I can't access the esp neither from the wireguard server, nor from a client connected to the same wireguard server, but even with it connected to the wireguard server, I can still access the endpoint via the local IP of the esp. When connected to wireguard, I don't think the esp can access anything via the internet, as it can't sync the time via ntp after connecting to wireguard. Other clients under the same server work properly. I've tried deleting and creating another client on the server, just in case, but that doesn't work either. The following code is what I've uploaded to the esp

#include <OneWire.h>  // https://www.pjrc.com/teensy/td_libs_OneWire.html
#include <DallasTemperature.h>  // https://github.com/milesburton/Arduino-Temperature-Control-Library
#include <WiFi.h>
#include <WireGuard-ESP32.h>  // https://github.com/ciniml/WireGuard-ESP32-Arduino
#include "time.h"

const int oneWirePin = 5; // DS18B20
OneWire oneWireBus(oneWirePin);
DallasTemperature t(&oneWireBus);

/* WIFI credentials */
//const char* ssid = "ssid";  // wifi ssid
//const char* password = "pass";  // wifi password

/* Server timeout */
unsigned long currentTime = millis();
unsigned long previousTime = 0;
const long timeoutTime = 2000;

/* Wiregard */
char private_key[] = "private-key";
IPAddress local_ip(10,7,0,3);
char public_key[] = "public-key";
char endpoint_address[] = "vpn-server";
int endpoint_port = 51820;
static WireGuard wg;

/* WiFi server */
WiFiServer server(80);  // Create a server on port 80
String header;  // Variable to store the header

/* Be able to read the ESPs internal temperature sensor */
#ifdef __cplusplus
  extern "C" {
#endif

uint8_t temprature_sens_read();

#ifdef __cplusplus
  }
#endif

/* Get the metrics and format them according to prometheus */
String getMetrics() {
  String p = "";
  float temp = 0;

  float temperature = ((temprature_sens_read() - 32) / 1.8);  // Internal temperature

  t.requestTemperatures();  // Get the DS18B20s temperature
  temp = t.getTempCByIndex(0);  // and store it in a variable

  setMetric(&p, "esp32_uptime", String(millis()));          // ESP uptime
  setMetric(&p, "esp32_wifi_rssi", String(WiFi.RSSI()));    // WiFi RSSI
  setMetric(&p, "esp32_temperature", String(temperature));  // Internal temperature
  setMetric(&p, "ds18b20_temperature", String(temp));       // DS18B20

  return p; // Return an string with all the metrics
}

/* Create a string containing a metric formated according to prometheus */
void setMetric(String *p, String metric, String value) {
  *p += "# " + metric + "\n";
  *p += "# TYPE " + metric + " gauge\n";
  *p += "" + metric + " ";
  *p += value;
  *p += "\n";
}

void setup() {
  Serial.begin(115200); // Serial port
  t.begin();  // DS18B20
  WiFi.begin(ssid, password); // WiFi

  /* Wait until wifi has connected */
  while (WiFi.status() != WL_CONNECTED) delay(500);

  /* When connected start the server and print the IP */
  Serial.println(WiFi.localIP());
  server.begin();

  /* Sync the time via NTP and print it */
  configTime(3600, 3600, "pool.ntp.org");
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)) Serial.println("Failed to get the time");  // If unable to get the time, print an error
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); // Otherwise print the time in the format: Weekday, Day Month Year Hour:Minute:Second

  /* Also connect to the wireguard VPN */
  Serial.println("Starting WG");
  if(!wg.begin(local_ip, private_key, endpoint_address, public_key, endpoint_port)) Serial.println("Failed to start WG");
}

void printLocalTime(){
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

void loop() {
  WiFiClient client = server.available(); // WiFi server is listening

  /* When a client connects */
  if (client) {
    currentTime = millis();       // Save current time
    previousTime = currentTime;   // Save lasts connection time
    Serial.println("Client");
    /*struct tm timeinfo;
    Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");   // Print the current time*/
    printLocalTime();
    String currentLine = "";
    /* While the client doesn't go over the timeout time */
    while (client.connected() && currentTime - previousTime <= timeoutTime) {
      currentTime = millis();
      /* If the client is listening */
      if (client.available()) {
        char c = client.read(); // Save the received information
        Serial.write(c);        // And print it
        header += c;
        if (c == '\n') {                    // When an end of line is received
          if (currentLine.length() == 0) {  // And the next line is blank
            /* Send the http header */
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
          }
          client.print(getMetrics()); // Send the metrics
          break;  // Break the loop
        }
      }
    }
    header = "";
    client.stop();  // Disconnect the client
    Serial.println("Disconnected"); // Say so on the serial port
    Serial.println(currentTime - previousTime);
    Serial.println("");
  }
}

The expected behaviour is: The esp connects to the specified WiFi, and then to the wireguard server, so now, the prometheus container, that is on a docker host in a separate network, but connected to the same vpn, can access the remote esp and save the data to be represented in grafana.

Thanks