split the peerguard tool into pgcli and pgserve

This commit is contained in:
rkonfj
2024-03-09 17:28:32 +08:00
parent 4fdd64fa20
commit 3b40717cbf
8 changed files with 90 additions and 81 deletions

3
.gitignore vendored
View File

@@ -1,5 +1,6 @@
*.exe
peerguard*
pgcli-*
pgserve-*
wintun/
*.zip
*.dll

View File

@@ -6,9 +6,11 @@ GOBUILD := CGO_ENABLED=0 go build -ldflags "-s -w -X 'main.Version=${version}' -
all: linux windows darwin
linuxamd64:
GOOS=linux GOARCH=amd64 ${GOBUILD} -o peerguard-${version}-linux-amd64
GOOS=linux GOARCH=amd64 ${GOBUILD} -o pgcli-${version}-linux-amd64 ./cmd/pgcli
GOOS=linux GOARCH=amd64 ${GOBUILD} -o pgserve-${version}-linux-amd64 ./cmd/pgserve
linuxarm64:
GOOS=linux GOARCH=arm64 ${GOBUILD} -o peerguard-${version}-linux-arm64
GOOS=linux GOARCH=arm64 ${GOBUILD} -o pgcli-${version}-linux-arm64 ./cmd/pgcli
GOOS=linux GOARCH=arm64 ${GOBUILD} -o pgserve-${version}-linux-arm64 ./cmd/pgserve
linux: linuxamd64 linuxarm64
wintun:
@@ -16,33 +18,35 @@ wintun:
unzip wintun-0.14.1.zip
rm wintun-0.14.1.zip
winamd64: wintun
GOOS=windows GOARCH=amd64 ${GOBUILD} -o peerguard-${version}-windows-amd64.exe
GOOS=windows GOARCH=amd64 ${GOBUILD} -o pgcli-${version}-windows-amd64.exe ./cmd/pgcli
cp wintun/bin/amd64/wintun.dll .
zip -r peerguard-${version}-windows-amd64.zip peerguard-${version}-windows-amd64.exe wintun.dll
zip -r pgcli-${version}-windows-amd64.zip pgcli-${version}-windows-amd64.exe wintun.dll
rm wintun.dll
winarm64: wintun
GOOS=windows GOARCH=arm64 ${GOBUILD} -o peerguard-${version}-windows-arm64.exe
GOOS=windows GOARCH=arm64 ${GOBUILD} -o pgcli-${version}-windows-arm64.exe ./cmd/pgcli
cp wintun/bin/arm64/wintun.dll .
zip -r peerguard-${version}-windows-arm64.zip peerguard-${version}-windows-arm64.exe wintun.dll
zip -r pgcli-${version}-windows-arm64.zip pgcli-${version}-windows-arm64.exe wintun.dll
rm wintun.dll
windows: winamd64 winarm64
darwinamd64:
GOOS=darwin GOARCH=amd64 ${GOBUILD} -o peerguard-${version}-darwin-amd64
GOOS=darwin GOARCH=amd64 ${GOBUILD} -o pgcli-${version}-darwin-amd64 ./cmd/pgcli
darwinarm64:
GOOS=darwin GOARCH=arm64 ${GOBUILD} -o peerguard-${version}-darwin-arm64
GOOS=darwin GOARCH=arm64 ${GOBUILD} -o pgcli-${version}-darwin-arm64 ./cmd/pgcli
darwin: darwinamd64 darwinarm64
github: clean all
gzip peerguard-${version}-linux*
gzip peerguard-${version}-darwin*
gzip pgcli-${version}-linux*
gzip pgcli-${version}-darwin*
gzip pgserve-${version}-linux*
git tag -d ${version} 2>/dev/null || true
gh release delete ${version} -y --cleanup-tag 2>/dev/null || true
gh release create ${version} --generate-notes --title "peerguard ${version}" peerguard-${version}*.gz peerguard-${version}*.zip
gh release create ${version} --generate-notes --title "peerguard ${version}" pgcli-${version}*.gz pgcli-${version}*.zip pgserve-${version}*.gz
dist: github
clean:
rm peerguard* 2>/dev/null || true
rm pgcli* 2>/dev/null || true
rm pgserve* 2>/dev/null || true
rm *.zip 2>/dev/null || true
rm *.dll 2>/dev/null || true

View File

@@ -1,8 +1,31 @@
## Example
# PeerGuard - Another p2p network library in Go
### 1. Code
## Get Started
#### Peer1 (act as echo server)
### Deploy the peermap server
#### 1. Run the pgserve daemon
```
$ pgserve -l 127.0.0.1:9987 --secret-key 5172554832d76672d1959a5ac63c5ab9 \
--stun stun.qq.com:3478 --stun stun.miwifi.com:3478
```
#### 2. Wrap pgserve as an https server
```
$ caddy reverse-proxy --from https://synf.in/pg --to 127.0.0.1:9987
```
### Follow the steps below to run VPN nodes in different networks
#### 1. Generate a network secret
```
# pgcli secret --secret-key 5172554832d76672d1959a5ac63c5ab9 > ~/.peerguard_network_secret.json
```
#### 2. Run a VPN daemon
```
# pgcli vpn -s wss://synf.in/pg --ipv4 100.64.0.1/24 --ipv6 fd00::1/64
```
## P2P programming example
### Peer1 (act as echo server)
```go
peermap := p2p.Peermap("wss://synf.in/pg")
@@ -11,13 +34,14 @@ if err != nil {
panic(err)
}
fmt.Println(intent.AuthURL()) // https://synf.in/oidc/google?state=5G68CtYnMRMdrtrRF
secret, err := intent.Wait(context.TODO())
networkSecret, err := intent.Wait(context.TODO())
if err != nil {
panic(err)
}
packetConn, err := p2p.ListenPacket(
&secret, peermap,
&networkSecret,
peermap,
p2p.ListenPeerID("uniqueString"), // any unique string (less than 256bytes)
)
if err != nil {
@@ -39,11 +63,11 @@ for {
}
```
#### Peer2
### Peer2
```go
...
packetConn, err := p2p.ListenPacket(secret.Secret, peermap)
packetConn, err := p2p.ListenPacket(&networkSecret, peermap)
if err != nil {
panic(err)
}
@@ -65,31 +89,3 @@ if err !=nil {
}
fmt.Println(peerID, ":", string(buf[:n])) // uniqueString : hello
```
### 2. VPN(p2p)
#### Machine 1
```
# peerguard vpn --peermap wss://synf.in/pg --ipv4 100.64.0.1/24 --ipv6 fd00::1/64
```
#### Machine 2
```
# peerguard vpn --peermap wss://synf.in/pg --ipv4 100.64.0.2/24 --ipv6 fd00::2/64
```
**Another terminal on machine 2**
```
# ping 100.64.0.1
PING 100.64.0.1 (100.64.0.1) 56(84) bytes of data.
64 bytes from 100.64.0.1: icmp_seq=1 ttl=64 time=7.88 ms
64 bytes from 100.64.0.1: icmp_seq=2 ttl=64 time=4.19 ms
64 bytes from 100.64.0.1: icmp_seq=3 ttl=64 time=4.47 ms
64 bytes from 100.64.0.1: icmp_seq=4 ttl=64 time=4.54 ms
...
# ping fd00::1
PING fd00::1 (fd00::1) 56 data bytes
64 bytes from fd00::1: icmp_seq=1 ttl=64 time=4.29 ms
64 bytes from fd00::1: icmp_seq=2 ttl=64 time=5.84 ms
64 bytes from fd00::1: icmp_seq=3 ttl=64 time=3.48 ms
64 bytes from fd00::1: icmp_seq=4 ttl=64 time=4.69 ms
```

View File

@@ -4,10 +4,9 @@ import (
"fmt"
"log/slog"
"github.com/rkonfj/peerguard/cmd/curve25519"
"github.com/rkonfj/peerguard/cmd/serve"
"github.com/rkonfj/peerguard/cmd/token"
"github.com/rkonfj/peerguard/cmd/vpn"
"github.com/rkonfj/peerguard/cmd/pgcli/curve25519"
"github.com/rkonfj/peerguard/cmd/pgcli/secret"
"github.com/rkonfj/peerguard/cmd/pgcli/vpn"
"github.com/spf13/cobra"
)
@@ -18,12 +17,12 @@ var (
func main() {
cmd := &cobra.Command{
Use: "peerguard",
Use: "pgcli",
Version: fmt.Sprintf("%s, commit %s", Version, Commit),
Short: "A peer to peer network toolset",
Short: "A p2p network toolset",
SilenceUsage: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
verbose, err := cmd.Flags().GetInt("v")
verbose, err := cmd.Flags().GetInt("verbose")
if err != nil {
return err
}
@@ -32,12 +31,10 @@ func main() {
},
}
cmd.AddCommand(serve.Cmd)
cmd.AddCommand(token.Cmd)
cmd.AddCommand(vpn.Cmd)
cmd.AddCommand(secret.Cmd)
cmd.AddCommand(curve25519.Cmd)
cmd.PersistentFlags().Int("v", 0, "logger verbosity level")
cmd.PersistentFlags().IntP("verbose", "V", 0, "logger verbosity level")
cmd.Execute()
}

View File

@@ -1,4 +1,4 @@
package token
package secret
import (
"encoding/json"
@@ -22,7 +22,7 @@ func init() {
if err != nil {
return err
}
networkID, err := cmd.Flags().GetString("network")
network, err := cmd.Flags().GetString("network")
if err != nil {
return err
}
@@ -30,18 +30,18 @@ func init() {
if err != nil {
return err
}
token, err := auth.NewAuthenticator(secretKey).GenerateSecret(networkID, validDuration)
secret, err := auth.NewAuthenticator(secretKey).GenerateSecret(network, validDuration)
if err != nil {
return err
}
return json.NewEncoder(os.Stdout).Encode(peer.NetworkSecret{
Secret: token,
Network: networkID,
Secret: secret,
Network: network,
Expire: time.Now().Add(validDuration - 10*time.Second),
})
},
}
Cmd.Flags().String("network", "", "network")
Cmd.Flags().String("network", "default", "network")
Cmd.Flags().String("secret-key", "", "key to generate network secret")
Cmd.Flags().Duration("duration", 365*24*time.Hour, "secret duration to expire")

View File

@@ -25,7 +25,7 @@ import (
var Cmd = &cobra.Command{
Use: "vpn",
Short: "Run a vpn daemon powered by PeerGuard",
Short: "Run a vpn daemon which backend is PeerGuard p2p network",
Args: cobra.NoArgs,
RunE: run,
}
@@ -39,7 +39,7 @@ func init() {
Cmd.Flags().String("key", "", "curve25519 private key in base64-url format (default generate a new one)")
Cmd.Flags().String("secret-file", "", "p2p network secret file (default ~/.peerguard_network_secret.json)")
Cmd.Flags().StringSlice("peermap", []string{}, "peermap cluster")
Cmd.Flags().StringP("server", "s", "", "peermap server")
Cmd.Flags().StringSlice("allowed-ip", []string{}, "declare IPs that can be routed/NATed by this machine (i.e. 192.168.0.0/24)")
Cmd.Flags().StringSlice("peer", []string{}, "specify peers instead of auto-discovery (pg://<peerID>?alias1=<ipv4>&alias2=<ipv6>)")
@@ -48,7 +48,7 @@ func init() {
Cmd.Flags().Duration("disco-challenges-initial-interval", 300*time.Millisecond, "ping challenges initial interval when disco")
Cmd.Flags().Float64("disco-challenges-backoff-rate", 1.35, "ping challenges backoff rate when disco")
Cmd.MarkFlagRequired("peermap")
Cmd.MarkFlagRequired("server")
Cmd.MarkFlagsOneRequired("ipv4", "ipv6")
}
@@ -105,10 +105,11 @@ func run(cmd *cobra.Command, args []string) (err error) {
return
}
cfg.Peermap, err = cmd.Flags().GetStringSlice("peermap")
server, err := cmd.Flags().GetString("server")
if err != nil {
return
}
cfg.Peermap = peer.PeermapCluster{server}
tunName, err := cmd.Flags().GetString("tun")
if err != nil {

View File

@@ -1,8 +1,9 @@
package serve
package main
import (
"context"
"errors"
"fmt"
"net/http"
"os"
"os/signal"
@@ -12,18 +13,27 @@ import (
"github.com/spf13/cobra"
)
var Cmd = &cobra.Command{
Use: "serve",
Short: "PeerGuard peermap daemon",
var (
Version = "unknown"
Commit = "unknown"
)
func main() {
serveCmd := &cobra.Command{
Use: "pgserve",
Version: fmt.Sprintf("%s, commit %s", Version, Commit),
Short: "Run a peermap server daemon",
SilenceUsage: true,
Args: cobra.NoArgs,
RunE: run,
}
serveCmd.Flags().StringP("config", "c", "config.yaml", "config file")
serveCmd.Flags().StringP("listen", "l", "127.0.0.1:9987", "listen http address")
serveCmd.Flags().String("secret-key", "", "key to generate network secret (defaut generate a random one)")
serveCmd.Flags().StringSlice("stun", []string{}, "stun server for peers NAT traversal (leave blank to disable NAT traversal)")
serveCmd.Flags().IntP("verbose", "V", 0, "logger verbosity level")
func init() {
Cmd.Flags().StringP("config", "c", "config.yaml", "config file")
Cmd.Flags().StringP("listen", "l", "", "listen http address (default 127.0.0.1:9987)")
Cmd.Flags().String("secret-key", "", "key to generate network secret (defaut generate a random one)")
Cmd.Flags().StringSlice("stun", []string{}, "stun server for peers NAT traversal (leave blank to disable NAT traversal)")
serveCmd.Execute()
}
func run(cmd *cobra.Command, args []string) error {