From 631b1bf12ece0d5e3909d24e7762be12f830b2ab Mon Sep 17 00:00:00 2001 From: Ruakij Date: Wed, 12 Apr 2023 19:50:41 +0200 Subject: [PATCH 1/4] Fix spelling --- cmd/app/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/app/main.go b/cmd/app/main.go index cde099d..067248a 100644 --- a/cmd/app/main.go +++ b/cmd/app/main.go @@ -53,7 +53,7 @@ func main() { logger.Error.Fatalf("Couldn't parse RECHECK_INTERVAL '%s': %s", checkIntervalStr, err) } - // Get the IPv4 address of the interface + // Get the IPv4 addresses of the interface addrs, err := netlink.AddrList(netInterface, netlink.FAMILY_V4) if err != nil { logger.Error.Fatal(err) From ba6342a71fb3454413855670c234a0a6450381fe Mon Sep 17 00:00:00 2001 From: Ruakij Date: Wed, 12 Apr 2023 19:57:57 +0200 Subject: [PATCH 2/4] Move IP-conversion into loop --- cmd/app/main.go | 75 +++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/cmd/app/main.go b/cmd/app/main.go index 067248a..8e28445 100644 --- a/cmd/app/main.go +++ b/cmd/app/main.go @@ -53,53 +53,54 @@ func main() { logger.Error.Fatalf("Couldn't parse RECHECK_INTERVAL '%s': %s", checkIntervalStr, err) } - // Get the IPv4 addresses of the interface - addrs, err := netlink.AddrList(netInterface, netlink.FAMILY_V4) + // Create a WireGuard client + client, err := wgctrl.New() if err != nil { logger.Error.Fatal(err) } - processedCount := 0 - filteredCount := 0 - for _, addr := range addrs { - // Check filter - if addr.String()[:len(filterPrefix)] != filterPrefix { - filteredCount++ - continue - } + defer client.Close() - // Add the IPv6 address to the interface - ipv6Str := *convertIPv4ToIPv6(&ipv6Format, addr.IPNet) - ipv6, err := netlink.ParseAddr(ipv6Str) + // Loop indefinitely + for { + // Get the IPv4 addresses of the interface + addrs, err := netlink.AddrList(netInterface, netlink.FAMILY_V4) if err != nil { - logger.Warn.Printf("failed parsing converted %s -> %s : %s", addr.IPNet.String(), ipv6Str, err) - continue + logger.Error.Fatal(err) } + processedCount := 0 + filteredCount := 0 + for _, addr := range addrs { + // Check filter + if addr.String()[:len(filterPrefix)] != filterPrefix { + filteredCount++ + continue + } - logger.Info.Printf("Adding converted %s -> %s to interface", addr.IPNet.String(), ipv6Str) - err = netlink.AddrAdd(netInterface, ipv6) - if err != nil { - switch { - case os.IsExist(err): - logger.Warn.Println("Address is already set on interface") - default: - logger.Warn.Printf("Failed to set address on interface: %v", err) + // Add the IPv6 address to the interface + ipv6Str := *convertIPv4ToIPv6(&ipv6Format, addr.IPNet) + ipv6, err := netlink.ParseAddr(ipv6Str) + if err != nil { + logger.Warn.Printf("failed parsing converted %s -> %s : %s", addr.IPNet.String(), ipv6Str, err) + continue } - } - processedCount++ - } - if(processedCount != len(addrs)) { - logger.Warn.Printf("Not all Interface-Addresses were processed. Summary: %d processed, %d filtered, %d failed", processedCount, filteredCount, len(addrs)-processedCount-filteredCount) - } - // Create a WireGuard client - client, err := wgctrl.New() - if err != nil { - logger.Error.Fatal(err) - } - defer client.Close() + logger.Info.Printf("Adding converted %s -> %s to interface", addr.IPNet.String(), ipv6Str) + err = netlink.AddrAdd(netInterface, ipv6) + if err != nil { + switch { + case os.IsExist(err): + logger.Warn.Println("Address is already set on interface") + default: + logger.Warn.Printf("Failed to set address on interface: %v", err) + } + } + processedCount++ + } + if processedCount != len(addrs) { + logger.Warn.Printf("Not all Interface-Addresses were processed. Summary: %d processed, %d filtered, %d failed", processedCount, filteredCount, len(addrs)-processedCount-filteredCount) + } - // Loop indefinitely - for { + // Get the WireGuard peers on the interface wgDevice, err := client.Device(iface) if err != nil { From 0d6564448ac3f6cc65ff65318597728ffd07e807 Mon Sep 17 00:00:00 2001 From: Ruakij Date: Wed, 12 Apr 2023 19:58:39 +0200 Subject: [PATCH 3/4] Make faulture to add address fatal --- cmd/app/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/app/main.go b/cmd/app/main.go index 8e28445..2950788 100644 --- a/cmd/app/main.go +++ b/cmd/app/main.go @@ -91,7 +91,7 @@ func main() { case os.IsExist(err): logger.Warn.Println("Address is already set on interface") default: - logger.Warn.Printf("Failed to set address on interface: %v", err) + logger.Error.Fatalf("Failed to set address on interface: %v", err) } } processedCount++ @@ -100,7 +100,7 @@ func main() { logger.Warn.Printf("Not all Interface-Addresses were processed. Summary: %d processed, %d filtered, %d failed", processedCount, filteredCount, len(addrs)-processedCount-filteredCount) } - + // Get the WireGuard peers on the interface wgDevice, err := client.Device(iface) if err != nil { From 9b0ed5a51b7759a6239ba3fafeaa743c2e5a4628 Mon Sep 17 00:00:00 2001 From: Ruakij Date: Wed, 12 Apr 2023 19:58:51 +0200 Subject: [PATCH 4/4] go-format --- cmd/app/main.go | 265 ++++++++++++++++++++++++------------------------ 1 file changed, 132 insertions(+), 133 deletions(-) diff --git a/cmd/app/main.go b/cmd/app/main.go index 2950788..4baccd2 100644 --- a/cmd/app/main.go +++ b/cmd/app/main.go @@ -7,8 +7,8 @@ import ( "time" envChecks "git.ruekov.eu/ruakij/routingtabletowg/lib/environmentchecks" - "git.ruekov.eu/ruakij/routingtabletowg/lib/wgchecks/netchecks" - + "git.ruekov.eu/ruakij/routingtabletowg/lib/wgchecks/netchecks" + "github.com/vishvananda/netlink" "golang.zx2c4.com/wireguard/wgctrl" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" @@ -18,153 +18,152 @@ var envRequired = []string{ "INTERFACE", } var envDefaults = map[string]string{ - "IPV6_FORMAT": "fc12::%02x%02x:%02x%02x/%d", - "FILTER_PREFIX": "100.100", - "RECHECK_INTERVAL": "5m", + "IPV6_FORMAT": "fc12::%02x%02x:%02x%02x/%d", + "FILTER_PREFIX": "100.100", + "RECHECK_INTERVAL": "5m", } func main() { // Environment-vars err := envChecks.HandleRequired(envRequired) - if(err != nil){ + if err != nil { logger.Error.Fatal(err) } envChecks.HandleDefaults(envDefaults) - // Get the network interface object + // Get the network interface object iface := os.Getenv("INTERFACE") - netInterface, err := netlink.LinkByName(iface) - if err != nil { - logger.Error.Fatal(err) - } - - ipv6Format := os.Getenv("IPV6_FORMAT") - ipv6TestStr := *convertIPv4ToIPv6(&ipv6Format, &net.IPNet{IP: net.IPv4(1,1,1,1), Mask: net.CIDRMask(24, net.IPv4len)}) - _, err = netlink.ParseIPNet(ipv6TestStr) - if err != nil { - logger.Error.Fatalf("IPV6_FORMAT is invalid: %s", err) - } - - filterPrefix := os.Getenv("FILTER_PREFIX") - - checkIntervalStr := os.Getenv("RECHECK_INTERVAL") - checkInterval, err := time.ParseDuration(checkIntervalStr) + netInterface, err := netlink.LinkByName(iface) + if err != nil { + logger.Error.Fatal(err) + } + + ipv6Format := os.Getenv("IPV6_FORMAT") + ipv6TestStr := *convertIPv4ToIPv6(&ipv6Format, &net.IPNet{IP: net.IPv4(1, 1, 1, 1), Mask: net.CIDRMask(24, net.IPv4len)}) + _, err = netlink.ParseIPNet(ipv6TestStr) + if err != nil { + logger.Error.Fatalf("IPV6_FORMAT is invalid: %s", err) + } + + filterPrefix := os.Getenv("FILTER_PREFIX") + + checkIntervalStr := os.Getenv("RECHECK_INTERVAL") + checkInterval, err := time.ParseDuration(checkIntervalStr) if err != nil { logger.Error.Fatalf("Couldn't parse RECHECK_INTERVAL '%s': %s", checkIntervalStr, err) } - // Create a WireGuard client - client, err := wgctrl.New() - if err != nil { - logger.Error.Fatal(err) - } - defer client.Close() - - // Loop indefinitely - for { - // Get the IPv4 addresses of the interface - addrs, err := netlink.AddrList(netInterface, netlink.FAMILY_V4) - if err != nil { - logger.Error.Fatal(err) - } - processedCount := 0 - filteredCount := 0 - for _, addr := range addrs { - // Check filter - if addr.String()[:len(filterPrefix)] != filterPrefix { - filteredCount++ - continue - } - - // Add the IPv6 address to the interface - ipv6Str := *convertIPv4ToIPv6(&ipv6Format, addr.IPNet) - ipv6, err := netlink.ParseAddr(ipv6Str) - if err != nil { - logger.Warn.Printf("failed parsing converted %s -> %s : %s", addr.IPNet.String(), ipv6Str, err) - continue - } - - logger.Info.Printf("Adding converted %s -> %s to interface", addr.IPNet.String(), ipv6Str) - err = netlink.AddrAdd(netInterface, ipv6) - if err != nil { - switch { - case os.IsExist(err): - logger.Warn.Println("Address is already set on interface") - default: - logger.Error.Fatalf("Failed to set address on interface: %v", err) - } - } - processedCount++ - } - if processedCount != len(addrs) { - logger.Warn.Printf("Not all Interface-Addresses were processed. Summary: %d processed, %d filtered, %d failed", processedCount, filteredCount, len(addrs)-processedCount-filteredCount) - } - - - // Get the WireGuard peers on the interface - wgDevice, err := client.Device(iface) - if err != nil { - logger.Error.Fatalf("getting WireGuard device from interface '%s' failed: %s", iface, err) - } + // Create a WireGuard client + client, err := wgctrl.New() + if err != nil { + logger.Error.Fatal(err) + } + defer client.Close() + + // Loop indefinitely + for { + // Get the IPv4 addresses of the interface + addrs, err := netlink.AddrList(netInterface, netlink.FAMILY_V4) + if err != nil { + logger.Error.Fatal(err) + } + processedCount := 0 + filteredCount := 0 + for _, addr := range addrs { + // Check filter + if addr.String()[:len(filterPrefix)] != filterPrefix { + filteredCount++ + continue + } + + // Add the IPv6 address to the interface + ipv6Str := *convertIPv4ToIPv6(&ipv6Format, addr.IPNet) + ipv6, err := netlink.ParseAddr(ipv6Str) + if err != nil { + logger.Warn.Printf("failed parsing converted %s -> %s : %s", addr.IPNet.String(), ipv6Str, err) + continue + } + + logger.Info.Printf("Adding converted %s -> %s to interface", addr.IPNet.String(), ipv6Str) + err = netlink.AddrAdd(netInterface, ipv6) + if err != nil { + switch { + case os.IsExist(err): + logger.Warn.Println("Address is already set on interface") + default: + logger.Error.Fatalf("Failed to set address on interface: %v", err) + } + } + processedCount++ + } + if processedCount != len(addrs) { + logger.Warn.Printf("Not all Interface-Addresses were processed. Summary: %d processed, %d filtered, %d failed", processedCount, filteredCount, len(addrs)-processedCount-filteredCount) + } + + // Get the WireGuard peers on the interface + wgDevice, err := client.Device(iface) + if err != nil { + logger.Error.Fatalf("getting WireGuard device from interface '%s' failed: %s", iface, err) + } var wgConfig wgtypes.Config - wgConfig.Peers = make([]wgtypes.PeerConfig, 0, len(wgDevice.Peers)) - - for _, peer := range wgDevice.Peers { - // Create slice for 1 expected addition - var addAllowedIPs = make([]net.IPNet, 0, 1) - - // Loop through the allowed-ips and add the ones starting with 100.100 - for _, allowedIP := range peer.AllowedIPs { - if allowedIP.String()[:len(filterPrefix)] == filterPrefix { - // Convert the IPv4 allowed-ip to an IPv6 address - ipv6Str := *convertIPv4ToIPv6(&ipv6Format, &allowedIP) - logger.Info.Printf("AllowedIP %s -> %s to peer %s", allowedIP.String(), ipv6Str, peer.PublicKey) - ipv6, err := netlink.ParseIPNet(ipv6Str) - if err != nil { - logger.Warn.Printf("Couldnt parse IPv6 address %s of peer %s: %s", ipv6Str, peer.PublicKey, err) - continue - } - - // Check if already set - if i, _ := netchecks.IPNetIndexByIPNet(&peer.AllowedIPs, ipv6); i != -1 { - continue - } - - // Add the IPv6 allowed-ip to the peer - addAllowedIPs = append(addAllowedIPs, *ipv6) - } - } - - if(len(addAllowedIPs) > 0){ - // Create peer-config - peerConfig := wgtypes.PeerConfig{ - PublicKey: peer.PublicKey, - AllowedIPs: append(peer.AllowedIPs, addAllowedIPs...), - } - - // Add entry - wgConfig.Peers = append(wgConfig.Peers, peerConfig) - } - } - - if(len(wgConfig.Peers) == 0){ - logger.Info.Println("No changes, skipping") - } else { - err = client.ConfigureDevice(iface, wgConfig) - if(err != nil){ - logger.Error.Fatalf("Error configuring wg-device '%s': %s", iface, err) - } - } - - // Sleep for x seconds before running the loop again - time.Sleep(checkInterval) - } + wgConfig.Peers = make([]wgtypes.PeerConfig, 0, len(wgDevice.Peers)) + + for _, peer := range wgDevice.Peers { + // Create slice for 1 expected addition + var addAllowedIPs = make([]net.IPNet, 0, 1) + + // Loop through the allowed-ips and add the ones starting with 100.100 + for _, allowedIP := range peer.AllowedIPs { + if allowedIP.String()[:len(filterPrefix)] == filterPrefix { + // Convert the IPv4 allowed-ip to an IPv6 address + ipv6Str := *convertIPv4ToIPv6(&ipv6Format, &allowedIP) + logger.Info.Printf("AllowedIP %s -> %s to peer %s", allowedIP.String(), ipv6Str, peer.PublicKey) + ipv6, err := netlink.ParseIPNet(ipv6Str) + if err != nil { + logger.Warn.Printf("Couldnt parse IPv6 address %s of peer %s: %s", ipv6Str, peer.PublicKey, err) + continue + } + + // Check if already set + if i, _ := netchecks.IPNetIndexByIPNet(&peer.AllowedIPs, ipv6); i != -1 { + continue + } + + // Add the IPv6 allowed-ip to the peer + addAllowedIPs = append(addAllowedIPs, *ipv6) + } + } + + if len(addAllowedIPs) > 0 { + // Create peer-config + peerConfig := wgtypes.PeerConfig{ + PublicKey: peer.PublicKey, + AllowedIPs: append(peer.AllowedIPs, addAllowedIPs...), + } + + // Add entry + wgConfig.Peers = append(wgConfig.Peers, peerConfig) + } + } + + if len(wgConfig.Peers) == 0 { + logger.Info.Println("No changes, skipping") + } else { + err = client.ConfigureDevice(iface, wgConfig) + if err != nil { + logger.Error.Fatalf("Error configuring wg-device '%s': %s", iface, err) + } + } + + // Sleep for x seconds before running the loop again + time.Sleep(checkInterval) + } } -func convertIPv4ToIPv6(ipv6Format *string, ipv4 *net.IPNet) (*string) { - CIDR, _ := ipv4.Mask.Size() - // Run format - ipv6Str := fmt.Sprintf(*ipv6Format, (*ipv4).IP[0], (*ipv4).IP[1], (*ipv4).IP[2], (*ipv4).IP[3], net.IPv6len*8-(net.IPv4len*8-CIDR)) - return &ipv6Str +func convertIPv4ToIPv6(ipv6Format *string, ipv4 *net.IPNet) *string { + CIDR, _ := ipv4.Mask.Size() + // Run format + ipv6Str := fmt.Sprintf(*ipv6Format, (*ipv4).IP[0], (*ipv4).IP[1], (*ipv4).IP[2], (*ipv4).IP[3], net.IPv6len*8-(net.IPv4len*8-CIDR)) + return &ipv6Str }