mirror of
https://github.com/fosrl/olm.git
synced 2026-02-25 06:16:47 +00:00
Formatting of peers and dns worked
This commit is contained in:
394
olm/olm.go
394
olm/olm.go
@@ -21,6 +21,7 @@ import (
|
||||
dnsOverride "github.com/fosrl/olm/dns/override"
|
||||
"github.com/fosrl/olm/network"
|
||||
"github.com/fosrl/olm/peermonitor"
|
||||
"github.com/fosrl/olm/peers"
|
||||
"github.com/fosrl/olm/websocket"
|
||||
"golang.zx2c4.com/wireguard/device"
|
||||
"golang.zx2c4.com/wireguard/tun"
|
||||
@@ -48,6 +49,7 @@ var (
|
||||
globalCtx context.Context
|
||||
stopRegister func()
|
||||
stopPing chan struct{}
|
||||
peerManager *peers.PeerManager
|
||||
)
|
||||
|
||||
func Init(ctx context.Context, config GlobalConfig) {
|
||||
@@ -464,33 +466,16 @@ func StartTunnel(config TunnelConfig) {
|
||||
interfaceIP,
|
||||
)
|
||||
|
||||
peerManager = peers.NewPeerManager(dev, peerMonitor, dnsProxy, interfaceName, privateKey)
|
||||
|
||||
for i := range wgData.Sites {
|
||||
site := &wgData.Sites[i] // Use a pointer to modify the struct in the slice
|
||||
site := wgData.Sites[i]
|
||||
apiServer.UpdatePeerStatus(site.SiteId, false, 0, site.Endpoint, false)
|
||||
|
||||
if err := ConfigurePeer(dev, *site, privateKey, endpoint); err != nil {
|
||||
logger.Error("Failed to configure peer: %v", err)
|
||||
if err := peerManager.AddPeer(site, endpoint); err != nil {
|
||||
logger.Error("Failed to add peer: %v", err)
|
||||
return
|
||||
}
|
||||
if err := network.AddRouteForServerIP(site.ServerIP, interfaceName); err != nil { // this is something for darwin only thats required
|
||||
logger.Error("Failed to add route for peer: %v", err)
|
||||
return
|
||||
}
|
||||
if err := network.AddRoutes(site.RemoteSubnets, interfaceName); err != nil {
|
||||
logger.Error("Failed to add routes for remote subnets: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, alias := range site.Aliases {
|
||||
// try to parse the alias address into net.IP
|
||||
address := net.ParseIP(alias.AliasAddress)
|
||||
if address == nil {
|
||||
logger.Warn("Invalid alias address for %s: %s", alias.Alias, alias.AliasAddress)
|
||||
continue
|
||||
}
|
||||
|
||||
dnsProxy.AddDNSRecord(alias.Alias, address)
|
||||
}
|
||||
|
||||
logger.Info("Configured peer %s", site.PublicKey)
|
||||
}
|
||||
@@ -528,41 +513,21 @@ func StartTunnel(config TunnelConfig) {
|
||||
return
|
||||
}
|
||||
|
||||
var updateData SiteConfig
|
||||
var updateData peers.SiteConfig
|
||||
if err := json.Unmarshal(jsonData, &updateData); err != nil {
|
||||
logger.Error("Error unmarshaling update data: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Update the peer in WireGuard
|
||||
if dev == nil {
|
||||
logger.Error("WireGuard device not initialized")
|
||||
return
|
||||
}
|
||||
|
||||
// Find the existing peer to merge updates with
|
||||
var existingPeer *SiteConfig
|
||||
var peerIndex int
|
||||
for i, site := range wgData.Sites {
|
||||
if site.SiteId == updateData.SiteId {
|
||||
existingPeer = &wgData.Sites[i]
|
||||
peerIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if existingPeer == nil {
|
||||
// Get existing peer from PeerManager
|
||||
existingPeer, exists := peerManager.GetPeer(updateData.SiteId)
|
||||
if !exists {
|
||||
logger.Error("Peer with site ID %d not found", updateData.SiteId)
|
||||
return
|
||||
}
|
||||
|
||||
// Store old values for comparison
|
||||
oldRemoteSubnets := existingPeer.RemoteSubnets
|
||||
oldPublicKey := existingPeer.PublicKey
|
||||
|
||||
// Create updated site config by merging with existing data
|
||||
// Only update fields that are provided (non-empty/non-zero)
|
||||
siteConfig := *existingPeer // Start with existing data
|
||||
siteConfig := existingPeer
|
||||
|
||||
if updateData.Endpoint != "" {
|
||||
siteConfig.Endpoint = updateData.Endpoint
|
||||
@@ -580,37 +545,13 @@ func StartTunnel(config TunnelConfig) {
|
||||
siteConfig.RemoteSubnets = updateData.RemoteSubnets
|
||||
}
|
||||
|
||||
// If the public key has changed, remove the old peer first
|
||||
if siteConfig.PublicKey != oldPublicKey {
|
||||
logger.Info("Public key changed for site %d, removing old peer with key %s", updateData.SiteId, oldPublicKey)
|
||||
if err := RemovePeer(dev, updateData.SiteId, oldPublicKey); err != nil {
|
||||
logger.Error("Failed to remove old peer: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := ConfigurePeer(dev, siteConfig, privateKey, endpoint); err != nil {
|
||||
if err := peerManager.UpdatePeer(siteConfig, endpoint); err != nil {
|
||||
logger.Error("Failed to update peer: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Handle remote subnet route changes
|
||||
if !stringSlicesEqual(oldRemoteSubnets, siteConfig.RemoteSubnets) {
|
||||
if err := network.RemoveRoutes(oldRemoteSubnets); err != nil {
|
||||
logger.Error("Failed to remove old remote subnet routes: %v", err)
|
||||
// Continue anyway to add new routes
|
||||
}
|
||||
|
||||
// Add new remote subnet routes
|
||||
if err := network.AddRoutes(siteConfig.RemoteSubnets, interfaceName); err != nil {
|
||||
logger.Error("Failed to add new remote subnet routes: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Update successful
|
||||
logger.Info("Successfully updated peer for site %d", updateData.SiteId)
|
||||
wgData.Sites[peerIndex] = siteConfig
|
||||
})
|
||||
|
||||
// Handler for adding a new peer
|
||||
@@ -623,46 +564,19 @@ func StartTunnel(config TunnelConfig) {
|
||||
return
|
||||
}
|
||||
|
||||
var siteConfig SiteConfig
|
||||
var siteConfig peers.SiteConfig
|
||||
if err := json.Unmarshal(jsonData, &siteConfig); err != nil {
|
||||
logger.Error("Error unmarshaling add data: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Add the peer to WireGuard
|
||||
if dev == nil {
|
||||
logger.Error("WireGuard device not initialized")
|
||||
return
|
||||
}
|
||||
|
||||
if err := ConfigurePeer(dev, siteConfig, privateKey, endpoint); err != nil {
|
||||
if err := peerManager.AddPeer(siteConfig, endpoint); err != nil {
|
||||
logger.Error("Failed to add peer: %v", err)
|
||||
return
|
||||
}
|
||||
if err := network.AddRouteForServerIP(siteConfig.ServerIP, interfaceName); err != nil {
|
||||
logger.Error("Failed to add route for new peer: %v", err)
|
||||
return
|
||||
}
|
||||
if err := network.AddRoutes(siteConfig.RemoteSubnets, interfaceName); err != nil {
|
||||
logger.Error("Failed to add routes for remote subnets: %v", err)
|
||||
return
|
||||
}
|
||||
for _, alias := range siteConfig.Aliases {
|
||||
// try to parse the alias address into net.IP
|
||||
address := net.ParseIP(alias.AliasAddress)
|
||||
if address == nil {
|
||||
logger.Warn("Invalid alias address for %s: %s", alias.Alias, alias.AliasAddress)
|
||||
continue
|
||||
}
|
||||
|
||||
dnsProxy.AddDNSRecord(alias.Alias, address)
|
||||
}
|
||||
|
||||
// Add successful
|
||||
logger.Info("Successfully added peer for site %d", siteConfig.SiteId)
|
||||
|
||||
// Update WgData with the new peer
|
||||
wgData.Sites = append(wgData.Sites, siteConfig)
|
||||
})
|
||||
|
||||
// Handler for removing a peer
|
||||
@@ -675,69 +589,19 @@ func StartTunnel(config TunnelConfig) {
|
||||
return
|
||||
}
|
||||
|
||||
var removeData PeerRemove
|
||||
var removeData peers.PeerRemove
|
||||
if err := json.Unmarshal(jsonData, &removeData); err != nil {
|
||||
logger.Error("Error unmarshaling remove data: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Find the peer to remove
|
||||
var peerToRemove *SiteConfig
|
||||
var newSites []SiteConfig
|
||||
|
||||
for _, site := range wgData.Sites {
|
||||
if site.SiteId == removeData.SiteId {
|
||||
peerToRemove = &site
|
||||
} else {
|
||||
newSites = append(newSites, site)
|
||||
}
|
||||
}
|
||||
|
||||
if peerToRemove == nil {
|
||||
logger.Error("Peer with site ID %d not found", removeData.SiteId)
|
||||
return
|
||||
}
|
||||
|
||||
// Remove the peer from WireGuard
|
||||
if dev == nil {
|
||||
logger.Error("WireGuard device not initialized")
|
||||
return
|
||||
}
|
||||
if err := RemovePeer(dev, removeData.SiteId, peerToRemove.PublicKey); err != nil {
|
||||
if err := peerManager.RemovePeer(removeData.SiteId); err != nil {
|
||||
logger.Error("Failed to remove peer: %v", err)
|
||||
// Send error response if needed
|
||||
return
|
||||
}
|
||||
|
||||
// Remove route for the peer
|
||||
err = network.RemoveRouteForServerIP(peerToRemove.ServerIP, interfaceName)
|
||||
if err != nil {
|
||||
logger.Error("Failed to remove route for peer: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Remove routes for remote subnets
|
||||
if err := network.RemoveRoutes(peerToRemove.RemoteSubnets); err != nil {
|
||||
logger.Error("Failed to remove routes for remote subnets: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, alias := range peerToRemove.Aliases {
|
||||
// try to parse the alias address into net.IP
|
||||
address := net.ParseIP(alias.AliasAddress)
|
||||
if address == nil {
|
||||
logger.Warn("Invalid alias address for %s: %s", alias.Alias, alias.AliasAddress)
|
||||
continue
|
||||
}
|
||||
|
||||
dnsProxy.RemoveDNSRecord(alias.Alias, address)
|
||||
}
|
||||
|
||||
// Remove successful
|
||||
logger.Info("Successfully removed peer for site %d", removeData.SiteId)
|
||||
|
||||
// Update WgData to remove the peer
|
||||
wgData.Sites = newSites
|
||||
})
|
||||
|
||||
// Handler for adding remote subnets to a peer
|
||||
@@ -750,77 +614,25 @@ func StartTunnel(config TunnelConfig) {
|
||||
return
|
||||
}
|
||||
|
||||
var addSubnetsData PeerAdd
|
||||
var addSubnetsData peers.PeerAdd
|
||||
if err := json.Unmarshal(jsonData, &addSubnetsData); err != nil {
|
||||
logger.Error("Error unmarshaling add-remote-subnets data: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Find the peer to update
|
||||
var peerIndex = -1
|
||||
for i, site := range wgData.Sites {
|
||||
if site.SiteId == addSubnetsData.SiteId {
|
||||
peerIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if peerIndex == -1 {
|
||||
logger.Error("Peer with site ID %d not found", addSubnetsData.SiteId)
|
||||
return
|
||||
}
|
||||
|
||||
// Add new subnets to the peer's remote subnets (avoiding duplicates)
|
||||
existingSubnets := make(map[string]bool)
|
||||
for _, subnet := range wgData.Sites[peerIndex].RemoteSubnets {
|
||||
existingSubnets[subnet] = true
|
||||
}
|
||||
|
||||
var newSubnets []string
|
||||
// Add new subnets
|
||||
for _, subnet := range addSubnetsData.RemoteSubnets {
|
||||
if !existingSubnets[subnet] {
|
||||
newSubnets = append(newSubnets, subnet)
|
||||
wgData.Sites[peerIndex].RemoteSubnets = append(wgData.Sites[peerIndex].RemoteSubnets, subnet)
|
||||
if err := peerManager.AddRemoteSubnet(addSubnetsData.SiteId, subnet); err != nil {
|
||||
logger.Error("Failed to add allowed IP %s: %v", subnet, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(newSubnets) == 0 {
|
||||
logger.Info("No new subnets to add for site %d (all already exist)", addSubnetsData.SiteId)
|
||||
// Still process aliases even if no new subnets
|
||||
} else {
|
||||
// Add routes for the new subnets
|
||||
if err := network.AddRoutes(newSubnets, interfaceName); err != nil {
|
||||
logger.Error("Failed to add routes for new remote subnets: %v", err)
|
||||
return
|
||||
}
|
||||
logger.Info("Successfully added %d remote subnet(s) to peer %d", len(newSubnets), addSubnetsData.SiteId)
|
||||
}
|
||||
|
||||
// Add new aliases to the peer's aliases (avoiding duplicates)
|
||||
existingAliases := make(map[string]bool)
|
||||
for _, alias := range wgData.Sites[peerIndex].Aliases {
|
||||
existingAliases[alias.Alias] = true
|
||||
}
|
||||
|
||||
var newAliases []Alias
|
||||
// Add new aliases
|
||||
for _, alias := range addSubnetsData.Aliases {
|
||||
if !existingAliases[alias.Alias] {
|
||||
address := net.ParseIP(alias.AliasAddress)
|
||||
if address == nil {
|
||||
logger.Warn("Invalid alias address for %s: %s", alias.Alias, alias.AliasAddress)
|
||||
continue
|
||||
}
|
||||
|
||||
// Add DNS record
|
||||
dnsProxy.AddDNSRecord(alias.Alias, address)
|
||||
newAliases = append(newAliases, alias)
|
||||
wgData.Sites[peerIndex].Aliases = append(wgData.Sites[peerIndex].Aliases, alias)
|
||||
if err := peerManager.AddAlias(addSubnetsData.SiteId, alias); err != nil {
|
||||
logger.Error("Failed to add alias %s: %v", alias.Alias, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(newAliases) > 0 {
|
||||
logger.Info("Successfully added %d alias(es) to peer %d", len(newAliases), addSubnetsData.SiteId)
|
||||
}
|
||||
})
|
||||
|
||||
// Handler for removing remote subnets from a peer
|
||||
@@ -833,90 +645,25 @@ func StartTunnel(config TunnelConfig) {
|
||||
return
|
||||
}
|
||||
|
||||
var removeSubnetsData RemovePeerData
|
||||
var removeSubnetsData peers.RemovePeerData
|
||||
if err := json.Unmarshal(jsonData, &removeSubnetsData); err != nil {
|
||||
logger.Error("Error unmarshaling remove-remote-subnets data: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Find the peer to update
|
||||
var peerIndex = -1
|
||||
for i, site := range wgData.Sites {
|
||||
if site.SiteId == removeSubnetsData.SiteId {
|
||||
peerIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if peerIndex == -1 {
|
||||
logger.Error("Peer with site ID %d not found", removeSubnetsData.SiteId)
|
||||
return
|
||||
}
|
||||
|
||||
// Create a map of subnets to remove for quick lookup
|
||||
subnetsToRemove := make(map[string]bool)
|
||||
// Remove subnets
|
||||
for _, subnet := range removeSubnetsData.RemoteSubnets {
|
||||
subnetsToRemove[subnet] = true
|
||||
}
|
||||
|
||||
// Filter out the subnets to remove
|
||||
var updatedSubnets []string
|
||||
var removedSubnets []string
|
||||
for _, subnet := range wgData.Sites[peerIndex].RemoteSubnets {
|
||||
if subnetsToRemove[subnet] {
|
||||
removedSubnets = append(removedSubnets, subnet)
|
||||
} else {
|
||||
updatedSubnets = append(updatedSubnets, subnet)
|
||||
if err := peerManager.RemoveRemoteSubnet(removeSubnetsData.SiteId, subnet); err != nil {
|
||||
logger.Error("Failed to remove allowed IP %s: %v", subnet, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(removedSubnets) == 0 {
|
||||
logger.Info("No subnets to remove for site %d (none matched)", removeSubnetsData.SiteId)
|
||||
// Still process aliases even if no subnets to remove
|
||||
} else {
|
||||
// Remove routes for the removed subnets
|
||||
if err := network.RemoveRoutes(removedSubnets); err != nil {
|
||||
logger.Error("Failed to remove routes for remote subnets: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Update the peer's remote subnets
|
||||
wgData.Sites[peerIndex].RemoteSubnets = updatedSubnets
|
||||
logger.Info("Successfully removed %d remote subnet(s) from peer %d", len(removedSubnets), removeSubnetsData.SiteId)
|
||||
}
|
||||
|
||||
// Create a map of aliases to remove for quick lookup
|
||||
aliasesToRemove := make(map[string]bool)
|
||||
// Remove aliases
|
||||
for _, alias := range removeSubnetsData.Aliases {
|
||||
aliasesToRemove[alias.Alias] = true
|
||||
}
|
||||
|
||||
// Filter out the aliases to remove
|
||||
var updatedAliases []Alias
|
||||
var removedAliases []Alias
|
||||
for _, alias := range wgData.Sites[peerIndex].Aliases {
|
||||
if aliasesToRemove[alias.Alias] {
|
||||
removedAliases = append(removedAliases, alias)
|
||||
} else {
|
||||
updatedAliases = append(updatedAliases, alias)
|
||||
if err := peerManager.RemoveAlias(removeSubnetsData.SiteId, alias.Alias); err != nil {
|
||||
logger.Error("Failed to remove alias %s: %v", alias.Alias, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(removedAliases) > 0 {
|
||||
// Remove DNS records for the removed aliases
|
||||
for _, alias := range removedAliases {
|
||||
address := net.ParseIP(alias.AliasAddress)
|
||||
if address == nil {
|
||||
logger.Warn("Invalid alias address for %s: %s", alias.Alias, alias.AliasAddress)
|
||||
continue
|
||||
}
|
||||
dnsProxy.RemoveDNSRecord(alias.Alias, address)
|
||||
}
|
||||
|
||||
// Update the peer's aliases
|
||||
wgData.Sites[peerIndex].Aliases = updatedAliases
|
||||
logger.Info("Successfully removed %d alias(es) from peer %d", len(removedAliases), removeSubnetsData.SiteId)
|
||||
}
|
||||
})
|
||||
|
||||
// Handler for updating remote subnets of a peer (remove old, add new in one operation)
|
||||
@@ -929,82 +676,41 @@ func StartTunnel(config TunnelConfig) {
|
||||
return
|
||||
}
|
||||
|
||||
var updateSubnetsData UpdatePeerData
|
||||
var updateSubnetsData peers.UpdatePeerData
|
||||
if err := json.Unmarshal(jsonData, &updateSubnetsData); err != nil {
|
||||
logger.Error("Error unmarshaling update-remote-subnets data: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Find the peer to update
|
||||
var peerIndex = -1
|
||||
for i, site := range wgData.Sites {
|
||||
if site.SiteId == updateSubnetsData.SiteId {
|
||||
peerIndex = i
|
||||
break
|
||||
// Remove old subnets
|
||||
for _, subnet := range updateSubnetsData.OldRemoteSubnets {
|
||||
if err := peerManager.RemoveRemoteSubnet(updateSubnetsData.SiteId, subnet); err != nil {
|
||||
logger.Error("Failed to remove allowed IP %s: %v", subnet, err)
|
||||
}
|
||||
}
|
||||
|
||||
if peerIndex == -1 {
|
||||
logger.Error("Peer with site ID %d not found", updateSubnetsData.SiteId)
|
||||
return
|
||||
}
|
||||
|
||||
// First, remove routes for old subnets
|
||||
if len(updateSubnetsData.OldRemoteSubnets) > 0 {
|
||||
if err := network.RemoveRoutes(updateSubnetsData.OldRemoteSubnets); err != nil {
|
||||
logger.Error("Failed to remove routes for old remote subnets: %v", err)
|
||||
return
|
||||
// Add new subnets
|
||||
for _, subnet := range updateSubnetsData.NewRemoteSubnets {
|
||||
if err := peerManager.AddRemoteSubnet(updateSubnetsData.SiteId, subnet); err != nil {
|
||||
logger.Error("Failed to add allowed IP %s: %v", subnet, err)
|
||||
}
|
||||
logger.Info("Removed %d old remote subnet(s) from peer %d", len(updateSubnetsData.OldRemoteSubnets), updateSubnetsData.SiteId)
|
||||
}
|
||||
|
||||
// Then, add routes for new subnets
|
||||
if len(updateSubnetsData.NewRemoteSubnets) > 0 {
|
||||
if err := network.AddRoutes(updateSubnetsData.NewRemoteSubnets, interfaceName); err != nil {
|
||||
logger.Error("Failed to add routes for new remote subnets: %v", err)
|
||||
// Attempt to rollback by re-adding old routes
|
||||
if rollbackErr := network.AddRoutes(updateSubnetsData.OldRemoteSubnets, interfaceName); rollbackErr != nil {
|
||||
logger.Error("Failed to rollback old routes: %v", rollbackErr)
|
||||
}
|
||||
return
|
||||
// Remove old aliases
|
||||
for _, alias := range updateSubnetsData.OldAliases {
|
||||
if err := peerManager.RemoveAlias(updateSubnetsData.SiteId, alias.Alias); err != nil {
|
||||
logger.Error("Failed to remove alias %s: %v", alias.Alias, err)
|
||||
}
|
||||
logger.Info("Added %d new remote subnet(s) to peer %d", len(updateSubnetsData.NewRemoteSubnets), updateSubnetsData.SiteId)
|
||||
}
|
||||
|
||||
// Finally, update the peer's remote subnets in wgData
|
||||
wgData.Sites[peerIndex].RemoteSubnets = updateSubnetsData.NewRemoteSubnets
|
||||
|
||||
logger.Info("Successfully updated remote subnets for peer %d (removed %d, added %d)",
|
||||
updateSubnetsData.SiteId, len(updateSubnetsData.OldRemoteSubnets), len(updateSubnetsData.NewRemoteSubnets))
|
||||
|
||||
// Remove DNS records for old aliases
|
||||
if len(updateSubnetsData.OldAliases) > 0 {
|
||||
for _, alias := range updateSubnetsData.OldAliases {
|
||||
address := net.ParseIP(alias.AliasAddress)
|
||||
if address == nil {
|
||||
logger.Warn("Invalid old alias address for %s: %s", alias.Alias, alias.AliasAddress)
|
||||
continue
|
||||
}
|
||||
dnsProxy.RemoveDNSRecord(alias.Alias, address)
|
||||
// Add new aliases
|
||||
for _, alias := range updateSubnetsData.NewAliases {
|
||||
if err := peerManager.AddAlias(updateSubnetsData.SiteId, alias); err != nil {
|
||||
logger.Error("Failed to add alias %s: %v", alias.Alias, err)
|
||||
}
|
||||
logger.Info("Removed %d old alias(es) from peer %d", len(updateSubnetsData.OldAliases), updateSubnetsData.SiteId)
|
||||
}
|
||||
|
||||
// Add DNS records for new aliases
|
||||
if len(updateSubnetsData.NewAliases) > 0 {
|
||||
for _, alias := range updateSubnetsData.NewAliases {
|
||||
address := net.ParseIP(alias.AliasAddress)
|
||||
if address == nil {
|
||||
logger.Warn("Invalid new alias address for %s: %s", alias.Alias, alias.AliasAddress)
|
||||
continue
|
||||
}
|
||||
dnsProxy.AddDNSRecord(alias.Alias, address)
|
||||
}
|
||||
logger.Info("Added %d new alias(es) to peer %d", len(updateSubnetsData.NewAliases), updateSubnetsData.SiteId)
|
||||
}
|
||||
|
||||
// Update the peer's aliases in wgData
|
||||
wgData.Sites[peerIndex].Aliases = updateSubnetsData.NewAliases
|
||||
logger.Info("Successfully updated remote subnets and aliases for peer %d", updateSubnetsData.SiteId)
|
||||
})
|
||||
|
||||
olm.RegisterHandler("olm/wg/peer/relay", func(msg websocket.WSMessage) {
|
||||
@@ -1016,7 +722,7 @@ func StartTunnel(config TunnelConfig) {
|
||||
return
|
||||
}
|
||||
|
||||
var relayData RelayPeerData
|
||||
var relayData peers.RelayPeerData
|
||||
if err := json.Unmarshal(jsonData, &relayData); err != nil {
|
||||
logger.Error("Error unmarshaling relay data: %v", err)
|
||||
return
|
||||
|
||||
120
olm/peer.go
120
olm/peer.go
@@ -1,120 +0,0 @@
|
||||
package olm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/fosrl/newt/logger"
|
||||
"github.com/fosrl/newt/util"
|
||||
"github.com/fosrl/olm/peermonitor"
|
||||
"golang.zx2c4.com/wireguard/device"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
// ConfigurePeer sets up or updates a peer within the WireGuard device
|
||||
func ConfigurePeer(dev *device.Device, siteConfig SiteConfig, privateKey wgtypes.Key, endpoint string) error {
|
||||
siteHost, err := util.ResolveDomain(formatEndpoint(siteConfig.Endpoint))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to resolve endpoint for site %d: %v", siteConfig.SiteId, err)
|
||||
}
|
||||
|
||||
// Split off the CIDR of the server IP which is just a string and add /32 for the allowed IP
|
||||
allowedIp := strings.Split(siteConfig.ServerIP, "/")
|
||||
if len(allowedIp) > 1 {
|
||||
allowedIp[1] = "32"
|
||||
} else {
|
||||
allowedIp = append(allowedIp, "32")
|
||||
}
|
||||
allowedIpStr := strings.Join(allowedIp, "/")
|
||||
|
||||
// Collect all allowed IPs in a slice
|
||||
var allowedIPs []string
|
||||
allowedIPs = append(allowedIPs, allowedIpStr)
|
||||
|
||||
// If we have anything in remoteSubnets, add those as well
|
||||
if len(siteConfig.RemoteSubnets) > 0 {
|
||||
// Add each remote subnet
|
||||
for _, subnet := range siteConfig.RemoteSubnets {
|
||||
subnet = strings.TrimSpace(subnet)
|
||||
if subnet != "" {
|
||||
allowedIPs = append(allowedIPs, subnet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Construct WireGuard config for this peer
|
||||
var configBuilder strings.Builder
|
||||
configBuilder.WriteString(fmt.Sprintf("private_key=%s\n", util.FixKey(privateKey.String())))
|
||||
configBuilder.WriteString(fmt.Sprintf("public_key=%s\n", util.FixKey(siteConfig.PublicKey)))
|
||||
|
||||
// Add each allowed IP separately
|
||||
for _, allowedIP := range allowedIPs {
|
||||
configBuilder.WriteString(fmt.Sprintf("allowed_ip=%s\n", allowedIP))
|
||||
}
|
||||
|
||||
configBuilder.WriteString(fmt.Sprintf("endpoint=%s\n", siteHost))
|
||||
configBuilder.WriteString("persistent_keepalive_interval=1\n")
|
||||
|
||||
config := configBuilder.String()
|
||||
logger.Debug("Configuring peer with config: %s", config)
|
||||
|
||||
err = dev.IpcSet(config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to configure WireGuard peer: %v", err)
|
||||
}
|
||||
|
||||
// Set up peer monitoring
|
||||
if peerMonitor != nil {
|
||||
monitorAddress := strings.Split(siteConfig.ServerIP, "/")[0]
|
||||
monitorPeer := net.JoinHostPort(monitorAddress, strconv.Itoa(int(siteConfig.ServerPort+1))) // +1 for the monitor port
|
||||
logger.Debug("Setting up peer monitor for site %d at %s", siteConfig.SiteId, monitorPeer)
|
||||
logger.Debug("Resolving primary relay %s for peer", endpoint)
|
||||
primaryRelay, err := util.ResolveDomain(endpoint) // Using global endpoint variable
|
||||
if err != nil {
|
||||
logger.Warn("Failed to resolve primary relay endpoint for peer: %v", err)
|
||||
}
|
||||
|
||||
wgConfig := &peermonitor.WireGuardConfig{
|
||||
SiteID: siteConfig.SiteId,
|
||||
PublicKey: util.FixKey(siteConfig.PublicKey),
|
||||
ServerIP: strings.Split(siteConfig.ServerIP, "/")[0],
|
||||
Endpoint: siteConfig.Endpoint,
|
||||
PrimaryRelay: primaryRelay,
|
||||
}
|
||||
|
||||
err = peerMonitor.AddPeer(siteConfig.SiteId, monitorPeer, wgConfig)
|
||||
if err != nil {
|
||||
logger.Warn("Failed to setup monitoring for site %d: %v", siteConfig.SiteId, err)
|
||||
} else {
|
||||
logger.Info("Started monitoring for site %d at %s", siteConfig.SiteId, monitorPeer)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemovePeer removes a peer from the WireGuard device
|
||||
func RemovePeer(dev *device.Device, siteId int, publicKey string) error {
|
||||
// Construct WireGuard config to remove the peer
|
||||
var configBuilder strings.Builder
|
||||
configBuilder.WriteString(fmt.Sprintf("public_key=%s\n", util.FixKey(publicKey)))
|
||||
configBuilder.WriteString("remove=true\n")
|
||||
|
||||
config := configBuilder.String()
|
||||
logger.Debug("Removing peer with config: %s", config)
|
||||
|
||||
err := dev.IpcSet(config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to remove WireGuard peer: %v", err)
|
||||
}
|
||||
|
||||
// Stop monitoring this peer
|
||||
if peerMonitor != nil {
|
||||
peerMonitor.RemovePeer(siteId)
|
||||
logger.Info("Stopped monitoring for site %d", siteId)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
67
olm/types.go
67
olm/types.go
@@ -1,11 +1,15 @@
|
||||
package olm
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/fosrl/olm/peers"
|
||||
)
|
||||
|
||||
type WgData struct {
|
||||
Sites []SiteConfig `json:"sites"`
|
||||
TunnelIP string `json:"tunnelIP"`
|
||||
UtilitySubnet string `json:"utilitySubnet"` // this is for things like the DNS server, and alias addresses
|
||||
Sites []peers.SiteConfig `json:"sites"`
|
||||
TunnelIP string `json:"tunnelIP"`
|
||||
UtilitySubnet string `json:"utilitySubnet"` // this is for things like the DNS server, and alias addresses
|
||||
}
|
||||
|
||||
type HolePunchMessage struct {
|
||||
@@ -27,61 +31,6 @@ type EncryptedHolePunchMessage struct {
|
||||
Ciphertext []byte `json:"ciphertext"`
|
||||
}
|
||||
|
||||
// PeerAction represents a request to add, update, or remove a peer
|
||||
type PeerAction struct {
|
||||
Action string `json:"action"` // "add", "update", or "remove"
|
||||
SiteInfo SiteConfig `json:"siteInfo"` // Site configuration information
|
||||
}
|
||||
|
||||
// UpdatePeerData represents the data needed to update a peer
|
||||
type SiteConfig struct {
|
||||
SiteId int `json:"siteId"`
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
PublicKey string `json:"publicKey,omitempty"`
|
||||
ServerIP string `json:"serverIP,omitempty"`
|
||||
ServerPort uint16 `json:"serverPort,omitempty"`
|
||||
RemoteSubnets []string `json:"remoteSubnets,omitempty"` // optional, array of subnets that this site can access
|
||||
Aliases []Alias `json:"aliases,omitempty"` // optional, array of alias configurations
|
||||
}
|
||||
|
||||
type Alias struct {
|
||||
Alias string `json:"alias"` // the alias name
|
||||
AliasAddress string `json:"aliasAddress"` // the alias IP address
|
||||
}
|
||||
|
||||
// RemovePeer represents the data needed to remove a peer
|
||||
type PeerRemove struct {
|
||||
SiteId int `json:"siteId"`
|
||||
}
|
||||
|
||||
type RelayPeerData struct {
|
||||
SiteId int `json:"siteId"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
}
|
||||
|
||||
// PeerAdd represents the data needed to add remote subnets to a peer
|
||||
type PeerAdd struct {
|
||||
SiteId int `json:"siteId"`
|
||||
RemoteSubnets []string `json:"remoteSubnets"` // subnets to add
|
||||
Aliases []Alias `json:"aliases,omitempty"` // aliases to add
|
||||
}
|
||||
|
||||
// RemovePeerData represents the data needed to remove remote subnets from a peer
|
||||
type RemovePeerData struct {
|
||||
SiteId int `json:"siteId"`
|
||||
RemoteSubnets []string `json:"remoteSubnets"` // subnets to remove
|
||||
Aliases []Alias `json:"aliases,omitempty"` // aliases to remove
|
||||
}
|
||||
|
||||
type UpdatePeerData struct {
|
||||
SiteId int `json:"siteId"`
|
||||
OldRemoteSubnets []string `json:"oldRemoteSubnets"` // old list of remote subnets
|
||||
NewRemoteSubnets []string `json:"newRemoteSubnets"` // new list of remote subnets
|
||||
OldAliases []Alias `json:"oldAliases,omitempty"` // old list of aliases
|
||||
NewAliases []Alias `json:"newAliases,omitempty"` // new list of aliases
|
||||
}
|
||||
|
||||
type GlobalConfig struct {
|
||||
// Logging
|
||||
LogLevel string
|
||||
|
||||
Reference in New Issue
Block a user