mirror of
https://github.com/sigcn/pg.git
synced 2025-11-01 13:42:33 +08:00
split the peerguard tool into pgcli and pgserve
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,5 +1,6 @@
|
|||||||
*.exe
|
*.exe
|
||||||
peerguard*
|
pgcli-*
|
||||||
|
pgserve-*
|
||||||
wintun/
|
wintun/
|
||||||
*.zip
|
*.zip
|
||||||
*.dll
|
*.dll
|
||||||
|
|||||||
28
Makefile
28
Makefile
@@ -6,9 +6,11 @@ GOBUILD := CGO_ENABLED=0 go build -ldflags "-s -w -X 'main.Version=${version}' -
|
|||||||
all: linux windows darwin
|
all: linux windows darwin
|
||||||
|
|
||||||
linuxamd64:
|
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:
|
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
|
linux: linuxamd64 linuxarm64
|
||||||
|
|
||||||
wintun:
|
wintun:
|
||||||
@@ -16,33 +18,35 @@ wintun:
|
|||||||
unzip wintun-0.14.1.zip
|
unzip wintun-0.14.1.zip
|
||||||
rm wintun-0.14.1.zip
|
rm wintun-0.14.1.zip
|
||||||
winamd64: wintun
|
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 .
|
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
|
rm wintun.dll
|
||||||
winarm64: wintun
|
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 .
|
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
|
rm wintun.dll
|
||||||
windows: winamd64 winarm64
|
windows: winamd64 winarm64
|
||||||
|
|
||||||
darwinamd64:
|
darwinamd64:
|
||||||
GOOS=darwin GOARCH=amd64 ${GOBUILD} -o peerguard-${version}-darwin-amd64
|
GOOS=darwin GOARCH=amd64 ${GOBUILD} -o pgcli-${version}-darwin-amd64 ./cmd/pgcli
|
||||||
darwinarm64:
|
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
|
darwin: darwinamd64 darwinarm64
|
||||||
|
|
||||||
github: clean all
|
github: clean all
|
||||||
gzip peerguard-${version}-linux*
|
gzip pgcli-${version}-linux*
|
||||||
gzip peerguard-${version}-darwin*
|
gzip pgcli-${version}-darwin*
|
||||||
|
gzip pgserve-${version}-linux*
|
||||||
git tag -d ${version} 2>/dev/null || true
|
git tag -d ${version} 2>/dev/null || true
|
||||||
gh release delete ${version} -y --cleanup-tag 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
|
dist: github
|
||||||
|
|
||||||
clean:
|
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 *.zip 2>/dev/null || true
|
||||||
rm *.dll 2>/dev/null || true
|
rm *.dll 2>/dev/null || true
|
||||||
|
|||||||
66
README.md
66
README.md
@@ -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
|
```go
|
||||||
peermap := p2p.Peermap("wss://synf.in/pg")
|
peermap := p2p.Peermap("wss://synf.in/pg")
|
||||||
|
|
||||||
@@ -11,13 +34,14 @@ if err != nil {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Println(intent.AuthURL()) // https://synf.in/oidc/google?state=5G68CtYnMRMdrtrRF
|
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 {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
packetConn, err := p2p.ListenPacket(
|
packetConn, err := p2p.ListenPacket(
|
||||||
&secret, peermap,
|
&networkSecret,
|
||||||
|
peermap,
|
||||||
p2p.ListenPeerID("uniqueString"), // any unique string (less than 256bytes)
|
p2p.ListenPeerID("uniqueString"), // any unique string (less than 256bytes)
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -39,11 +63,11 @@ for {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Peer2
|
### Peer2
|
||||||
```go
|
```go
|
||||||
...
|
...
|
||||||
|
|
||||||
packetConn, err := p2p.ListenPacket(secret.Secret, peermap)
|
packetConn, err := p2p.ListenPacket(&networkSecret, peermap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -65,31 +89,3 @@ if err !=nil {
|
|||||||
}
|
}
|
||||||
fmt.Println(peerID, ":", string(buf[:n])) // uniqueString : hello
|
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
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
"github.com/rkonfj/peerguard/cmd/curve25519"
|
"github.com/rkonfj/peerguard/cmd/pgcli/curve25519"
|
||||||
"github.com/rkonfj/peerguard/cmd/serve"
|
"github.com/rkonfj/peerguard/cmd/pgcli/secret"
|
||||||
"github.com/rkonfj/peerguard/cmd/token"
|
"github.com/rkonfj/peerguard/cmd/pgcli/vpn"
|
||||||
"github.com/rkonfj/peerguard/cmd/vpn"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -18,12 +17,12 @@ var (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "peerguard",
|
Use: "pgcli",
|
||||||
Version: fmt.Sprintf("%s, commit %s", Version, Commit),
|
Version: fmt.Sprintf("%s, commit %s", Version, Commit),
|
||||||
Short: "A peer to peer network toolset",
|
Short: "A p2p network toolset",
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
verbose, err := cmd.Flags().GetInt("v")
|
verbose, err := cmd.Flags().GetInt("verbose")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -32,12 +31,10 @@ func main() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.AddCommand(serve.Cmd)
|
|
||||||
cmd.AddCommand(token.Cmd)
|
|
||||||
cmd.AddCommand(vpn.Cmd)
|
cmd.AddCommand(vpn.Cmd)
|
||||||
|
cmd.AddCommand(secret.Cmd)
|
||||||
cmd.AddCommand(curve25519.Cmd)
|
cmd.AddCommand(curve25519.Cmd)
|
||||||
|
|
||||||
cmd.PersistentFlags().Int("v", 0, "logger verbosity level")
|
cmd.PersistentFlags().IntP("verbose", "V", 0, "logger verbosity level")
|
||||||
|
|
||||||
cmd.Execute()
|
cmd.Execute()
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package token
|
package secret
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -22,7 +22,7 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
networkID, err := cmd.Flags().GetString("network")
|
network, err := cmd.Flags().GetString("network")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -30,18 +30,18 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
token, err := auth.NewAuthenticator(secretKey).GenerateSecret(networkID, validDuration)
|
secret, err := auth.NewAuthenticator(secretKey).GenerateSecret(network, validDuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return json.NewEncoder(os.Stdout).Encode(peer.NetworkSecret{
|
return json.NewEncoder(os.Stdout).Encode(peer.NetworkSecret{
|
||||||
Secret: token,
|
Secret: secret,
|
||||||
Network: networkID,
|
Network: network,
|
||||||
Expire: time.Now().Add(validDuration - 10*time.Second),
|
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().String("secret-key", "", "key to generate network secret")
|
||||||
Cmd.Flags().Duration("duration", 365*24*time.Hour, "secret duration to expire")
|
Cmd.Flags().Duration("duration", 365*24*time.Hour, "secret duration to expire")
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ import (
|
|||||||
|
|
||||||
var Cmd = &cobra.Command{
|
var Cmd = &cobra.Command{
|
||||||
Use: "vpn",
|
Use: "vpn",
|
||||||
Short: "Run a vpn daemon powered by PeerGuard",
|
Short: "Run a vpn daemon which backend is PeerGuard p2p network",
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: run,
|
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("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().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("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>)")
|
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().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.Flags().Float64("disco-challenges-backoff-rate", 1.35, "ping challenges backoff rate when disco")
|
||||||
|
|
||||||
Cmd.MarkFlagRequired("peermap")
|
Cmd.MarkFlagRequired("server")
|
||||||
Cmd.MarkFlagsOneRequired("ipv4", "ipv6")
|
Cmd.MarkFlagsOneRequired("ipv4", "ipv6")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,10 +105,11 @@ func run(cmd *cobra.Command, args []string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.Peermap, err = cmd.Flags().GetStringSlice("peermap")
|
server, err := cmd.Flags().GetString("server")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
cfg.Peermap = peer.PeermapCluster{server}
|
||||||
|
|
||||||
tunName, err := cmd.Flags().GetString("tun")
|
tunName, err := cmd.Flags().GetString("tun")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package serve
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@@ -12,18 +13,27 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Cmd = &cobra.Command{
|
var (
|
||||||
Use: "serve",
|
Version = "unknown"
|
||||||
Short: "PeerGuard peermap daemon",
|
Commit = "unknown"
|
||||||
Args: cobra.NoArgs,
|
)
|
||||||
RunE: run,
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func main() {
|
||||||
Cmd.Flags().StringP("config", "c", "config.yaml", "config file")
|
serveCmd := &cobra.Command{
|
||||||
Cmd.Flags().StringP("listen", "l", "", "listen http address (default 127.0.0.1:9987)")
|
Use: "pgserve",
|
||||||
Cmd.Flags().String("secret-key", "", "key to generate network secret (defaut generate a random one)")
|
Version: fmt.Sprintf("%s, commit %s", Version, Commit),
|
||||||
Cmd.Flags().StringSlice("stun", []string{}, "stun server for peers NAT traversal (leave blank to disable NAT traversal)")
|
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")
|
||||||
|
|
||||||
|
serveCmd.Execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(cmd *cobra.Command, args []string) error {
|
func run(cmd *cobra.Command, args []string) error {
|
||||||
Reference in New Issue
Block a user