19 Commits

Author SHA1 Message Date
Alec Scott
5ff46dc02e Merge pull request #27 from hyprspace/add/UPnP
Add initial support for UPnP to Hyprspace
2021-08-21 12:06:45 -07:00
Alec Scott
52c78391bb Add initial support for UPnP to Hyprspace 2021-08-21 12:04:47 -07:00
Alec Scott
c5ccc0daaa Update README.md 2021-07-22 09:56:38 -07:00
Alec Scott
795da55458 Update README.md 2021-07-22 09:54:27 -07:00
Alec Scott
5b957d3ed7 Create codeql-analysis.yml 2021-07-13 15:48:08 -07:00
Alec Scott
f9c74c1cc1 Merge pull request #19 from max-privatevoid/patch-1
Don't hardcode `ip` binary path
2021-07-08 18:54:11 -07:00
Max
17f09c48dc Don't hardcode ip binary path
Not all systems install the binary in this path, a correctly configured PATH environment variable should suffice.
2021-07-05 22:49:03 +02:00
Alec Scott
05cc6b08ce Merge pull request #15 from hyprspace/feature/dht-client
Switch to DHTClient Mode & Build Smaller Binaries
2021-06-26 10:36:58 -07:00
Alec Scott
1e23bdb2e0 Switch to DHTClient Mode & Build Smaller Binaries 2021-06-26 10:33:08 -07:00
Alec Scott
f4a7b5abbe Merge pull request #11 from hyprspace/feature/experience-improvements
Improve Error Handling & Allow Multiple Interfaces
2021-06-16 22:30:25 -07:00
Alec Scott
53768270bd Improve Error Handling & Allow Multiple Interfaces 2021-06-16 22:26:15 -07:00
Alec Scott
0c59a57fc0 Merge pull request #7 from swedneck/main
Add template systemd service file
2021-06-14 18:43:06 -07:00
Alec Scott
d3fb8478b9 Move systemd service file to examples directory 2021-06-14 18:41:08 -07:00
Tim Stahel
e8b9a09992 improved systemd service file, now a proper template 2021-06-14 00:38:05 +02:00
Tim Stahel
85a67189ff add crappy systemd service file 2021-06-12 21:34:14 +02:00
Alec Scott
91a21970ce Update README.md 2021-06-10 22:54:37 -07:00
Alec Scott
5b24c1d1bf Update README.md 2021-06-10 07:43:02 -07:00
Alec Scott
b5fe9d691d Update README.md 2021-06-09 22:28:30 -07:00
Alec Scott
76d27fbcfa Add Demo Video 2021-06-09 22:26:51 -07:00
14 changed files with 174 additions and 27 deletions

View File

@@ -7,6 +7,6 @@ do
platform_split=(${platform//\// })
GOOS=${platform_split[0]}
GOARCH=${platform_split[1]}
env GOOS=$GOOS GOARCH=$GOARCH go build -ldflags "-X github.com/hyprspace/hyprspace/cli.appVersion=$1" -o hyprspace-$1-${GOOS}-${GOARCH} .
env GOOS=$GOOS GOARCH=$GOARCH CGO_ENABLED=0 go build -ldflags "-s -w -X github.com/hyprspace/hyprspace/cli.appVersion=$1" -o hyprspace-$1-${GOOS}-${GOARCH} .
done

71
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,71 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '21 19 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'go' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

3
.gitignore vendored
View File

@@ -1 +1,2 @@
hyprspace
hyprspace
.DS_Store

View File

@@ -2,9 +2,14 @@
# Hyprspace
[![Go Report Card](https://goreportcard.com/badge/github.com/hyprspace/hyprspace)](https://goreportcard.com/report/github.com/hyprspace/hyprspace)
[![](https://img.shields.io/matrix/hyprspace:matrix.org)](https://matrix.to/#/%23hyprspace:matrix.org)
A Lightweight VPN Built on top of Libp2p for Truly Distributed Networks.
https://user-images.githubusercontent.com/19558067/121469777-f42cdb80-c971-11eb-84de-9dd4f6d6cd1f.mp4
## Table of Contents
- [A Bit of Backstory](#a-bit-of-backstory)
- [Use Cases](#use-cases)
@@ -35,6 +40,9 @@ Honestly, I even use this system when I'm at home and could connect directly to
If anyone else has some use cases please add them! Pull requests welcome!
| :exclamation: | Hyprspace is still a very new project. Although we've tested the code locally for security, it hasn't been audited by a third party yet. We probably wouldn't trust it yet in high security environments. |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
## Getting Started
### Prerequisites
If you're running Hyprspace on a Mac you'll need to install `iproute2mac`. If you're using the `brew` package manager that's as simple as,
@@ -44,7 +52,7 @@ brew install iproute2mac
### Installation
1. Go to Hyprspace Releases (other there -->)
1. Go to Hyprspace Releases (over there -->)
2. Copy the link for your corresponding OS and Architecture.
3. Run `sudo mkdir -p /usr/local/bin/`
4. Run `sudo curl -L "PATH-TO-RELEASE" -o /usr/local/bin/hyprspace`
@@ -61,7 +69,7 @@ brew install iproute2mac
| `init` | `i` | Initialize an interface's configuration. |
| `up` | `up` | Create and Bring Up a Hyprspace Interface |
| `down ` | `d` | Bring Down and Delete A Hyprspace Interface |
| `update` | `upd` | Have Hyprspace update its own binary. |
| `update` | `upd` | Have Hyprspace update its own binary to the latest release. |
## Tutorial

View File

@@ -55,6 +55,7 @@ func InitRun(r *cmd.Root, c *cmd.Sub) {
new := config.Config{
Interface: config.Interface{
Name: args.InterfaceName,
ListenPort: 8001,
Address: "10.1.1.1/24",
ID: host.ID().Pretty(),
PrivateKey: string(keyBytes),

View File

@@ -9,6 +9,8 @@ import (
"github.com/DataDrake/cli-ng/v2/cmd"
)
var appVersion string = "develop"
//GlobalFlags contains the flags for commands.
type GlobalFlags struct {
Config string `short:"c" long:"config" desc:"Specify a custom config path."`
@@ -19,15 +21,18 @@ var Root *cmd.Root
func init() {
Root = &cmd.Root{
Name: "hyprspace",
Short: "Hyprspace Distributed Network",
Flags: &GlobalFlags{},
Name: "hyprspace",
Short: "Hyprspace Distributed Network",
Version: appVersion,
Flags: &GlobalFlags{},
}
cmd.Register(&cmd.Help)
cmd.Register(&Init)
cmd.Register(&Up)
cmd.Register(&Down)
cmd.Register(&Update)
cmd.Register(&cmd.Version)
}
func checkErr(err error) {

View File

@@ -3,11 +3,14 @@ package cli
import (
"bufio"
"context"
"errors"
"fmt"
"io"
"log"
"net"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"time"
@@ -75,15 +78,18 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
if !flags.Foreground {
// Make results chan
out := make(chan bool)
out := make(chan error)
go createDaemon(out)
select {
case <-out:
case err = <-out:
case <-time.After(30 * time.Second):
}
checkErr(err)
fmt.Println("[+] Successfully Created Hyprspace Daemon")
if err != nil {
fmt.Println("[+] Failed to Create Hyprspace Daemon")
} else {
fmt.Println("[+] Successfully Created Hyprspace Daemon")
}
return
}
@@ -96,7 +102,9 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
fmt.Println("[+] Creating TUN Device")
// Create new TUN device
iface, err = tun.New(Global.Interface.Name)
checkErr(err)
if err != nil {
checkErr(errors.New("interface already in use"))
}
// Set TUN MTU
tun.SetMTU(Global.Interface.Name, 1420)
// Add Address to Interface
@@ -106,8 +114,35 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
ctx := context.Background()
fmt.Println("[+] Creating LibP2P Node")
// Check that the listener port is available.
var ln net.Listener
port := Global.Interface.ListenPort
if port != 8001 {
ln, err = net.Listen("tcp", ":"+strconv.Itoa(port))
if err != nil {
checkErr(errors.New("could not create node, listen port already in use by something else"))
}
} else {
for {
ln, err = net.Listen("tcp", ":"+strconv.Itoa(port))
if err == nil {
break
}
if port >= 65535 {
checkErr(errors.New("failed to find open port"))
}
port++
}
}
if ln != nil {
ln.Close()
}
// Create P2P Node
host, dht, err := p2p.CreateNode(ctx, Global.Interface.PrivateKey, streamHandler)
host, dht, err := p2p.CreateNode(ctx,
Global.Interface.PrivateKey,
port,
streamHandler)
checkErr(err)
// Setup Peer Table for Quick Packet --> Dest ID lookup
@@ -162,7 +197,7 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
}
}
func createDaemon(out chan<- bool) {
func createDaemon(out chan<- error) {
path, err := os.Executable()
checkErr(err)
// Create Pipe to monitor for daemon output.
@@ -173,7 +208,7 @@ func createDaemon(out chan<- bool) {
path,
append(os.Args, "--foreground"),
&os.ProcAttr{
Files: []*os.File{nil, w, nil},
Files: []*os.File{nil, w, w},
},
)
checkErr(err)
@@ -186,7 +221,10 @@ func createDaemon(out chan<- bool) {
fmt.Println(scanner.Text())
err = process.Release()
checkErr(err)
out <- true
if count < 4 {
out <- errors.New("failed to create daemon")
}
out <- nil
}
func streamHandler(stream network.Stream) {

View File

@@ -14,8 +14,6 @@ import (
"github.com/tcnksm/go-latest"
)
var appVersion string
// Update checks for a new version of the Hyprspace program and updates itself
// if a newer version is found and the user agrees to update.
var Update = cmd.Sub{

View File

@@ -15,8 +15,9 @@ type Config struct {
// Interface defines all of the fields that a local node needs to know about itself!
type Interface struct {
Name string `yaml:"name"`
Address string `yaml:"address"`
ID string `yaml:"id"`
ListenPort int `yaml:"listen_port"`
Address string `yaml:"address"`
DiscoverKey string `yaml:"discover_key"`
PrivateKey string `yaml:"private_key"`
}
@@ -32,6 +33,16 @@ func Read(path string) (result Config, err error) {
if err != nil {
return
}
result = Config{
Interface: Interface{
Name: "hs0",
ListenPort: 8001,
Address: "10.1.1.1",
ID: "",
DiscoverKey: "",
PrivateKey: "",
},
}
err = yaml.Unmarshal(in, &result)
return
}

View File

@@ -0,0 +1,12 @@
[Unit]
Description=hyprspace daemon for %i
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/hyprspace up %i --foreground
ExecStop=/usr/local/bin/hyprspace down %i
Restart=on-failure
[Install]
WantedBy=default.target

1
go.mod
View File

@@ -6,6 +6,7 @@ require (
github.com/DataDrake/cli-ng/v2 v2.0.2
github.com/hashicorp/go-version v1.2.1 // indirect
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf
github.com/ipfs/go-datastore v0.4.5
github.com/kr/text v0.2.0 // indirect
github.com/libp2p/go-libp2p v0.14.1
github.com/libp2p/go-libp2p-core v0.8.5

View File

@@ -18,7 +18,7 @@ func Discover(ctx context.Context, h host.Host, dht *dht.IpfsDHT, rendezvous str
var routingDiscovery = discovery.NewRoutingDiscovery(dht)
discovery.Advertise(ctx, routingDiscovery, rendezvous)
ticker := time.NewTicker(time.Second * 1)
ticker := time.NewTicker(time.Second * 5)
defer ticker.Stop()
for {

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"sync"
"github.com/ipfs/go-datastore"
"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/host"
@@ -18,7 +19,7 @@ import (
const Protocol = "/hyprspace/0.0.1"
// CreateNode creates an internal Libp2p nodes and returns it and it's DHT Discovery service.
func CreateNode(ctx context.Context, inputKey string, handler network.StreamHandler) (node host.Host, dhtOut *dht.IpfsDHT, err error) {
func CreateNode(ctx context.Context, inputKey string, port int, handler network.StreamHandler) (node host.Host, dhtOut *dht.IpfsDHT, err error) {
// Unmarshal Private Key
privateKey, err := crypto.UnmarshalPrivateKey([]byte(inputKey))
if err != nil {
@@ -27,8 +28,11 @@ func CreateNode(ctx context.Context, inputKey string, handler network.StreamHand
// Create libp2p node
node, err = libp2p.New(ctx,
libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", 8001)),
libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", port)),
libp2p.Identity(privateKey),
libp2p.DefaultSecurity,
libp2p.NATPortMap(),
libp2p.FallbackDefaults,
)
if err != nil {
return
@@ -38,10 +42,7 @@ func CreateNode(ctx context.Context, inputKey string, handler network.StreamHand
node.SetStreamHandler(Protocol, handler)
// Create DHT Subsystem
dhtOut, err = dht.New(ctx, node)
if err != nil {
return
}
dhtOut = dht.NewDHTClient(ctx, node, datastore.NewMapDatastore())
// Define Bootstrap Nodes.
peers := []string{

View File

@@ -46,7 +46,7 @@ func Delete(name string) (err error) {
}
func ip(args ...string) (err error) {
cmd := exec.Command("/sbin/ip", args...)
cmd := exec.Command("ip", args...)
err = cmd.Run()
return
}