mirror of
https://github.com/fosrl/newt.git
synced 2026-02-07 21:46:39 +00:00
182 lines
4.7 KiB
Go
182 lines
4.7 KiB
Go
// Example of using netstack2 TCP/UDP proxying with WireGuard
|
|
//
|
|
// This example shows how to enable transparent TCP/UDP proxying
|
|
// through a WireGuard tunnel using netstack.
|
|
//
|
|
// Build: go build -o example examples/proxying/main.go
|
|
// Run: ./example
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/netip"
|
|
|
|
"github.com/fosrl/newt/netstack2"
|
|
)
|
|
|
|
func main() {
|
|
fmt.Println("Netstack2 TCP/UDP Proxying Examples")
|
|
fmt.Println("====================================\n")
|
|
|
|
// Example 1: Recommended - Subnet-based proxying (dual-interface)
|
|
example1()
|
|
|
|
// Example 2: Single interface with proxying (may conflict with WireGuard)
|
|
example2()
|
|
|
|
// Example 3: Enable proxying after creation (single interface)
|
|
example3()
|
|
|
|
// Example 4: Standard netstack without proxying (backward compatible)
|
|
example4()
|
|
}
|
|
|
|
func example1() {
|
|
fmt.Println("=== Example 1: Subnet-Based Proxying (Recommended) ===")
|
|
fmt.Println("This approach avoids conflicts with WireGuard by using a secondary NIC")
|
|
|
|
localAddresses := []netip.Addr{
|
|
netip.MustParseAddr("10.0.0.2"),
|
|
}
|
|
dnsServers := []netip.Addr{
|
|
netip.MustParseAddr("1.1.1.1"),
|
|
}
|
|
mtu := 1420
|
|
|
|
// Create netstack normally (no proxying on main interface)
|
|
tun, tnet, err := netstack2.CreateNetTUN(localAddresses, dnsServers, mtu)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create netstack: %v", err)
|
|
}
|
|
defer tun.Close()
|
|
|
|
fmt.Println("✓ Netstack created (WireGuard uses NIC 1)")
|
|
|
|
// Define subnets that should be proxied
|
|
proxySubnets := []netip.Prefix{
|
|
netip.MustParsePrefix("192.168.1.0/24"), // Internal services
|
|
netip.MustParsePrefix("10.20.0.0/16"), // Application subnet
|
|
}
|
|
|
|
// Enable proxying on a secondary NIC for these subnets
|
|
err = tnet.EnableProxyOnSubnet(proxySubnets, true, true)
|
|
if err != nil {
|
|
log.Fatalf("Failed to enable proxy on subnet: %v", err)
|
|
}
|
|
|
|
fmt.Println("✓ TCP/UDP proxying enabled on NIC 2 for:")
|
|
for _, subnet := range proxySubnets {
|
|
fmt.Printf(" - %s\n", subnet)
|
|
}
|
|
fmt.Println("✓ Routing table updated to direct subnet traffic to proxy NIC")
|
|
fmt.Println(" → WireGuard on NIC 1: handles encryption/decryption")
|
|
fmt.Println(" → Proxy on NIC 2: handles TCP/UDP termination for specified subnets")
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
func example2() {
|
|
fmt.Println("=== Example 2: Single Interface with Proxying (Not Recommended) ===")
|
|
fmt.Println("⚠️ May conflict with WireGuard packet handling!")
|
|
|
|
localAddresses := []netip.Addr{
|
|
netip.MustParseAddr("10.0.0.2"),
|
|
}
|
|
dnsServers := []netip.Addr{
|
|
netip.MustParseAddr("1.1.1.1"),
|
|
}
|
|
mtu := 1420
|
|
|
|
// Create netstack with both TCP and UDP proxying enabled
|
|
tun, tnet, err := netstack2.CreateNetTUNWithOptions(
|
|
localAddresses,
|
|
dnsServers,
|
|
mtu,
|
|
netstack2.NetTunOptions{
|
|
EnableTCPProxy: true,
|
|
EnableUDPProxy: true,
|
|
},
|
|
)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create netstack: %v", err)
|
|
}
|
|
defer tun.Close()
|
|
|
|
fmt.Println("✓ Netstack created with TCP and UDP proxying enabled")
|
|
fmt.Println(" → Any TCP/UDP traffic through the tunnel will be proxied to actual targets")
|
|
|
|
// Now any TCP or UDP connection made through the tunnel will be
|
|
// automatically terminated in netstack and proxied to the target
|
|
|
|
_ = tnet
|
|
fmt.Println()
|
|
}
|
|
|
|
func example2() {
|
|
fmt.Println("=== Example 2: Enable proxying after creation ===")
|
|
|
|
localAddresses := []netip.Addr{
|
|
netip.MustParseAddr("10.0.0.3"),
|
|
}
|
|
dnsServers := []netip.Addr{
|
|
netip.MustParseAddr("1.1.1.1"),
|
|
}
|
|
mtu := 1420
|
|
|
|
// Create standard netstack first
|
|
tun, tnet, err := netstack2.CreateNetTUN(localAddresses, dnsServers, mtu)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create netstack: %v", err)
|
|
}
|
|
defer tun.Close()
|
|
|
|
fmt.Println("✓ Netstack created")
|
|
|
|
// Enable TCP proxying
|
|
if err := tnet.EnableTCPProxy(); err != nil {
|
|
log.Fatalf("Failed to enable TCP proxy: %v", err)
|
|
}
|
|
fmt.Println("✓ TCP proxying enabled")
|
|
|
|
// Enable UDP proxying
|
|
if err := tnet.EnableUDPProxy(); err != nil {
|
|
log.Fatalf("Failed to enable UDP proxy: %v", err)
|
|
}
|
|
fmt.Println("✓ UDP proxying enabled")
|
|
|
|
// Calling EnableTCPProxy again is safe (no-op)
|
|
if err := tnet.EnableTCPProxy(); err != nil {
|
|
log.Fatalf("Failed to re-enable TCP proxy: %v", err)
|
|
}
|
|
fmt.Println("✓ Re-enabling TCP proxying is safe (no-op)")
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
func example3() {
|
|
fmt.Println("=== Example 3: Standard netstack (no proxying) ===")
|
|
|
|
localAddresses := []netip.Addr{
|
|
netip.MustParseAddr("10.0.0.4"),
|
|
}
|
|
dnsServers := []netip.Addr{
|
|
netip.MustParseAddr("1.1.1.1"),
|
|
}
|
|
mtu := 1420
|
|
|
|
// Use standard CreateNetTUN - backward compatible
|
|
tun, tnet, err := netstack2.CreateNetTUN(localAddresses, dnsServers, mtu)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create netstack: %v", err)
|
|
}
|
|
defer tun.Close()
|
|
|
|
fmt.Println("✓ Standard netstack created (no proxying)")
|
|
fmt.Println(" → Use tnet.DialTCP(), tnet.DialUDP() for manual connections")
|
|
|
|
_ = tnet
|
|
fmt.Println()
|
|
}
|