diff --git a/packages/networking/hyprspace/README.md b/packages/networking/hyprspace/README.md index 9edde1e..2bf06af 100644 --- a/packages/networking/hyprspace/README.md +++ b/packages/networking/hyprspace/README.md @@ -187,6 +187,49 @@ sudo hyprspace down hs1 WireGuard is a registered trademark of Jason A. Donenfeld. + +## Routes + +### Prepare each route node: + +``` +# sysctl -n net.ipv4.ip_forward +0 +# sysctl -w net.ipv4.ip_forward=1 +iptables -t nat -A POSTROUTING -s /24 -o eth0 -j MASQUERADE +iptables -A FORWARD 1 -i -o -j ACCEPT +iptables -A FORWARD 1 -i -o -j ACCEPT + +``` +Determine gateway router: +``` +# curl ifconfg.me + +``` + +### Configure client: +Config hyprspace yaml configuration file: +``` +interface: + ... +peers: + ID: ... + ... +routes: + 192.168.3.0/24: + ip: 10.0.0.3 + 0.0.0.0/0: + ip: 10.0.0.1 + +``` +Prepare routes +``` +One for each route: +# ip route add via + +And all traffic for hyprspace tun +# ip route add default dev metric 1 +``` ## License Copyright 2021-2022 Alec Scott diff --git a/packages/networking/hyprspace/cli/up.go b/packages/networking/hyprspace/cli/up.go index b8f8c69..b3788b1 100644 --- a/packages/networking/hyprspace/cli/up.go +++ b/packages/networking/hyprspace/cli/up.go @@ -180,6 +180,10 @@ func UpRun(r *cmd.Root, c *cmd.Sub) { // Initialize active streams map and packet byte array. activeStreams = make(map[string]network.Stream) var packet = make([]byte, 1420) + ip, _, err := net.ParseCIDR(cfg.Interface.Address) + if err != nil { + checkErr(errors.New("unable to parse address")) + } for { // Read in a packet from the tun device. plen, err := tunDev.Iface.Read(packet) @@ -188,8 +192,21 @@ func UpRun(r *cmd.Root, c *cmd.Sub) { continue } - // Decode the packet's destination address - dst := net.IPv4(packet[16], packet[17], packet[18], packet[19]).String() + dstIP := net.IPv4(packet[16], packet[17], packet[18], packet[19]) + dst := dstIP.String() + + // Check route table for destination address. + for route, _ := range cfg.Routes { + _, network, _ := net.ParseCIDR(route) + if network.Contains(dstIP) { + src := net.IPv4(packet[12], packet[13], packet[14], packet[15]) + _, ok := peerTable[dst] + // Only rewrite if initiator is us or receiver is not a known peer + if src.Equal(ip) && !ok { + dst = cfg.Routes[route].IP + } + } + } // Check if we already have an open connection to the destination peer. stream, ok := activeStreams[dst] diff --git a/packages/networking/hyprspace/config/config.go b/packages/networking/hyprspace/config/config.go index f0450db..3ebfdec 100644 --- a/packages/networking/hyprspace/config/config.go +++ b/packages/networking/hyprspace/config/config.go @@ -10,9 +10,10 @@ import ( // Config is the main Configuration Struct for Hyprspace. type Config struct { - Path string `yaml:"path,omitempty"` - Interface Interface `yaml:"interface"` - Peers map[string]Peer `yaml:"peers"` + Path string `yaml:"path,omitempty"` + Interface Interface `yaml:"interface"` + Peers map[string]Peer `yaml:"peers"` + Routes map[string]Route `yaml:"routes"` } // Interface defines all of the fields that a local node needs to know about itself! @@ -29,6 +30,10 @@ type Peer struct { ID string `yaml:"id"` } +type Route struct { + IP string `yaml:"ip"` +} + // Read initializes a config from a file. func Read(path string) (*Config, error) { in, err := os.ReadFile(path) @@ -55,6 +60,17 @@ func Read(path string) (*Config, error) { for ip := range result.Peers { if net.ParseIP(ip).String() == "" { return nil, fmt.Errorf("%s is not a valid ip address", ip) + } else { + fmt.Printf("[+] Assign this ip: %s to node: %s.\n", ip, result.Peers[ip].ID) + } + } + + for route := range result.Routes { + _, _, err := net.ParseCIDR(route) + if err != nil { + return nil, fmt.Errorf("%s is not a valid route", route) + } else { + fmt.Printf("[+] Assign route %s via %s.\n", route, result.Routes[route].IP) } }