Shift things around - remove native

This commit is contained in:
Owen
2025-11-17 13:39:32 -05:00
parent 491180c6a1
commit dbbea6b34c
8 changed files with 184 additions and 1088 deletions

View File

@@ -4,17 +4,18 @@ import (
"fmt"
"strings"
"github.com/fosrl/newt/clients"
wgnetstack "github.com/fosrl/newt/clients"
"github.com/fosrl/newt/logger"
"github.com/fosrl/newt/netstack2"
"github.com/fosrl/newt/proxy"
"github.com/fosrl/newt/websocket"
"golang.zx2c4.com/wireguard/tun/netstack"
"github.com/fosrl/newt/wgnetstack"
"github.com/fosrl/newt/wgtester"
)
var wgService *wgnetstack.WireGuardService
var wgService *clients.WireGuardService
var wgTesterServer *wgtester.Server
var ready bool

View File

@@ -1,4 +1,4 @@
package wgnetstack
package clients
import (
"context"
@@ -31,16 +31,17 @@ import (
type WgConfig struct {
IpAddress string `json:"ipAddress"`
Peers []Peer `json:"peers"`
Targets TargetsByType `json:"targets"`
Targets []Target `json:"targets"`
}
type TargetsByType struct {
UDP []string `json:"udp"`
TCP []string `json:"tcp"`
type Target struct {
CIDR string `json:"cidr"`
PortRange []PortRange `json:"portRange,omitempty"`
}
type TargetData struct {
Targets []string `json:"targets"`
type PortRange struct {
Min uint16 `json:"min"`
Max uint16 `json:"max"`
}
type Peer struct {
@@ -178,6 +179,8 @@ func NewWireGuardService(interfaceName string, mtu int, generateAndSaveKeyTo str
wsClient.RegisterHandler("newt/wg/peer/add", service.handleAddPeer)
wsClient.RegisterHandler("newt/wg/peer/remove", service.handleRemovePeer)
wsClient.RegisterHandler("newt/wg/peer/update", service.handleUpdatePeer)
wsClient.RegisterHandler("newt/wg/target/add", service.handleAddTarget)
wsClient.RegisterHandler("newt/wg/target/remove", service.handleRemoveTarget)
return service, nil
}
@@ -327,6 +330,10 @@ func (s *WireGuardService) handleConfig(msg websocket.WSMessage) {
if err := s.ensureWireguardPeers(config.Peers); err != nil {
logger.Error("Failed to ensure WireGuard peers: %v", err)
}
if err := s.ensureTargets(config.Targets); err != nil {
logger.Error("Failed to ensure WireGuard targets: %v", err)
}
}
func (s *WireGuardService) ensureWireguardInterface(wgconfig WgConfig) error {
@@ -376,7 +383,7 @@ func (s *WireGuardService) ensureWireguardInterface(wgconfig WgConfig) error {
// logger.Info("Private key is %s", fixKey(s.key.String()))
// Configure WireGuard with private key
config := fmt.Sprintf("private_key=%s", fixKey(s.key.String()))
config := fmt.Sprintf("private_key=%s", util.FixKey(s.key.String()))
err = s.device.IpcSet(config)
if err != nil {
@@ -409,20 +416,6 @@ func (s *WireGuardService) ensureWireguardInterface(wgconfig WgConfig) error {
return nil
}
func fixKey(key string) string {
// Remove any whitespace
key = strings.TrimSpace(key)
// Decode from base64
decoded, err := base64.StdEncoding.DecodeString(key)
if err != nil {
logger.Fatal("Error decoding base64: %v", err)
}
// Convert to hex
return hex.EncodeToString(decoded)
}
func (s *WireGuardService) ensureWireguardPeers(peers []Peer) error {
// For netstack, we need to manage peers differently
// We'll configure peers directly on the device using IPC
@@ -461,6 +454,38 @@ func (s *WireGuardService) ensureWireguardPeers(peers []Peer) error {
return nil
}
func (s *WireGuardService) ensureTargets(targets []Target) error {
if s.tnet == nil {
return fmt.Errorf("netstack not initialized")
}
// handler.AddSubnetRule(subnet2, []PortRange{
// {Min: 12000, Max: 12001},
// {Min: 8000, Max: 8000},
// })
for _, target := range targets {
prefix, err := netip.ParsePrefix(target.CIDR)
if err != nil {
return fmt.Errorf("invalid CIDR %s: %v", target.CIDR, err)
}
var portRanges []netstack2.PortRange
for _, pr := range target.PortRange {
portRanges = append(portRanges, netstack2.PortRange{
Min: pr.Min,
Max: pr.Max,
})
}
s.tnet.AddProxySubnetRule(prefix, portRanges)
logger.Info("Added target subnet %s with port ranges: %v", target.CIDR, target.PortRange)
}
return nil
}
func (s *WireGuardService) addPeerToDevice(peer Peer) error {
// parse the key first
pubKey, err := wgtypes.ParseKey(peer.PublicKey)
@@ -469,7 +494,7 @@ func (s *WireGuardService) addPeerToDevice(peer Peer) error {
}
// Build IPC configuration string for the peer
config := fmt.Sprintf("public_key=%s", fixKey(pubKey.String()))
config := fmt.Sprintf("public_key=%s", util.FixKey(pubKey.String()))
// Add allowed IPs
for _, allowedIP := range peer.AllowedIPs {
@@ -559,7 +584,7 @@ func (s *WireGuardService) removePeer(publicKey string) error {
}
// Build IPC configuration string to remove the peer
config := fmt.Sprintf("public_key=%s\nremove=true", fixKey(pubKey.String()))
config := fmt.Sprintf("public_key=%s\nremove=true", util.FixKey(pubKey.String()))
if err := s.device.IpcSet(config); err != nil {
return fmt.Errorf("failed to remove peer: %v", err)
@@ -603,7 +628,7 @@ func (s *WireGuardService) handleUpdatePeer(msg websocket.WSMessage) {
}
// Build IPC configuration string to update the peer
config := fmt.Sprintf("public_key=%s\nupdate_only=true", fixKey(pubKey.String()))
config := fmt.Sprintf("public_key=%s\nupdate_only=true", util.FixKey(pubKey.String()))
// Handle AllowedIPs update
if len(request.AllowedIPs) > 0 {
@@ -801,6 +826,81 @@ func (s *WireGuardService) reportPeerBandwidth() error {
return nil
}
// filterReadOnlyFields removes read-only fields from WireGuard IPC configuration
func (s *WireGuardService) handleAddTarget(msg websocket.WSMessage) {
logger.Debug("Received message: %v", msg.Data)
var target Target
jsonData, err := json.Marshal(msg.Data)
if err != nil {
logger.Info("Error marshaling data: %v", err)
return
}
if err := json.Unmarshal(jsonData, &target); err != nil {
logger.Info("Error unmarshaling target data: %v", err)
return
}
if s.tnet == nil {
logger.Info("Netstack not initialized")
return
}
prefix, err := netip.ParsePrefix(target.CIDR)
if err != nil {
logger.Info("Invalid CIDR %s: %v", target.CIDR, err)
return
}
var portRanges []netstack2.PortRange
for _, pr := range target.PortRange {
portRanges = append(portRanges, netstack2.PortRange{
Min: pr.Min,
Max: pr.Max,
})
}
s.tnet.AddProxySubnetRule(prefix, portRanges)
logger.Info("Added target subnet %s with port ranges: %v", target.CIDR, target.PortRange)
}
func (s *WireGuardService) handleRemoveTarget(msg websocket.WSMessage) {
logger.Debug("Received message: %v", msg.Data)
type RemoveTargetRequest struct {
CIDR string `json:"cidr"`
}
jsonData, err := json.Marshal(msg.Data)
if err != nil {
logger.Info("Error marshaling data: %v", err)
return
}
var request RemoveTargetRequest
if err := json.Unmarshal(jsonData, &request); err != nil {
logger.Info("Error unmarshaling data: %v", err)
return
}
if s.tnet == nil {
logger.Info("Netstack not initialized")
return
}
prefix, err := netip.ParsePrefix(request.CIDR)
if err != nil {
logger.Info("Invalid CIDR %s: %v", request.CIDR, err)
return
}
s.tnet.RemoveProxySubnetRule(prefix)
logger.Info("Removed target subnet %s", request.CIDR)
}
// filterReadOnlyFields removes read-only fields from WireGuard IPC configuration
func (s *WireGuardService) filterReadOnlyFields(config string) string {
lines := strings.Split(config, "\n")

View File

@@ -3,8 +3,6 @@ package main
import (
"bytes"
"context"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"os"
@@ -27,20 +25,6 @@ import (
const msgHealthFileWriteFailed = "Failed to write health file: %v"
func fixKey(key string) string {
// Remove any whitespace
key = strings.TrimSpace(key)
// Decode from base64
decoded, err := base64.StdEncoding.DecodeString(key)
if err != nil {
logger.Fatal("Error decoding base64: %v", err)
}
// Convert to hex
return hex.EncodeToString(decoded)
}
func ping(tnet *netstack.Net, dst string, timeout time.Duration) (time.Duration, error) {
logger.Debug("Pinging %s", dst)
socket, err := tnet.Dial("ping4", dst)

View File

@@ -678,7 +678,7 @@ func main() {
public_key=%s
allowed_ip=%s/32
endpoint=%s
persistent_keepalive_interval=5`, fixKey(privateKey.String()), fixKey(wgData.PublicKey), wgData.ServerIP, endpoint)
persistent_keepalive_interval=5`, util.FixKey(privateKey.String()), util.FixKey(wgData.PublicKey), wgData.ServerIP, endpoint)
err = dev.IpcSet(config)
if err != nil {

View File

@@ -150,18 +150,18 @@ func NewProxyHandler(options ProxyHandlerOptions) (*ProxyHandler, error) {
}
}
// Example 1: Add a subnet with no port restrictions (all ports allowed)
// This accepts all traffic to 10.20.20.0/24
subnet1 := netip.MustParsePrefix("10.20.20.0/24")
handler.AddSubnetRule(subnet1, nil)
// // Example 1: Add a subnet with no port restrictions (all ports allowed)
// // This accepts all traffic to 10.20.20.0/24
// subnet1 := netip.MustParsePrefix("10.20.20.0/24")
// handler.AddSubnetRule(subnet1, nil)
// Example 2: Add a subnet with specific port ranges
// This accepts traffic to 192.168.1.0/24 only on ports 80, 443, and 8000-9000
subnet2 := netip.MustParsePrefix("10.20.21.21/32")
handler.AddSubnetRule(subnet2, []PortRange{
{Min: 12000, Max: 12001},
{Min: 8000, Max: 8000},
})
// // Example 2: Add a subnet with specific port ranges
// // This accepts traffic to 192.168.1.0/24 only on ports 80, 443, and 8000-9000
// subnet2 := netip.MustParsePrefix("10.20.21.21/32")
// handler.AddSubnetRule(subnet2, []PortRange{
// {Min: 12000, Max: 12001},
// {Min: 8000, Max: 8000},
// })
return handler, nil
}

View File

@@ -48,6 +48,7 @@ type netTun struct {
mtu int
dnsServers []netip.Addr
hasV4, hasV6 bool
// TODO: LETS NOT KEEP THIS ON THE TUN AND MOVE IT BUT WE CAN KEEP IT FOR NOW
proxyHandler *ProxyHandler // Handles promiscuous mode packet processing
}
@@ -347,6 +348,30 @@ func (net *Net) ListenUDP(laddr *net.UDPAddr) (*gonet.UDPConn, error) {
return net.DialUDP(laddr, nil)
}
// AddProxySubnetRule adds a subnet rule to the proxy handler
// If portRanges is nil or empty, all ports are allowed for this subnet
func (net *Net) AddProxySubnetRule(prefix netip.Prefix, portRanges []PortRange) {
tun := (*netTun)(net)
if tun.proxyHandler != nil {
tun.proxyHandler.AddSubnetRule(prefix, portRanges)
}
}
// RemoveProxySubnetRule removes a subnet rule from the proxy handler
func (net *Net) RemoveProxySubnetRule(prefix netip.Prefix) {
tun := (*netTun)(net)
if tun.proxyHandler != nil {
tun.proxyHandler.RemoveSubnetRule(prefix)
}
}
// GetProxyHandler returns the proxy handler (for advanced use cases)
// Returns nil if proxy is not enabled
func (net *Net) GetProxyHandler() *ProxyHandler {
tun := (*netTun)(net)
return tun.proxyHandler
}
type PingConn struct {
laddr PingAddr
raddr PingAddr

View File

@@ -1,6 +1,8 @@
package util
import (
"encoding/base64"
"encoding/hex"
"fmt"
"net"
"strings"
@@ -120,3 +122,17 @@ func FindAvailableUDPPort(minPort, maxPort uint16) (uint16, error) {
return 0, fmt.Errorf("no available consecutive UDP ports found in range %d-%d", minPort, maxPort)
}
func FixKey(key string) string {
// Remove any whitespace
key = strings.TrimSpace(key)
// Decode from base64
decoded, err := base64.StdEncoding.DecodeString(key)
if err != nil {
logger.Fatal("Error decoding base64: %v", err)
}
// Convert to hex
return hex.EncodeToString(decoded)
}

1030
wg/wg.go

File diff suppressed because it is too large Load Diff