91 lines
2.7 KiB
Go
91 lines
2.7 KiB
Go
/* SPDX-License-Identifier: MIT
|
|
*
|
|
* Multi-path WireGuard Example
|
|
*
|
|
* This example demonstrates how to create a WireGuard device that sends
|
|
* packets through multiple network interfaces simultaneously.
|
|
*/
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"golang.zx2c4.com/wireguard/device"
|
|
"golang.zx2c4.com/wireguard/tun"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) < 2 {
|
|
fmt.Printf("Usage: %s <interface1> [interface2] [interface3] ...\n", os.Args[0])
|
|
fmt.Println("Example: sudo ./multipath eth0 wlan0")
|
|
fmt.Println("\nThis will create a WireGuard tunnel that sends packets through both eth0 and wlan0")
|
|
fmt.Println("Available interfaces:")
|
|
|
|
interfaces, err := device.GetNetworkInterfaceInfo()
|
|
if err != nil {
|
|
log.Fatalf("Failed to get interface info: %v", err)
|
|
}
|
|
|
|
for _, iface := range interfaces {
|
|
fmt.Printf(" %s\n", iface.String())
|
|
}
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Get interface names from command line
|
|
interfaceNames := os.Args[1:]
|
|
|
|
fmt.Printf("Creating multi-path WireGuard device using interfaces: %v\n", interfaceNames)
|
|
|
|
// Create logger
|
|
logger := device.NewLogger(device.LogLevelVerbose, "multipath-example: ")
|
|
|
|
// Create TUN device
|
|
tunDevice, err := tun.CreateTUN("wg-multipath", 1420)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create TUN device: %v", err)
|
|
}
|
|
defer tunDevice.Close()
|
|
|
|
fmt.Printf("Created TUN device: %s\n", tunDevice.Name())
|
|
|
|
// Create multi-path WireGuard device
|
|
wgDevice, err := device.NewMultiPathDeviceByNames(tunDevice, interfaceNames, logger)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create multi-path WireGuard device: %v", err)
|
|
}
|
|
defer wgDevice.Close()
|
|
|
|
fmt.Printf("Multi-path WireGuard device created successfully!\n")
|
|
fmt.Printf("Each outbound packet will be sent through ALL %d specified interfaces\n", len(interfaceNames))
|
|
|
|
// Configure WireGuard (you would normally load this from a config file)
|
|
// This is just a basic example configuration
|
|
logger.Verbosef("Device ready. You can now configure it using wg(8) commands:")
|
|
logger.Verbosef(" sudo wg set %s private-key <private-key-file>", tunDevice.Name())
|
|
logger.Verbosef(" sudo wg set %s peer <peer-public-key> endpoint <peer-endpoint> allowed-ips <allowed-ips>", tunDevice.Name())
|
|
logger.Verbosef(" sudo ip addr add <your-vpn-ip>/24 dev %s", tunDevice.Name())
|
|
logger.Verbosef(" sudo ip link set %s up", tunDevice.Name())
|
|
|
|
// Bring device up
|
|
err = wgDevice.Up()
|
|
if err != nil {
|
|
log.Fatalf("Failed to bring device up: %v", err)
|
|
}
|
|
|
|
fmt.Println("WireGuard device is up and running!")
|
|
fmt.Println("Press Ctrl+C to stop...")
|
|
|
|
// Wait for interrupt signal
|
|
c := make(chan os.Signal, 1)
|
|
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
|
|
<-c
|
|
|
|
fmt.Println("\nShutting down...")
|
|
wgDevice.Down()
|
|
} |