From 0942fb132f694b08701d105c8d5b29ab8db144bc Mon Sep 17 00:00:00 2001 From: Steven Polley Date: Sat, 20 Apr 2024 19:25:15 -0600 Subject: [PATCH] QoL feature - select best interface on current system When generating a default config instead of using a canned value like "eth0", hypd will isntead look at what interfaces the system has and make a best guess based on progressively narrowing filters. --- hypd/README.md | 4 +- hypd/configuration/configuration.go | 10 +++- hypd/configuration/defaultNIC.go | 81 +++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 hypd/configuration/defaultNIC.go diff --git a/hypd/README.md b/hypd/README.md index 1fc6989..f119a92 100644 --- a/hypd/README.md +++ b/hypd/README.md @@ -33,7 +33,9 @@ Running hypd requires specifying a configuration file. It's recommended you gen ./hypd generate defaultconfig > hypd.conf ``` -Make sure you take the time to review the hypd.conf file and edit it to your liking, this is the most important step. +Make sure you take the time to review the hypd.conf file and edit it to your liking, this is the most important step. Make sure the network interface is correct, hypd will make an educated guess based on the interfaces your system has. + +If you have complex requirements, you can make the successAction/timeoutAction an external shell script. If you want to disable the timeoutAction, you can set timeoutSeconds to 0. Once you have set your config file, you can finally run hypd. diff --git a/hypd/configuration/configuration.go b/hypd/configuration/configuration.go index ee9a81a..1003581 100644 --- a/hypd/configuration/configuration.go +++ b/hypd/configuration/configuration.go @@ -57,8 +57,16 @@ func LoadConfiguration(configFilePath string) (*HypdConfiguration, error) { } func DefaultConfig() *HypdConfiguration { + var ifaceString string + iface, err := getDefaultNIC() + if err == nil { + ifaceString = iface.Name + } else { + ifaceString = "enp0s3" // fallback to fixed value + } + return &HypdConfiguration{ - NetworkInterface: "enp0s3", + NetworkInterface: ifaceString, PreSharedKeyDirectory: "./secrets/", SuccessAction: "iptables -A INPUT -p tcp -s %s --dport 22 -j ACCEPT", TimeoutSeconds: 1440, diff --git a/hypd/configuration/defaultNIC.go b/hypd/configuration/defaultNIC.go new file mode 100644 index 0000000..c1311eb --- /dev/null +++ b/hypd/configuration/defaultNIC.go @@ -0,0 +1,81 @@ +package configuration + +import ( + "fmt" + "net" +) + +// QoL feature to try and detect the best NIC for hyp +func getDefaultNIC() (*net.Interface, error) { + ifaces, err := net.Interfaces() + if err != nil { + return nil, fmt.Errorf("failed to get network interfaces on this system: %v", err) + } + if len(ifaces) < 1 { + return nil, fmt.Errorf("this system has no network interfaces: %v", err) + } + + // Just pick one to start + selectedIface := ifaces[0] + filteredIfaces := make([]net.Interface, 0) + + // Check for ethernet addresses + for _, iface := range ifaces { + if len(iface.HardwareAddr) == 6 { + selectedIface = iface + filteredIfaces = append(filteredIfaces, iface) + } + } + ifaces = filteredIfaces + filteredIfaces = make([]net.Interface, 0) + + // Check for interfaces that are up and not loopbacks + for _, iface := range ifaces { + if iface.Flags&net.FlagUp != 0 && iface.Flags&net.FlagRunning != 0 && iface.Flags&net.FlagLoopback == 0 { + selectedIface = iface + filteredIfaces = append(filteredIfaces, iface) + } + } + ifaces = filteredIfaces + filteredIfaces = make([]net.Interface, 0) + + // Check for interfaces that have IPv4 addresses assigned + for _, iface := range ifaces { + addresses, err := iface.Addrs() + if err != nil { + continue + } + for _, address := range addresses { + ip, _, err := net.ParseCIDR(address.String()) + if err != nil { + continue + } + if ip.To4() != nil { + selectedIface = iface + filteredIfaces = append(filteredIfaces, iface) + } + } + } + ifaces = filteredIfaces + filteredIfaces = nil + + // Check for interfaces that have non RFC1918 addresses assigned + for _, iface := range ifaces { + addresses, err := iface.Addrs() + if err != nil { + continue + } + for _, address := range addresses { + ip, _, err := net.ParseCIDR(address.String()) + if err != nil { + continue + } + if !ip.IsPrivate() { + selectedIface = iface + + } + } + } + + return &selectedIface, nil // TBD +}