diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..bd5e1f2 --- /dev/null +++ b/go.mod @@ -0,0 +1,12 @@ +module jptrlanding.dev/jptr/ssh-orchestrate + +go 1.22.3 + +require ( + github.com/Psiphon-Labs/psiphon-tunnel-core v1.0.11-0.20240607114104-c1011b0e0261 // indirect + github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091 // indirect + github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 // indirect + github.com/vishvananda/netlink v1.1.0 // indirect + github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect + golang.org/x/sys v0.21.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..89da422 --- /dev/null +++ b/go.sum @@ -0,0 +1,13 @@ +github.com/Psiphon-Labs/psiphon-tunnel-core v1.0.11-0.20240607114104-c1011b0e0261 h1:QCbphNE60nTOGdEjFHQgymSKhMkJ9bdeCgTfqSaSJfI= +github.com/Psiphon-Labs/psiphon-tunnel-core v1.0.11-0.20240607114104-c1011b0e0261/go.mod h1:Z5txHi6IF67uDg206QnSxkgE1I3FJUDDJ3n0pa+bKRs= +github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091 h1:1zN6ImoqhSJhN8hGXFaJlSC8msLmIbX8bFqOfWLKw0w= +github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091/go.mod h1:N20Z5Y8oye9a7HmytmZ+tr8Q2vlP0tAHP13kTHzwvQY= +github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8= +github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E= +github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/main.go b/main.go new file mode 100644 index 0000000..84aa197 --- /dev/null +++ b/main.go @@ -0,0 +1,139 @@ +package main + +import ( + "bufio" + "fmt" + "log" + "os" +// "time" + "strconv" + + "math/rand" + + "github.com/songgao/packets/ethernet" + "github.com/songgao/water" + + "github.com/vishvananda/netlink" +) + +type Client struct { + ifce *water.Interface + hostname string + addr *netlink.Addr +} + +// -- funcs -- + +// writes out desired hostname to file. generates a small bash script for +// the client to run +//func generateNewClient() { +// +// var desired_hostname string +// fmt.Printf("Please enter a desired hostname for the new client: ") +// +// scanner := bufio.NewScanner(os.Stdin) +// scanner.Scan() +// err := scanner.Err() +// if err != nil { +// log.Fatal(err) +// panic(err) +// } +// desired_hostname = scanner.Text() +// +// +//} + +// maps ip --> hostname +// used to verify collisions +var client_leases = make(map[string]string) + +func generateClientTUN(hn string) Client { + + // configure TUN interface + config := water.Config{ + DeviceType: water.TUN, + } + config.Name = "tun_"+hn + + + cl_ifce, err := water.New(config) + if err != nil { + log.Fatal(err) + } + + // Generate a free address to assign + var cl_Addr_str string + + // This is a bad way of doing it, and only accounts for local conflicts + // theres definitely a way to find if it conflicts somewhere else + // ideally, it shouldnt be locked to this 16 block, either. eventually, + // the allowed range (CIDR included) should be defined. + // this is an alpha for now, just to get *something* nice working + r := rand.New(rand.NewSource(255)) + for { + var b1 int = int(r.Int31n(255)) + var b2 int = int(r.Int31n(255)) + cl_Addr_str = "." + strconv.Itoa(b1) + "." + strconv.Itoa(b2) + + fmt.Println(cl_Addr_str) + + _, isLeased := client_leases[cl_Addr_str] + if !isLeased { + break + } + } + + cl_Link, err := netlink.LinkByName(config.Name) + if err != nil { + log.Fatal(err) + } + + cl_Addr, err := netlink.ParseAddr("169.254"+cl_Addr_str+"/16") + if err != nil { + log.Fatal(err) + } + + // register addr -> ifce with host + netlink.AddrAdd(cl_Link, cl_Addr) + + return Client { + ifce: cl_ifce, + hostname: hn, + addr: cl_Addr, + } +} + +func main() { + var desired_hostname string + fmt.Printf("your nosthanem is ") + hn, _ := os.Hostname() + fmt.Println(hn) + fmt.Printf("Please enter a desired hostname for the new client: ") + + scanner := bufio.NewScanner(os.Stdin) + scanner.Scan() + err := scanner.Err() + if err != nil { + log.Fatal(err) + } + desired_hostname = scanner.Text() + var registered_client Client = generateClientTUN(desired_hostname) + log.Printf("interface name: %s\n", registered_client.ifce.Name()) + + var frame ethernet.Frame + ifce := registered_client.ifce + for { + frame.Resize(1500) + n, err := ifce.Read([]byte(frame)) + if err != nil { + log.Fatal(err) + } + frame = frame[:n] + log.Printf("Dst: %s\n", frame.Destination()) + log.Printf("Src: %s\n", frame.Source()) + log.Printf("Ethertype: % x\n", frame.Ethertype()) + log.Printf("Payload: % x\n", frame.Payload()) + } + +// generateNewClient() +}