mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-13 08:59:08 +02:00
Add client's interaction with management service (#71)
* Add client's interaction with management service * Getting updates * Fixed key and nil ptr * Added setupKey param * Added managment address parameter * Fixed test * feature: use RemotePeers from the management server instead of deprecated Peers * merge: merge changes from main
This commit is contained in:
+29
-18
@@ -1,10 +1,13 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/wiretrustee/wiretrustee/connection"
|
||||
"os"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -16,24 +19,9 @@ var (
|
||||
Short: "add remote peer",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
InitLog(logLevel)
|
||||
|
||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||
log.Error("config doesn't exist, please run 'wiretrustee init' first")
|
||||
os.Exit(ExitSetupFailed)
|
||||
}
|
||||
|
||||
config, err := Read(configPath)
|
||||
err := addPeer(key, allowedIPs)
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading config file, message: %v", err)
|
||||
}
|
||||
config.Peers = append(config.Peers, connection.Peer{
|
||||
WgPubKey: key,
|
||||
WgAllowedIps: allowedIPs,
|
||||
})
|
||||
|
||||
err = config.Write(configPath)
|
||||
if err != nil {
|
||||
log.Errorf("failed writing config to %s: %s", config, err.Error())
|
||||
log.Errorf("Failed to add peer: %s", err)
|
||||
os.Exit(ExitSetupFailed)
|
||||
}
|
||||
},
|
||||
@@ -46,3 +34,26 @@ func init() {
|
||||
addPeerCmd.MarkPersistentFlagRequired("key") //nolint
|
||||
addPeerCmd.MarkPersistentFlagRequired("allowedIPs") //nolint
|
||||
}
|
||||
|
||||
func addPeer(peerKey string, allowedIPs string) error {
|
||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||
return status.Errorf(codes.FailedPrecondition, "Config doesn't exist, please run 'wiretrustee init' first")
|
||||
}
|
||||
|
||||
config, err := Read(configPath)
|
||||
if err != nil {
|
||||
return status.Errorf(codes.FailedPrecondition, "Error reading config file, message: %s", err)
|
||||
}
|
||||
config.Peers = append(config.Peers, connection.Peer{
|
||||
WgPubKey: key,
|
||||
WgAllowedIps: allowedIPs,
|
||||
})
|
||||
|
||||
err = config.Write(configPath)
|
||||
if err != nil {
|
||||
log.Errorf("failed writing config to %s: %s", config, err.Error())
|
||||
return status.Errorf(codes.Internal, "failed writing config to %s: %s", configPath, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+4
-2
@@ -2,11 +2,12 @@ package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
ice "github.com/pion/ice/v2"
|
||||
"github.com/wiretrustee/wiretrustee/connection"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
ice "github.com/pion/ice/v2"
|
||||
"github.com/wiretrustee/wiretrustee/connection"
|
||||
)
|
||||
|
||||
// Config Configuration type
|
||||
@@ -17,6 +18,7 @@ type Config struct {
|
||||
StunTurnURLs []*ice.URL
|
||||
// host:port of the signal server
|
||||
SignalAddr string
|
||||
ManagementAddr string
|
||||
WgAddr string
|
||||
WgIface string
|
||||
IFaceBlackList []string
|
||||
|
||||
+23
-18
@@ -1,21 +1,23 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
ice "github.com/pion/ice/v2"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
wgKey string
|
||||
wgInterface string
|
||||
wgLocalAddr string
|
||||
signalAddr string
|
||||
stunURLs string
|
||||
turnURLs string
|
||||
wgKey string
|
||||
wgInterface string
|
||||
wgLocalAddr string
|
||||
signalAddr string
|
||||
managementAddr string
|
||||
stunURLs string
|
||||
turnURLs string
|
||||
|
||||
initCmd = &cobra.Command{
|
||||
Use: "init",
|
||||
@@ -81,12 +83,13 @@ var (
|
||||
}
|
||||
|
||||
config := &Config{
|
||||
PrivateKey: wgKey,
|
||||
Peers: nil,
|
||||
StunTurnURLs: stunTurnURLs,
|
||||
SignalAddr: signalAddr,
|
||||
WgAddr: wgLocalAddr,
|
||||
WgIface: wgInterface,
|
||||
PrivateKey: wgKey,
|
||||
Peers: nil,
|
||||
StunTurnURLs: stunTurnURLs,
|
||||
SignalAddr: signalAddr,
|
||||
ManagementAddr: managementAddr,
|
||||
WgAddr: wgLocalAddr,
|
||||
WgIface: wgInterface,
|
||||
}
|
||||
|
||||
err = config.Write(configPath)
|
||||
@@ -105,14 +108,16 @@ func init() {
|
||||
initCmd.PersistentFlags().StringVar(&wgInterface, "wgInterface", "wiretrustee0", "Wireguard interface name, e.g. wiretreustee0 or wg0")
|
||||
initCmd.PersistentFlags().StringVar(&wgLocalAddr, "wgLocalAddr", "", "Wireguard local address, e.g. 10.30.30.1/24")
|
||||
initCmd.PersistentFlags().StringVar(&signalAddr, "signalAddr", "", "Signal server address, e.g. signal.wiretrustee.com:10000")
|
||||
initCmd.PersistentFlags().StringVar(&managementAddr, "managementAddr", "", "Management server address, e.g. management.wiretrustee.com:10000")
|
||||
initCmd.PersistentFlags().StringVar(&stunURLs, "stunURLs", "", "Comma separated STUN server URLs: protocol:host:port, e.g. stun:stun.l.google.com:19302,stun:stun1.l.google.com:19302")
|
||||
//todo user:password@protocol:host:port not the best way to pass TURN credentials, do it according to https://tools.ietf.org/html/rfc7065 E.g. use oauth
|
||||
initCmd.PersistentFlags().StringVar(&turnURLs, "turnURLs", "", "Comma separated TURN server URLs: user:password@protocol:host:port, e.g. user:password@turn:stun.wiretrustee.com:3468")
|
||||
//initCmd.MarkPersistentFlagRequired("configPath")
|
||||
initCmd.MarkPersistentFlagRequired("wgLocalAddr") //nolint
|
||||
initCmd.MarkPersistentFlagRequired("signalAddr") //nolint
|
||||
initCmd.MarkPersistentFlagRequired("stunURLs") //nolint
|
||||
initCmd.MarkPersistentFlagRequired("turnURLs") //nolint
|
||||
initCmd.MarkPersistentFlagRequired("wgLocalAddr") //nolint
|
||||
initCmd.MarkPersistentFlagRequired("signalAddr") //nolint
|
||||
initCmd.MarkPersistentFlagRequired("managementAddr") //nolint
|
||||
initCmd.MarkPersistentFlagRequired("stunURLs") //nolint
|
||||
initCmd.MarkPersistentFlagRequired("turnURLs") //nolint
|
||||
}
|
||||
|
||||
// generateKey generates a new Wireguard private key
|
||||
|
||||
+4
-1
@@ -2,10 +2,11 @@ package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/kardianos/service"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/kardianos/service"
|
||||
)
|
||||
|
||||
func Test_ServiceInstallCMD(t *testing.T) {
|
||||
@@ -65,6 +66,8 @@ func Test_ServiceRunCMD(t *testing.T) {
|
||||
"stun:stun.wiretrustee.com:3468",
|
||||
"--signalAddr",
|
||||
"signal.wiretrustee.com:10000",
|
||||
"--managementAddr",
|
||||
"management.wiretrustee.com:10000",
|
||||
"--turnURLs",
|
||||
"foo:bar@turn:stun.wiretrustee.com:3468",
|
||||
"--wgInterface",
|
||||
|
||||
@@ -2,15 +2,27 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/wiretrustee/wiretrustee/connection"
|
||||
"github.com/wiretrustee/wiretrustee/encryption"
|
||||
mgm "github.com/wiretrustee/wiretrustee/management/proto"
|
||||
sig "github.com/wiretrustee/wiretrustee/signal"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
"os"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/keepalive"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var (
|
||||
setupKey string
|
||||
|
||||
upCmd = &cobra.Command{
|
||||
Use: "up",
|
||||
Short: "start wiretrustee",
|
||||
@@ -28,8 +40,9 @@ var (
|
||||
os.Exit(ExitSetupFailed)
|
||||
}
|
||||
|
||||
var sigTLSEnabled = false
|
||||
go processManagement(config.ManagementAddr, setupKey, myKey)
|
||||
|
||||
var sigTLSEnabled = false
|
||||
ctx := context.Background()
|
||||
signalClient, err := sig.NewClient(ctx, config.SignalAddr, myKey, sigTLSEnabled)
|
||||
if err != nil {
|
||||
@@ -58,3 +71,107 @@ var (
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
upCmd.PersistentFlags().StringVar(&setupKey, "setupKey", "", "Setup key to join a network, if not specified a new network will be created")
|
||||
}
|
||||
|
||||
func processManagement(managementAddr string, setupKey string, ourPrivateKey wgtypes.Key) {
|
||||
err := connectToManagement(managementAddr, setupKey, ourPrivateKey)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to connect to managment server: %s", err)
|
||||
os.Exit(ExitSetupFailed)
|
||||
}
|
||||
|
||||
for {
|
||||
_ = connectToManagement(managementAddr, setupKey, ourPrivateKey)
|
||||
}
|
||||
}
|
||||
|
||||
func connectToManagement(managementAddr string, setupKey string, ourPrivateKey wgtypes.Key) error {
|
||||
log.Printf("Connecting to management server %s", managementAddr)
|
||||
mgmCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
mgmConn, err := grpc.DialContext(
|
||||
mgmCtx,
|
||||
managementAddr,
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithBlock(),
|
||||
grpc.WithKeepaliveParams(keepalive.ClientParameters{
|
||||
Time: 3 * time.Second,
|
||||
Timeout: 2 * time.Second,
|
||||
}))
|
||||
|
||||
if err != nil {
|
||||
return status.Errorf(codes.FailedPrecondition, "Error while connecting to the Management Service %s: %s", managementAddr, err)
|
||||
}
|
||||
defer mgmConn.Close()
|
||||
|
||||
log.Printf("Connected to management server %s", managementAddr)
|
||||
|
||||
mgmClient := mgm.NewManagementServiceClient(mgmConn)
|
||||
serverKeyResponse, err := mgmClient.GetServerKey(mgmCtx, &mgm.Empty{})
|
||||
if err != nil {
|
||||
return status.Errorf(codes.FailedPrecondition, "Error while getting server key: %s", err)
|
||||
}
|
||||
|
||||
serverKey, err := wgtypes.ParseKey(serverKeyResponse.Key)
|
||||
if err != nil {
|
||||
return status.Errorf(codes.FailedPrecondition, "Failed parsing Wireguard public server key %s: [%s]", serverKeyResponse.Key, err)
|
||||
}
|
||||
|
||||
_, err = mgmClient.RegisterPeer(mgmCtx, &mgm.RegisterPeerRequest{Key: ourPrivateKey.PublicKey().String(), SetupKey: setupKey})
|
||||
if err != nil {
|
||||
return status.Errorf(codes.FailedPrecondition, "Error while registering account: %s", err)
|
||||
}
|
||||
|
||||
log.Println("Peer registered")
|
||||
updatePeers(mgmClient, serverKey, ourPrivateKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
func updatePeers(mgmClient mgm.ManagementServiceClient, remotePubKey wgtypes.Key, ourPrivateKey wgtypes.Key) {
|
||||
log.Printf("Getting peers updates")
|
||||
ctx := context.Background()
|
||||
req := &mgm.SyncRequest{}
|
||||
encryptedReq, err := encryption.EncryptMessage(remotePubKey, ourPrivateKey, req)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to encrypt message: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
syncReq := &mgm.EncryptedMessage{WgPubKey: ourPrivateKey.PublicKey().String(), Body: encryptedReq}
|
||||
stream, err := mgmClient.Sync(ctx, syncReq)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to open management stream: %s", err)
|
||||
return
|
||||
}
|
||||
for {
|
||||
update, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
log.Errorf("Managment stream was closed: %s", err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Errorf("Managment stream disconnected: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Infof("Got peers update")
|
||||
resp := &mgm.SyncResponse{}
|
||||
err = encryption.DecryptMessage(remotePubKey, ourPrivateKey, update.Body, resp)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to decrypt message: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, peer := range resp.RemotePeers {
|
||||
log.Infof("Peer: %s", peer)
|
||||
_ = addPeer(peer.WgPubKey, strings.Join(peer.AllowedIps, ","))
|
||||
}
|
||||
|
||||
// for _, peer := range resp.RemotePeers {
|
||||
// log.Infof("Peer: %s", peer.WgPubKey)
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user