Skip to content

Latest commit

 

History

History
232 lines (172 loc) · 6.05 KB

File metadata and controls

232 lines (172 loc) · 6.05 KB

WireGuard Setup Guide for ESP32-CAM

This guide will help you set up WireGuard VPN on your ESP32-CAM device.

Prerequisites

  1. A WireGuard server (can be set up on a VPS, home server, or cloud instance)
  2. Admin access to configure the WireGuard server
  3. Basic understanding of networking concepts

Overview

The ESP32-CAM implementation:

  1. Synchronizes time with NTP (required for WireGuard)
  2. Establishes a WireGuard VPN tunnel to your server
  3. Maintains encrypted communication through the tunnel

Step 1: Set Up WireGuard Server

Option A: Ubuntu/Debian Server

# Install WireGuard
sudo apt update
sudo apt install wireguard

# Generate server keys
cd /etc/wireguard
umask 077
wg genkey | tee server_private.key | wg pubkey > server_public.key

# Create server configuration
sudo nano /etc/wireguard/wg0.conf

Add this configuration:

[Interface]
PrivateKey = <SERVER_PRIVATE_KEY_FROM_FILE>
Address = 10.0.0.1/24
ListenPort = 51820
SaveConfig = true

# Enable IP forwarding and NAT (optional, for internet routing)
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Enable IP forwarding
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# Start WireGuard
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

Step 2: Generate ESP32 Keys

On your WireGuard server:

# Generate ESP32 client keys
wg genkey | tee esp32_private.key | wg pubkey > esp32_public.key

# Display the keys
echo "ESP32 Private Key:"
cat esp32_private.key
echo ""
echo "ESP32 Public Key:"
cat esp32_public.key

Step 3: Add ESP32 as WireGuard Peer

On your server, add the ESP32 as a peer:

sudo wg set wg0 peer <ESP32_PUBLIC_KEY> allowed-ips 10.0.0.2/32
sudo wg-quick save wg0

Or manually edit /etc/wireguard/wg0.conf:

[Peer]
PublicKey = <ESP32_PUBLIC_KEY>
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25

Then restart WireGuard:

sudo systemctl restart wg-quick@wg0

Step 4: Configure ESP32-CAM

Edit include/secrets.h in your project:

// NTP Time Server (required for WireGuard)
#define NTP_SERVER "pool.ntp.org"
#define GMT_OFFSET_SEC 0
#define DAYLIGHT_OFFSET_SEC 0

// WireGuard Configuration
#define WG_PRIVATE_KEY "YOUR_ESP32_PRIVATE_KEY_HERE"      // From esp32_private.key
#define WG_LOCAL_IP "10.0.0.2"                            // ESP32's tunnel IP
#define WG_ENDPOINT_ADDRESS "YOUR_SERVER_IP"              // Server's public IP
#define WG_ENDPOINT_PORT 51820                            // Server's WireGuard port
#define WG_PUBLIC_KEY "YOUR_SERVER_PUBLIC_KEY_HERE"       // From server_public.key

Important Notes:

  • WG_PRIVATE_KEY: The private key from esp32_private.key (base64 encoded)
  • WG_PUBLIC_KEY: The public key from server_public.key (base64 encoded)
  • WG_ENDPOINT_ADDRESS: Must be an IP address (not a domain name in this version)
  • WG_LOCAL_IP: Must match the IP you assigned in the server's peer configuration

Step 5: Verify Server Configuration

On your WireGuard server:

# Check WireGuard status
sudo wg show

# Check if UDP port is open
sudo netstat -unlp | grep 51820

# Check firewall (if using ufw)
sudo ufw allow 51820/udp

Step 6: Upload and Test

  1. Build and upload the firmware to your ESP32-CAM
  2. Monitor the Serial output (115200 baud):

Expected output:

ESP32-CAM with Firebase Starting...
Connecting to Wi-Fi...
Connected with IP: 192.168.1.100

=== SYNCHRONIZING TIME WITH NTP ===
Waiting for NTP time sync....
✅ Time synchronized successfully!
Current time: Wed Oct 29 12:34:56 2025

=== INITIALIZING WIREGUARD ===
WireGuard Local IP: 10.0.0.2
WireGuard Endpoint: YOUR_SERVER_IP:51820
✅ WireGuard initialized successfully!
✅ WireGuard tunnel IP: 10.0.0.2
✅ WireGuard VPN tunnel established

Troubleshooting

Time Sync Fails

  • Check WiFi connection is stable
  • Try different NTP server: time.google.com, time.cloudflare.com
  • Check timezone settings in secrets.h

WireGuard Connection Fails

  • Verify server is running: sudo wg show
  • Check firewall: Ensure UDP port 51820 is open
  • Verify keys: Make sure you're using the correct keys
  • Check IP addresses: Ensure WG_LOCAL_IP doesn't conflict with existing peers
  • Server logs: sudo journalctl -u wg-quick@wg0 -f

On the Server

# Check WireGuard status
sudo wg show

# Expected output should show your ESP32 peer
interface: wg0
  public key: <SERVER_PUBLIC_KEY>
  private key: (hidden)
  listening port: 51820

peer: <ESP32_PUBLIC_KEY>
  endpoint: <ESP32_PUBLIC_IP>:<random_port>
  allowed ips: 10.0.0.2/32
  latest handshake: X seconds ago
  transfer: X.XX KiB received, X.XX KiB sent

Testing the Connection

Once connected, you can ping the ESP32 through the tunnel:

# From your WireGuard server
ping 10.0.0.2

You can also access the ESP32's web interface through the tunnel:

http://10.0.0.2/
ws://10.0.0.2:81/ws

Security Notes

  1. Keep private keys secret - Never commit them to version control
  2. Use strong keys - Always generate keys using wg genkey
  3. Firewall rules - Only open necessary ports on your server
  4. Regular updates - Keep your WireGuard server updated
  5. Monitor connections - Regularly check sudo wg show for unauthorized peers

Advanced Configuration

Using a Domain Name (requires DNS resolution)

The current implementation requires an IP address. For domain name support, you would need to add DNS resolution code before calling initWireGuard().

PersistentKeepalive

The ESP32 should send keepalive packets to maintain the connection. This is especially important if the ESP32 is behind NAT. The WireGuard-ESP32 library handles this automatically.

Resources