Skip to content

hurzhurz/wg-bridge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🌐 WireGuard Bridge

A lightweight DERP-like UDP relay server designed to connect multiple WireGuard peers across NAT, dynamic IPs, or different IP protocol versions (IPv4/IPv6).

It functions as a stateless middleman, allowing peers to establish a direct-feeling connection without the overhead of tunnel-in-tunnel encapsulation.


🛡️ Key Features

  • No Tunnel-in-Tunnel Overhead: Packets are forwarded at the UDP layer, maintaining maximum performance.
  • End-to-End Encrypted: The bridge only sees encrypted WireGuard packets. It does not possess any private keys.
  • NAT & Dynamic IP Friendly: Solves connectivity issues where both peers are behind restrictive NAT or use changing IPs.
  • Protocol Agnostic: Seamlessly bridges IPv4 and IPv6 traffic.
  • Simple Authorization: Uses WireGuard's mac1 field and public keys for secure peer validation.

⚠️ Disclaimer

Use at your own risk. This implementation is a functional prototype. While the forwarded data remains secure due to WireGuard's design, the bridge itself might be unreliable or exhibit edge-case bugs in high-load scenarios.


⚙️ How it Works

The bridge listens on a UDP socket and observes WireGuard handshakes to learn which peer indices belong to which public keys.

  1. Handshake Observation: When an initiation packet arrives, the bridge verifies the mac1 field against a list of allowed public keys.
  2. Peer Discovery: Since the exact destination might be unknown at the start, the bridge forwards the initiation to all potential peers in the same "key group".
  3. Session Tracking: Once the handshake response is seen, the bridge maps the session indices and forwards subsequent transport packets directly between the two verified endpoints.

🚀 Getting Started

1. Requirements

  • Python 3.x
  • No external libraries required (uses standard library modules like socket, hashlib, etc.)

2. Basic Usage

Run the script by providing one or more comma-separated lists of public keys that are allowed to communicate with each other.

# Example: Create a group of 3 peers allowed to talk to each other
python3 wg-bridge.py --keys "PubKey1...,PubKey2...,PubKey3..."

# Example: Multiple isolated groups
python3 wg-bridge.py \
  --keys "GroupA_Key1...,GroupA_Key2..." \
  --keys "GroupB_Key1...,GroupB_Key2..."

Parameters:

  • --port, -p: UDP port to listen on (Default: 51820).
  • --keys, -k: Comma-separated list of public keys. Can be used multiple times.

📦 Deployment Options

Docker (Recommended)

You can use the provided Dockerfile or example.docker-compose.yml.

docker-compose up -d

Systemd Service

  1. Copy wg-bridge.py to /opt/wg-bridge/.
  2. Edit example.wg-bridge.service with your actual keys and path.
  3. Install the service:
cp example.wg-bridge.service /etc/systemd/system/wg-bridge.service
systemctl daemon-reload
systemctl enable --now wg-bridge

🔧 WireGuard Client Configuration

To use the bridge, adjust your local WireGuard configuration (/etc/wireguard/wg0.conf or mobile app):

  1. Endpoint: Set the Endpoint of all relevant peers to the IP/Domain and Port of your Bridge server.
    • Note: WireGuard allows using the same Endpoint for multiple peers.
  2. Persistent Keepalive: Highly recommended to keep NAT mappings alive.
    [Peer]
    PublicKey = <Remote_Peer_Public_Key>
    Endpoint = bridge.yourserver.com:51820
    PersistentKeepalive = 25
    AllowedIPs = 10.0.0.x/32

📝 License

This project is provided "as-is". Check the source code for details.

About

Lightweight WireGuard UDP Relay (DERP-like) for NAT traversal and dynamic IP connectivity. No tunnel overhead.

Topics

Resources

Stars

Watchers

Forks

Contributors