mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-22 08:03:30 +01:00
Peer configuration management (#69)
* feature: add config properties to the SyncResponse of the management gRpc service * fix: lint errors * chore: modify management protocol according to the review notes * fix: management proto fields sequence * feature: add proper peer configuration to be synced * chore: minor changes * feature: finalize peer config management * fix: lint errors * feature: add management server config file * refactor: extract hosts-config to a separate file * refactor: review notes applied to correct file_store usage * refactor: extract management service configuration to a file * refactor: simplify management config
This commit is contained in:
parent
c0c4c4a266
commit
2c2c1e19df
@ -16,9 +16,11 @@ docker run -d --name wiretrustee-management \
|
||||
-p 33073:33073 \
|
||||
-p 443:443 \
|
||||
-v /var/lib/wiretrustee/:/var/lib/wiretrustee/ \
|
||||
-v /etc/wiretrustee/:/etc/wiretrustee/ \
|
||||
wiretrustee/wiretrustee:management-v0.0.8-SNAPSHOT-079d35e-amd64 \
|
||||
--port 33073 \
|
||||
--datadir /var/lib/wiretrustee/ \
|
||||
--hosts-config /etc/wiretrustee/hosts-config.json \
|
||||
--letsencrypt-domain <YOUR-DOMAIN> \
|
||||
--log-level info
|
||||
```
|
||||
@ -91,13 +93,47 @@ Certificate:
|
||||
docker run -d --name wiretrustee-management \
|
||||
-p 33073:33073 \
|
||||
-v /var/lib/wiretrustee/:/var/lib/wiretrustee/ \
|
||||
-v /etc/wiretrustee/:/etc/wiretrustee/ \
|
||||
wiretrustee/wiretrustee:management-v0.0.8-SNAPSHOT-079d35e-amd64 \
|
||||
--port 33073 \
|
||||
--datadir /var/lib/wiretrustee/ \
|
||||
--hosts-config /etc/wiretrustee/hosts-config.json \
|
||||
--letsencrypt-domain app.wiretrustee.com \
|
||||
--log-level debug
|
||||
```
|
||||
|
||||
### hosts-config.json file example:
|
||||
|
||||
```json
|
||||
{
|
||||
"Stuns": [
|
||||
{
|
||||
"Proto": 2,
|
||||
"Host": "stun.wiretrustee.com",
|
||||
"Port": 3468,
|
||||
"Username": "",
|
||||
"Password": null
|
||||
}
|
||||
],
|
||||
"Turns": [
|
||||
{
|
||||
"Proto": 2,
|
||||
"Host": "stun.wiretrustee.com",
|
||||
"Port": 3468,
|
||||
"Username": "some_user",
|
||||
"Password": "c29tZV9wYXNzd29yZA=="
|
||||
}
|
||||
],
|
||||
"Signal": {
|
||||
"Proto": 2,
|
||||
"Host": "signal.wiretrustee.com",
|
||||
"Port": 10000,
|
||||
"Username": "",
|
||||
"Password": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## For development purposes:
|
||||
|
||||
Install golang gRpc tools:
|
||||
|
@ -3,7 +3,8 @@ package cmd
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
server2 "github.com/wiretrustee/wiretrustee/management/server"
|
||||
"github.com/wiretrustee/wiretrustee/management/server"
|
||||
"github.com/wiretrustee/wiretrustee/util"
|
||||
|
||||
"net"
|
||||
"os"
|
||||
@ -21,6 +22,7 @@ import (
|
||||
var (
|
||||
mgmtPort int
|
||||
mgmtDataDir string
|
||||
mgmtConfig string
|
||||
mgmtLetsencryptDomain string
|
||||
|
||||
kaep = keepalive.EnforcementPolicy{
|
||||
@ -41,24 +43,29 @@ var (
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
flag.Parse()
|
||||
|
||||
if _, err := os.Stat(mgmtDataDir); os.IsNotExist(err) {
|
||||
err = os.MkdirAll(mgmtDataDir, os.ModeDir)
|
||||
config, err := loadConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("failed reading provided config file: %s: %v", mgmtConfig, err)
|
||||
}
|
||||
|
||||
if _, err = os.Stat(config.Datadir); os.IsNotExist(err) {
|
||||
err = os.MkdirAll(config.Datadir, os.ModeDir)
|
||||
if err != nil {
|
||||
log.Fatalf("failed creating datadir: %s: %v", mgmtDataDir, err)
|
||||
log.Fatalf("failed creating datadir: %s: %v", config.Datadir, err)
|
||||
}
|
||||
}
|
||||
|
||||
var opts []grpc.ServerOption
|
||||
|
||||
if mgmtLetsencryptDomain != "" {
|
||||
transportCredentials := credentials.NewTLS(encryption.EnableLetsEncrypt(mgmtDataDir, mgmtLetsencryptDomain))
|
||||
if config.LetsEncryptDomain != "" {
|
||||
transportCredentials := credentials.NewTLS(encryption.EnableLetsEncrypt(config.Datadir, config.LetsEncryptDomain))
|
||||
opts = append(opts, grpc.Creds(transportCredentials))
|
||||
}
|
||||
|
||||
opts = append(opts, grpc.KeepaliveEnforcementPolicy(kaep), grpc.KeepaliveParams(kasp))
|
||||
grpcServer := grpc.NewServer(opts...)
|
||||
|
||||
server, err := server2.NewServer(mgmtDataDir)
|
||||
server, err := server.NewServer(config)
|
||||
if err != nil {
|
||||
log.Fatalf("failed creating new server: %v", err)
|
||||
}
|
||||
@ -83,8 +90,28 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func loadConfig() (*server.Config, error) {
|
||||
config := &server.Config{}
|
||||
_, err := util.ReadJson(mgmtConfig, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if mgmtLetsencryptDomain != "" {
|
||||
config.LetsEncryptDomain = mgmtLetsencryptDomain
|
||||
}
|
||||
if mgmtDataDir != "" {
|
||||
config.Datadir = mgmtDataDir
|
||||
}
|
||||
|
||||
return config, err
|
||||
}
|
||||
|
||||
func init() {
|
||||
mgmtCmd.Flags().IntVar(&mgmtPort, "port", 33073, "server port to listen on")
|
||||
mgmtCmd.Flags().StringVar(&mgmtDataDir, "datadir", "/var/lib/wiretrustee/", "server data directory location")
|
||||
mgmtCmd.Flags().StringVar(&mgmtConfig, "config", "/etc/wiretrustee/management.json", "Wiretrustee config file location. Config params specified via command line (e.g. datadir) have a precedence over configuration from this file")
|
||||
mgmtCmd.Flags().StringVar(&mgmtLetsencryptDomain, "letsencrypt-domain", "", "a domain to issue Let's Encrypt certificate for. Enables TLS using Let's Encrypt. Will fetch and renew certificate, and run the server with TLS")
|
||||
|
||||
rootCmd.MarkFlagRequired("config") //nolint
|
||||
|
||||
}
|
||||
|
@ -24,22 +24,28 @@ const (
|
||||
type HostConfig_Protocol int32
|
||||
|
||||
const (
|
||||
HostConfig_PLAIN HostConfig_Protocol = 0
|
||||
HostConfig_TLS HostConfig_Protocol = 1
|
||||
HostConfig_DTLS HostConfig_Protocol = 2
|
||||
HostConfig_UDP HostConfig_Protocol = 0
|
||||
HostConfig_TCP HostConfig_Protocol = 1
|
||||
HostConfig_HTTP HostConfig_Protocol = 2
|
||||
HostConfig_HTTPS HostConfig_Protocol = 3
|
||||
HostConfig_DTLS HostConfig_Protocol = 4
|
||||
)
|
||||
|
||||
// Enum value maps for HostConfig_Protocol.
|
||||
var (
|
||||
HostConfig_Protocol_name = map[int32]string{
|
||||
0: "PLAIN",
|
||||
1: "TLS",
|
||||
2: "DTLS",
|
||||
0: "UDP",
|
||||
1: "TCP",
|
||||
2: "HTTP",
|
||||
3: "HTTPS",
|
||||
4: "DTLS",
|
||||
}
|
||||
HostConfig_Protocol_value = map[string]int32{
|
||||
"PLAIN": 0,
|
||||
"TLS": 1,
|
||||
"DTLS": 2,
|
||||
"UDP": 0,
|
||||
"TCP": 1,
|
||||
"HTTP": 2,
|
||||
"HTTPS": 3,
|
||||
"DTLS": 4,
|
||||
}
|
||||
)
|
||||
|
||||
@ -175,8 +181,6 @@ type SyncResponse struct {
|
||||
WiretrusteeConfig *WiretrusteeConfig `protobuf:"bytes,1,opt,name=wiretrusteeConfig,proto3" json:"wiretrusteeConfig,omitempty"`
|
||||
PeerConfig *PeerConfig `protobuf:"bytes,2,opt,name=peerConfig,proto3" json:"peerConfig,omitempty"`
|
||||
RemotePeers []*RemotePeerConfig `protobuf:"bytes,3,rep,name=remotePeers,proto3" json:"remotePeers,omitempty"`
|
||||
// Deprecated: used for compatibility
|
||||
Peers []string `protobuf:"bytes,4,rep,name=peers,proto3" json:"peers,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SyncResponse) Reset() {
|
||||
@ -232,13 +236,6 @@ func (x *SyncResponse) GetRemotePeers() []*RemotePeerConfig {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SyncResponse) GetPeers() []string {
|
||||
if x != nil {
|
||||
return x.Peers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RegisterPeerRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -502,9 +499,9 @@ type HostConfig struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"`
|
||||
Port int32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"`
|
||||
Protocol HostConfig_Protocol `protobuf:"varint,3,opt,name=protocol,proto3,enum=management.HostConfig_Protocol" json:"protocol,omitempty"`
|
||||
// URI of the resource e.g. turns://stun.wiretrustee.com:4430 or signal.wiretrustee.com:10000
|
||||
Uri string `protobuf:"bytes,1,opt,name=uri,proto3" json:"uri,omitempty"`
|
||||
Protocol HostConfig_Protocol `protobuf:"varint,2,opt,name=protocol,proto3,enum=management.HostConfig_Protocol" json:"protocol,omitempty"`
|
||||
}
|
||||
|
||||
func (x *HostConfig) Reset() {
|
||||
@ -539,25 +536,18 @@ func (*HostConfig) Descriptor() ([]byte, []int) {
|
||||
return file_management_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *HostConfig) GetHost() string {
|
||||
func (x *HostConfig) GetUri() string {
|
||||
if x != nil {
|
||||
return x.Host
|
||||
return x.Uri
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *HostConfig) GetPort() int32 {
|
||||
if x != nil {
|
||||
return x.Port
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *HostConfig) GetProtocol() HostConfig_Protocol {
|
||||
if x != nil {
|
||||
return x.Protocol
|
||||
}
|
||||
return HostConfig_PLAIN
|
||||
return HostConfig_UDP
|
||||
}
|
||||
|
||||
// ProtectedHostConfig is similar to HostConfig but has additional user and password
|
||||
@ -755,7 +745,7 @@ var file_management_proto_rawDesc = []byte{
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x67, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62,
|
||||
0x6f, 0x64, 0x79, 0x22, 0x0d, 0x0a, 0x0b, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x22, 0xe9, 0x01, 0x0a, 0x0c, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x73, 0x74, 0x22, 0xd3, 0x01, 0x0a, 0x0c, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x11, 0x77, 0x69, 0x72, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74,
|
||||
0x65, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d,
|
||||
0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x57, 0x69, 0x72, 0x65,
|
||||
@ -768,78 +758,76 @@ var file_management_proto_rawDesc = []byte{
|
||||
0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
|
||||
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74,
|
||||
0x65, 0x50, 0x65, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x72, 0x65, 0x6d,
|
||||
0x6f, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x65, 0x65, 0x72,
|
||||
0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x22, 0x43,
|
||||
0x0a, 0x13, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x75, 0x70,
|
||||
0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x74, 0x75, 0x70,
|
||||
0x4b, 0x65, 0x79, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50,
|
||||
0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5f, 0x0a, 0x11, 0x53,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
|
||||
0x65, 0x79, 0x12, 0x38, 0x0a, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x22, 0x07, 0x0a, 0x05,
|
||||
0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xa8, 0x01, 0x0a, 0x11, 0x57, 0x69, 0x72, 0x65, 0x74, 0x72,
|
||||
0x75, 0x73, 0x74, 0x65, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2c, 0x0a, 0x05, 0x73,
|
||||
0x74, 0x75, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x61, 0x6e,
|
||||
0x6f, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x73, 0x22, 0x43, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69,
|
||||
0x73, 0x74, 0x65, 0x72, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x74, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x22, 0x16, 0x0a,
|
||||
0x14, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5f, 0x0a, 0x11, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b,
|
||||
0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x38, 0x0a, 0x09,
|
||||
0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70,
|
||||
0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22,
|
||||
0xa8, 0x01, 0x0a, 0x11, 0x57, 0x69, 0x72, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x65, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2c, 0x0a, 0x05, 0x73, 0x74, 0x75, 0x6e, 0x73, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x05, 0x73, 0x74,
|
||||
0x75, 0x6e, 0x73, 0x12, 0x35, 0x0a, 0x05, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
|
||||
0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x52, 0x05, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x61, 0x6e,
|
||||
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x52, 0x05, 0x73, 0x74, 0x75, 0x6e, 0x73, 0x12, 0x35, 0x0a, 0x05, 0x74, 0x75, 0x72,
|
||||
0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
||||
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x48,
|
||||
0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x05, 0x74, 0x75, 0x72, 0x6e, 0x73,
|
||||
0x12, 0x2e, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x69, 0x67, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x22, 0x98, 0x01, 0x0a, 0x0a, 0x48,
|
||||
0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x3b, 0x0a, 0x08, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e,
|
||||
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x3b, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a,
|
||||
0x03, 0x54, 0x43, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x02,
|
||||
0x12, 0x09, 0x0a, 0x05, 0x48, 0x54, 0x54, 0x50, 0x53, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x44,
|
||||
0x54, 0x4c, 0x53, 0x10, 0x04, 0x22, 0x7d, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74,
|
||||
0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x0a,
|
||||
0x68, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x16, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x48, 0x6f,
|
||||
0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c,
|
||||
0x22, 0x9b, 0x01, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68,
|
||||
0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3b, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x6d, 0x61, 0x6e, 0x61,
|
||||
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x28, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
|
||||
0x12, 0x09, 0x0a, 0x05, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x54,
|
||||
0x4c, 0x53, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x54, 0x4c, 0x53, 0x10, 0x02, 0x22, 0x7d,
|
||||
0x0a, 0x13, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x0a, 0x68, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x61, 0x6e, 0x61,
|
||||
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x52, 0x0a, 0x68, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65,
|
||||
0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x38, 0x0a,
|
||||
0x0a, 0x50, 0x65, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61,
|
||||
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64,
|
||||
0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x03, 0x64, 0x6e, 0x73, 0x22, 0x4e, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x74,
|
||||
0x65, 0x50, 0x65, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x77,
|
||||
0x67, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77,
|
||||
0x67, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77,
|
||||
0x65, 0x64, 0x49, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x6c, 0x6c,
|
||||
0x6f, 0x77, 0x65, 0x64, 0x49, 0x70, 0x73, 0x32, 0xa9, 0x02, 0x0a, 0x11, 0x4d, 0x61, 0x6e, 0x61,
|
||||
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x53, 0x0a,
|
||||
0x0c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1f, 0x2e,
|
||||
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73,
|
||||
0x74, 0x65, 0x72, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20,
|
||||
0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69,
|
||||
0x73, 0x74, 0x65, 0x72, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x00, 0x12, 0x46, 0x0a, 0x04, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e,
|
||||
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65,
|
||||
0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
||||
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x0c, 0x47, 0x65,
|
||||
0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e,
|
||||
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e,
|
||||
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65,
|
||||
0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x33,
|
||||
0x0a, 0x09, 0x69, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61,
|
||||
0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11,
|
||||
0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||
0x79, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x68, 0x6f, 0x73, 0x74, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73,
|
||||
0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73,
|
||||
0x77, 0x6f, 0x72, 0x64, 0x22, 0x38, 0x0a, 0x0a, 0x50, 0x65, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03,
|
||||
0x64, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x6e, 0x73, 0x22, 0x4e,
|
||||
0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x67, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x67, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x1e,
|
||||
0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x49, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x49, 0x70, 0x73, 0x32, 0xa9,
|
||||
0x02, 0x0a, 0x11, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x12, 0x53, 0x0a, 0x0c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
|
||||
0x50, 0x65, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x65, 0x65, 0x72, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x04, 0x53, 0x79, 0x6e,
|
||||
0x63, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45,
|
||||
0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a,
|
||||
0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63,
|
||||
0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30,
|
||||
0x01, 0x12, 0x42, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65,
|
||||
0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45,
|
||||
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x09, 0x69, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74,
|
||||
0x68, 0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
|
||||
0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -41,9 +41,6 @@ message SyncResponse {
|
||||
PeerConfig peerConfig = 2;
|
||||
|
||||
repeated RemotePeerConfig remotePeers = 3;
|
||||
|
||||
// Deprecated: used for compatibility
|
||||
repeated string peers = 4;
|
||||
}
|
||||
|
||||
message RegisterPeerRequest {
|
||||
@ -78,14 +75,16 @@ message WiretrusteeConfig {
|
||||
|
||||
// HostConfig describes connection properties of some server (e.g. STUN, Signal, Management)
|
||||
message HostConfig {
|
||||
string host = 1;
|
||||
int32 port = 2;
|
||||
Protocol protocol = 3;
|
||||
// URI of the resource e.g. turns://stun.wiretrustee.com:4430 or signal.wiretrustee.com:10000
|
||||
string uri = 1;
|
||||
Protocol protocol = 2;
|
||||
|
||||
enum Protocol {
|
||||
PLAIN = 0;
|
||||
TLS = 1;
|
||||
DTLS = 2;
|
||||
UDP = 0;
|
||||
TCP = 1;
|
||||
HTTP = 2;
|
||||
HTTPS = 3;
|
||||
DTLS = 4;
|
||||
}
|
||||
}
|
||||
// ProtectedHostConfig is similar to HostConfig but has additional user and password
|
||||
|
119
management/server/account.go
Normal file
119
management/server/account.go
Normal file
@ -0,0 +1,119 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"net"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type AccountManager struct {
|
||||
Store Store
|
||||
// mutex to synchronise account operations (e.g. generating Peer IP address inside the Network)
|
||||
mux sync.Mutex
|
||||
}
|
||||
|
||||
// Account represents a unique account of the system
|
||||
type Account struct {
|
||||
Id string
|
||||
SetupKeys map[string]*SetupKey
|
||||
Network *Network
|
||||
Peers []*Peer
|
||||
}
|
||||
|
||||
// SetupKey represents a pre-authorized key used to register machines (peers)
|
||||
// One key might have multiple machines
|
||||
type SetupKey struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
// Peer represents a machine connected to the network.
|
||||
// The Peer is a Wireguard peer identified by a public key
|
||||
type Peer struct {
|
||||
// Wireguard public key
|
||||
Key string
|
||||
// A setup key this peer was registered with
|
||||
SetupKey *SetupKey
|
||||
// IP address of the Peer
|
||||
IP net.IP
|
||||
}
|
||||
|
||||
// NewManager creates a new AccountManager with a provided Store
|
||||
func NewManager(store Store) *AccountManager {
|
||||
return &AccountManager{
|
||||
Store: store,
|
||||
mux: sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
// GetPeer returns a peer from a Store
|
||||
func (manager *AccountManager) GetPeer(peerKey string) (*Peer, error) {
|
||||
manager.mux.Lock()
|
||||
defer manager.mux.Unlock()
|
||||
|
||||
peer, err := manager.Store.GetPeer(peerKey)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.NotFound, "provided peer key doesn't exists %s", peerKey)
|
||||
}
|
||||
|
||||
return peer, nil
|
||||
}
|
||||
|
||||
// GetPeersForAPeer returns a list of peers available for a given peer (key)
|
||||
// Effectively all the peers of the original peer's account except for the peer itself
|
||||
func (manager *AccountManager) GetPeersForAPeer(peerKey string) ([]*Peer, error) {
|
||||
manager.mux.Lock()
|
||||
defer manager.mux.Unlock()
|
||||
|
||||
account, err := manager.Store.GetPeerAccount(peerKey)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Invalid peer key %s", peerKey)
|
||||
}
|
||||
|
||||
var res []*Peer
|
||||
for _, peer := range account.Peers {
|
||||
if peer.Key != peerKey {
|
||||
res = append(res, peer)
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// AddPeer adds a new peer to the Store.
|
||||
// Each Account has a list of pre-authorised SetupKey and if no Account has a given key err wit ha code codes.Unauthenticated
|
||||
// will be returned, meaning the key is invalid
|
||||
// Each new Peer will be assigned a new next net.IP from the Account.Network and Account.Network.LastIP will be updated (IP's are not reused).
|
||||
func (manager *AccountManager) AddPeer(setupKey string, peerKey string) (*Peer, error) {
|
||||
manager.mux.Lock()
|
||||
defer manager.mux.Unlock()
|
||||
|
||||
account, err := manager.Store.GetAccountBySetupKey(setupKey)
|
||||
if err != nil {
|
||||
//todo
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var takenIps []net.IP
|
||||
for _, peer := range account.Peers {
|
||||
takenIps = append(takenIps, peer.IP)
|
||||
}
|
||||
|
||||
network := account.Network
|
||||
nextIp, _ := AllocatePeerIP(network.Net, takenIps)
|
||||
|
||||
newPeer := &Peer{
|
||||
Key: peerKey,
|
||||
SetupKey: &SetupKey{Key: setupKey},
|
||||
IP: nextIp,
|
||||
}
|
||||
|
||||
account.Peers = append(account.Peers, newPeer)
|
||||
err = manager.Store.SaveAccount(account)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed adding peer")
|
||||
}
|
||||
|
||||
return newPeer, nil
|
||||
|
||||
}
|
30
management/server/config.go
Normal file
30
management/server/config.go
Normal file
@ -0,0 +1,30 @@
|
||||
package server
|
||||
|
||||
type Protocol string
|
||||
|
||||
const (
|
||||
UDP Protocol = "udp"
|
||||
DTLS Protocol = "dtls"
|
||||
TCP Protocol = "tcp"
|
||||
HTTP Protocol = "http"
|
||||
HTTPS Protocol = "https"
|
||||
)
|
||||
|
||||
// Config of the Management service
|
||||
type Config struct {
|
||||
Stuns []*Host
|
||||
Turns []*Host
|
||||
Signal *Host
|
||||
|
||||
Datadir string
|
||||
LetsEncryptDomain string
|
||||
}
|
||||
|
||||
// Host represents a Wiretrustee host (e.g. STUN, TURN, Signal)
|
||||
type Host struct {
|
||||
Proto Protocol
|
||||
// URI e.g. turns://stun.wiretrustee.com:4430 or signal.wiretrustee.com:10000
|
||||
URI string
|
||||
Username string
|
||||
Password []byte
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package store
|
||||
package server
|
||||
|
||||
import (
|
||||
"os"
|
||||
@ -26,6 +26,9 @@ type FileStore struct {
|
||||
storeFile string `json:"-"`
|
||||
}
|
||||
|
||||
type StoredAccount struct {
|
||||
}
|
||||
|
||||
// NewStore restores a store from the file located in the datadir
|
||||
func NewStore(dataDir string) (*FileStore, error) {
|
||||
return restore(filepath.Join(dataDir, storeFileName))
|
||||
@ -59,15 +62,13 @@ func restore(file string) (*FileStore, error) {
|
||||
store := read.(*FileStore)
|
||||
store.storeFile = file
|
||||
store.SetupKeyId2AccountId = make(map[string]string)
|
||||
store.PeerKeyId2AccountId = make(map[string]string)
|
||||
for accountId, account := range store.Accounts {
|
||||
for setupKeyId := range account.SetupKeys {
|
||||
store.SetupKeyId2AccountId[strings.ToLower(setupKeyId)] = accountId
|
||||
}
|
||||
}
|
||||
store.PeerKeyId2AccountId = make(map[string]string)
|
||||
for accountId, account := range store.Accounts {
|
||||
for peerId := range account.Peers {
|
||||
store.PeerKeyId2AccountId[strings.ToLower(peerId)] = accountId
|
||||
for _, peer := range account.Peers {
|
||||
store.PeerKeyId2AccountId[strings.ToLower(peer.Key)] = accountId
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,47 +81,32 @@ func (s *FileStore) persist(file string) error {
|
||||
return util.WriteJson(file, s)
|
||||
}
|
||||
|
||||
// PeerExists checks whether peer exists or not
|
||||
func (s *FileStore) PeerExists(peerKey string) bool {
|
||||
// GetPeer returns a peer from a Store
|
||||
func (s *FileStore) GetPeer(peerKey string) (*Peer, error) {
|
||||
s.mux.Lock()
|
||||
defer s.mux.Unlock()
|
||||
|
||||
_, accountIdFound := s.PeerKeyId2AccountId[peerKey]
|
||||
return accountIdFound
|
||||
}
|
||||
|
||||
// AddPeer adds peer to the store and associates it with a Account and a SetupKey. Returns related Account
|
||||
// Each Account has a list of pre-authorised SetupKey and if no Account has a given key err will be returned, meaning the key is invalid
|
||||
func (s *FileStore) AddPeer(setupKey string, peerKey string) error {
|
||||
s.mux.Lock()
|
||||
defer s.mux.Unlock()
|
||||
|
||||
accountId, accountIdFound := s.SetupKeyId2AccountId[strings.ToLower(setupKey)]
|
||||
accountId, accountIdFound := s.PeerKeyId2AccountId[peerKey]
|
||||
if !accountIdFound {
|
||||
return status.Errorf(codes.NotFound, "Provided setup key doesn't exists")
|
||||
return nil, status.Errorf(codes.Internal, "account not found")
|
||||
}
|
||||
|
||||
account, accountFound := s.Accounts[accountId]
|
||||
if !accountFound {
|
||||
return status.Errorf(codes.Internal, "Invalid setup key")
|
||||
}
|
||||
|
||||
key, setupKeyFound := account.SetupKeys[strings.ToLower(setupKey)]
|
||||
if !setupKeyFound {
|
||||
return status.Errorf(codes.Internal, "Invalid setup key")
|
||||
}
|
||||
|
||||
account.Peers[peerKey] = &Peer{Key: peerKey, SetupKey: key}
|
||||
s.PeerKeyId2AccountId[peerKey] = accountId
|
||||
err := s.persist(s.storeFile)
|
||||
account, err := s.GetAccount(accountId)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
return nil
|
||||
|
||||
for _, peer := range account.Peers {
|
||||
if peer.Key == peerKey {
|
||||
return peer, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, status.Errorf(codes.NotFound, "peer not found")
|
||||
}
|
||||
|
||||
// AddAccount adds new account to the store.
|
||||
func (s *FileStore) AddAccount(account *Account) error {
|
||||
// SaveAccount updates an existing account or adds a new one
|
||||
func (s *FileStore) SaveAccount(account *Account) error {
|
||||
s.mux.Lock()
|
||||
defer s.mux.Unlock()
|
||||
|
||||
@ -133,6 +119,10 @@ func (s *FileStore) AddAccount(account *Account) error {
|
||||
s.SetupKeyId2AccountId[strings.ToLower(keyId)] = account.Id
|
||||
}
|
||||
|
||||
for _, peer := range account.Peers {
|
||||
s.PeerKeyId2AccountId[peer.Key] = account.Id
|
||||
}
|
||||
|
||||
err := s.persist(s.storeFile)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -141,9 +131,32 @@ func (s *FileStore) AddAccount(account *Account) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetPeersForAPeer returns a list of peers available for a given peer (key)
|
||||
// Effectively all the peers of the original peer's account if any
|
||||
func (s *FileStore) GetPeersForAPeer(peerKey string) ([]string, error) {
|
||||
func (s *FileStore) GetAccountBySetupKey(setupKey string) (*Account, error) {
|
||||
|
||||
accountId, accountIdFound := s.SetupKeyId2AccountId[strings.ToLower(setupKey)]
|
||||
if !accountIdFound {
|
||||
return nil, status.Errorf(codes.NotFound, "provided setup key doesn't exists")
|
||||
}
|
||||
|
||||
account, err := s.GetAccount(accountId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func (s *FileStore) GetAccount(accountId string) (*Account, error) {
|
||||
|
||||
account, accountFound := s.Accounts[accountId]
|
||||
if !accountFound {
|
||||
return nil, status.Errorf(codes.Internal, "account not found")
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func (s *FileStore) GetPeerAccount(peerKey string) (*Account, error) {
|
||||
s.mux.Lock()
|
||||
defer s.mux.Unlock()
|
||||
|
||||
@ -152,16 +165,5 @@ func (s *FileStore) GetPeersForAPeer(peerKey string) ([]string, error) {
|
||||
return nil, status.Errorf(codes.NotFound, "Provided peer key doesn't exists %s", peerKey)
|
||||
}
|
||||
|
||||
account, accountFound := s.Accounts[accountId]
|
||||
if !accountFound {
|
||||
return nil, status.Errorf(codes.Internal, "Invalid peer key %s", peerKey)
|
||||
}
|
||||
peers := make([]string, 0, len(account.Peers))
|
||||
for p := range account.Peers {
|
||||
if p != peerKey {
|
||||
peers = append(peers, p)
|
||||
}
|
||||
}
|
||||
|
||||
return peers, nil
|
||||
return s.GetAccount(accountId)
|
||||
}
|
@ -2,7 +2,7 @@ package server_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
server2 "github.com/wiretrustee/wiretrustee/management/server"
|
||||
server "github.com/wiretrustee/wiretrustee/management/server"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net"
|
||||
@ -33,7 +33,7 @@ var _ = Describe("Management service", func() {
|
||||
|
||||
var (
|
||||
addr string
|
||||
server *grpc.Server
|
||||
s *grpc.Server
|
||||
dataDir string
|
||||
client mgmtProto.ManagementServiceClient
|
||||
serverPubKey wgtypes.Key
|
||||
@ -50,11 +50,17 @@ var _ = Describe("Management service", func() {
|
||||
err = util.CopyFileContents("testdata/store.json", filepath.Join(dataDir, "store.json"))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
var listener net.Listener
|
||||
server, listener = startServer(dataDir)
|
||||
|
||||
config := &server.Config{}
|
||||
_, err = util.ReadJson("testdata/management.json", config)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
config.Datadir = dataDir
|
||||
|
||||
s, listener = startServer(config)
|
||||
addr = listener.Addr().String()
|
||||
client, conn = createRawClient(addr)
|
||||
|
||||
// server public key
|
||||
// s public key
|
||||
resp, err := client.GetServerKey(context.TODO(), &mgmtProto.Empty{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
serverPubKey, err = wgtypes.ParseKey(resp.Key)
|
||||
@ -63,7 +69,7 @@ var _ = Describe("Management service", func() {
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
server.Stop()
|
||||
s.Stop()
|
||||
err := conn.Close()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
err = os.RemoveAll(dataDir)
|
||||
@ -82,6 +88,54 @@ var _ = Describe("Management service", func() {
|
||||
|
||||
Context("when calling Sync endpoint", func() {
|
||||
|
||||
Context("when there is a new peer registered", func() {
|
||||
Specify("a proper configuration is returned", func() {
|
||||
key, _ := wgtypes.GenerateKey()
|
||||
registerPeerWithValidSetupKey(key, client)
|
||||
|
||||
encryptedBytes, err := encryption.EncryptMessage(serverPubKey, key, &mgmtProto.SyncRequest{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
sync, err := client.Sync(context.TODO(), &mgmtProto.EncryptedMessage{
|
||||
WgPubKey: key.PublicKey().String(),
|
||||
Body: encryptedBytes,
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
encryptedResponse := &mgmtProto.EncryptedMessage{}
|
||||
err = sync.RecvMsg(encryptedResponse)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
resp := &mgmtProto.SyncResponse{}
|
||||
err = encryption.DecryptMessage(serverPubKey, key, encryptedResponse.Body, resp)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(resp.PeerConfig.Address).To(BeEquivalentTo("100.64.0.1"))
|
||||
|
||||
expectedSignalConfig := &mgmtProto.HostConfig{
|
||||
Uri: "signal.wiretrustee.com:10000",
|
||||
Protocol: mgmtProto.HostConfig_HTTP,
|
||||
}
|
||||
expectedStunsConfig := &mgmtProto.HostConfig{
|
||||
Uri: "stun:stun.wiretrustee.com:3468",
|
||||
Protocol: mgmtProto.HostConfig_UDP,
|
||||
}
|
||||
expectedTurnsConfig := &mgmtProto.ProtectedHostConfig{
|
||||
HostConfig: &mgmtProto.HostConfig{
|
||||
Uri: "turn:stun.wiretrustee.com:3468",
|
||||
Protocol: mgmtProto.HostConfig_UDP,
|
||||
},
|
||||
User: "some_user",
|
||||
Password: "some_password",
|
||||
}
|
||||
|
||||
Expect(resp.WiretrusteeConfig.Signal).To(BeEquivalentTo(expectedSignalConfig))
|
||||
Expect(resp.WiretrusteeConfig.Stuns).To(ConsistOf(expectedStunsConfig))
|
||||
Expect(resp.WiretrusteeConfig.Turns).To(ConsistOf(expectedTurnsConfig))
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
Context("when there are 3 peers registered under one account", func() {
|
||||
Specify("a list containing other 2 peers is returned", func() {
|
||||
key, _ := wgtypes.GenerateKey()
|
||||
@ -112,8 +166,9 @@ var _ = Describe("Management service", func() {
|
||||
err = pb.Unmarshal(decryptedBytes, resp)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(resp.GetPeers()).To(HaveLen(2))
|
||||
Expect(resp.GetPeers()).To(ContainElements(key1.PublicKey().String(), key2.PublicKey().String()))
|
||||
Expect(resp.GetRemotePeers()).To(HaveLen(2))
|
||||
peers := []string{resp.GetRemotePeers()[0].WgPubKey, resp.GetRemotePeers()[1].WgPubKey}
|
||||
Expect(peers).To(ContainElements(key1.PublicKey().String(), key2.PublicKey().String()))
|
||||
|
||||
})
|
||||
})
|
||||
@ -143,7 +198,7 @@ var _ = Describe("Management service", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
resp := &mgmtProto.SyncResponse{}
|
||||
err = pb.Unmarshal(decryptedBytes, resp)
|
||||
Expect(resp.GetPeers()).To(HaveLen(0))
|
||||
Expect(resp.GetRemotePeers()).To(HaveLen(0))
|
||||
|
||||
wg := sync2.WaitGroup{}
|
||||
wg.Add(1)
|
||||
@ -167,8 +222,8 @@ var _ = Describe("Management service", func() {
|
||||
wg.Wait()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(resp.GetPeers()).To(ContainElements(key1.PublicKey().String()))
|
||||
Expect(resp.GetPeers()).To(HaveLen(1))
|
||||
Expect(resp.GetRemotePeers()).To(HaveLen(1))
|
||||
Expect(resp.GetRemotePeers()[0].WgPubKey).To(BeEquivalentTo(key1.PublicKey().String()))
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -291,6 +346,52 @@ var _ = Describe("Management service", func() {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("when there are peers registered under one account concurrently", func() {
|
||||
Specify("then there are no duplicate IPs", func() {
|
||||
|
||||
initialPeers := 30
|
||||
|
||||
ipChannel := make(chan string, 20)
|
||||
for i := 0; i < initialPeers; i++ {
|
||||
go func() {
|
||||
key, _ := wgtypes.GenerateKey()
|
||||
registerPeerWithValidSetupKey(key, client)
|
||||
encryptedBytes, err := encryption.EncryptMessage(serverPubKey, key, &mgmtProto.SyncRequest{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// open stream
|
||||
sync, err := client.Sync(context.TODO(), &mgmtProto.EncryptedMessage{
|
||||
WgPubKey: key.PublicKey().String(),
|
||||
Body: encryptedBytes,
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
encryptedResponse := &mgmtProto.EncryptedMessage{}
|
||||
err = sync.RecvMsg(encryptedResponse)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
resp := &mgmtProto.SyncResponse{}
|
||||
err = encryption.DecryptMessage(serverPubKey, key, encryptedResponse.Body, resp)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
ipChannel <- resp.GetPeerConfig().Address
|
||||
|
||||
}()
|
||||
}
|
||||
|
||||
ips := make(map[string]struct{})
|
||||
for ip := range ipChannel {
|
||||
if _, ok := ips[ip]; ok {
|
||||
Fail("found duplicate IP: " + ip)
|
||||
}
|
||||
ips[ip] = struct{}{}
|
||||
if len(ips) == initialPeers {
|
||||
break
|
||||
}
|
||||
}
|
||||
close(ipChannel)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
func registerPeerWithValidSetupKey(key wgtypes.Key, client mgmtProto.ManagementServiceClient) *mgmtProto.RegisterPeerResponse {
|
||||
@ -320,13 +421,13 @@ func createRawClient(addr string) (mgmtProto.ManagementServiceClient, *grpc.Clie
|
||||
return mgmtProto.NewManagementServiceClient(conn), conn
|
||||
}
|
||||
|
||||
func startServer(dataDir string) (*grpc.Server, net.Listener) {
|
||||
func startServer(config *server.Config) (*grpc.Server, net.Listener) {
|
||||
lis, err := net.Listen("tcp", ":0")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
s := grpc.NewServer()
|
||||
server, err := server2.NewServer(dataDir)
|
||||
mgmtServer, err := server.NewServer(config)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
mgmtProto.RegisterManagementServiceServer(s, server)
|
||||
mgmtProto.RegisterManagementServiceServer(s, mgmtServer)
|
||||
go func() {
|
||||
if err := s.Serve(lis); err != nil {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
69
management/server/network.go
Normal file
69
management/server/network.go
Normal file
@ -0,0 +1,69 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
var (
|
||||
upperIPv4 = []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 255, 255, 255, 255}
|
||||
upperIPv6 = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
|
||||
)
|
||||
|
||||
type Network struct {
|
||||
Id string
|
||||
Net net.IPNet
|
||||
Dns string
|
||||
}
|
||||
|
||||
// AllocatePeerIP pics an available IP from an net.IPNet.
|
||||
// This method considers already taken IPs and reuses IPs if there are gaps in takenIps
|
||||
// E.g. if ipNet=100.30.0.0/16 and takenIps=[100.30.0.1, 100.30.0.5] then the result would be 100.30.0.2
|
||||
func AllocatePeerIP(ipNet net.IPNet, takenIps []net.IP) (net.IP, error) {
|
||||
takenIpMap := make(map[string]net.IP)
|
||||
takenIpMap[ipNet.IP.String()] = ipNet.IP
|
||||
for _, ip := range takenIps {
|
||||
takenIpMap[ip.String()] = ip
|
||||
}
|
||||
for ip := ipNet.IP.Mask(ipNet.Mask); ipNet.Contains(ip); ip = GetNextIP(ip) {
|
||||
if _, ok := takenIpMap[ip.String()]; !ok {
|
||||
return ip, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("failed allocating new IP for the ipNet %s and takenIps %s", ipNet.String(), takenIps)
|
||||
}
|
||||
|
||||
// GetNextIP returns the next IP from the given IP address. If the given IP is
|
||||
// the last IP of a v4 or v6 range, the same IP is returned.
|
||||
// Credits to Cilium team.
|
||||
// Copyright 2017-2020 Authors of Cilium
|
||||
func GetNextIP(ip net.IP) net.IP {
|
||||
if ip.Equal(upperIPv4) || ip.Equal(upperIPv6) {
|
||||
return ip
|
||||
}
|
||||
|
||||
nextIP := make(net.IP, len(ip))
|
||||
switch len(ip) {
|
||||
case net.IPv4len:
|
||||
ipU32 := binary.BigEndian.Uint32(ip)
|
||||
ipU32++
|
||||
binary.BigEndian.PutUint32(nextIP, ipU32)
|
||||
return nextIP
|
||||
case net.IPv6len:
|
||||
ipU64 := binary.BigEndian.Uint64(ip[net.IPv6len/2:])
|
||||
ipU64++
|
||||
binary.BigEndian.PutUint64(nextIP[net.IPv6len/2:], ipU64)
|
||||
if ipU64 == 0 {
|
||||
ipU64 = binary.BigEndian.Uint64(ip[:net.IPv6len/2])
|
||||
ipU64++
|
||||
binary.BigEndian.PutUint64(nextIP[:net.IPv6len/2], ipU64)
|
||||
} else {
|
||||
copy(nextIP[:net.IPv6len/2], ip[:net.IPv6len/2])
|
||||
}
|
||||
return nextIP
|
||||
default:
|
||||
return ip
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/wiretrustee/wiretrustee/management/store"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -17,33 +17,38 @@ import (
|
||||
|
||||
// Server an instance of a Management server
|
||||
type Server struct {
|
||||
Store *store.FileStore
|
||||
wgKey wgtypes.Key
|
||||
accountManager *AccountManager
|
||||
wgKey wgtypes.Key
|
||||
proto.UnimplementedManagementServiceServer
|
||||
peerChannels map[string]chan *UpdateChannelMessage
|
||||
channelsMux *sync.Mutex
|
||||
config *Config
|
||||
}
|
||||
|
||||
// AllowedIPsFormat generates Wireguard AllowedIPs format (e.g. 100.30.30.1/32)
|
||||
const AllowedIPsFormat = "%s/32"
|
||||
|
||||
type UpdateChannelMessage struct {
|
||||
Update *proto.SyncResponse
|
||||
}
|
||||
|
||||
// NewServer creates a new Management server
|
||||
func NewServer(dataDir string) (*Server, error) {
|
||||
func NewServer(config *Config) (*Server, error) {
|
||||
key, err := wgtypes.GeneratePrivateKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
store, err := store.NewStore(dataDir)
|
||||
store, err := NewStore(config.Datadir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Server{
|
||||
Store: store,
|
||||
wgKey: key,
|
||||
// peerKey -> event channel
|
||||
peerChannels: make(map[string]chan *UpdateChannelMessage),
|
||||
channelsMux: &sync.Mutex{},
|
||||
peerChannels: make(map[string]chan *UpdateChannelMessage),
|
||||
channelsMux: &sync.Mutex{},
|
||||
accountManager: NewManager(store),
|
||||
config: config,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -73,8 +78,8 @@ func (s *Server) Sync(req *proto.EncryptedMessage, srv proto.ManagementService_S
|
||||
return status.Errorf(codes.InvalidArgument, "provided wgPubKey %s is invalid", peerKey.String())
|
||||
}
|
||||
|
||||
exists := s.Store.PeerExists(peerKey.String())
|
||||
if !exists {
|
||||
peer, err := s.accountManager.GetPeer(peerKey.String())
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Unauthenticated, "provided peer with the key wgPubKey %s is not registered", peerKey.String())
|
||||
}
|
||||
|
||||
@ -84,7 +89,7 @@ func (s *Server) Sync(req *proto.EncryptedMessage, srv proto.ManagementService_S
|
||||
return status.Errorf(codes.InvalidArgument, "invalid request message")
|
||||
}
|
||||
|
||||
err = s.sendInitialSync(peerKey, srv)
|
||||
err = s.sendInitialSync(peerKey, peer, srv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -132,28 +137,28 @@ func (s *Server) RegisterPeer(ctx context.Context, req *proto.RegisterPeerReques
|
||||
s.channelsMux.Lock()
|
||||
defer s.channelsMux.Unlock()
|
||||
|
||||
err := s.Store.AddPeer(req.SetupKey, req.Key)
|
||||
peer, err := s.accountManager.AddPeer(req.SetupKey, req.Key)
|
||||
if err != nil {
|
||||
return &proto.RegisterPeerResponse{}, status.Errorf(codes.NotFound, "provided setup key doesn't exists")
|
||||
}
|
||||
|
||||
peers, err := s.Store.GetPeersForAPeer(req.Key)
|
||||
peers, err := s.accountManager.GetPeersForAPeer(peer.Key)
|
||||
if err != nil {
|
||||
//todo return a proper error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// notify other peers of our registration
|
||||
for _, peer := range peers {
|
||||
if channel, ok := s.peerChannels[peer]; ok {
|
||||
for _, remotePeer := range peers {
|
||||
if channel, ok := s.peerChannels[remotePeer.Key]; ok {
|
||||
// exclude notified peer and add ourselves
|
||||
peersToSend := []string{req.Key}
|
||||
peersToSend := []*Peer{peer}
|
||||
for _, p := range peers {
|
||||
if peer != p {
|
||||
if remotePeer.Key != p.Key {
|
||||
peersToSend = append(peersToSend, p)
|
||||
}
|
||||
}
|
||||
update := &proto.SyncResponse{Peers: peersToSend}
|
||||
update := toSyncResponse(s.config, peer, peersToSend)
|
||||
channel <- &UpdateChannelMessage{Update: update}
|
||||
}
|
||||
}
|
||||
@ -161,6 +166,73 @@ func (s *Server) RegisterPeer(ctx context.Context, req *proto.RegisterPeerReques
|
||||
return &proto.RegisterPeerResponse{}, nil
|
||||
}
|
||||
|
||||
func toResponseProto(configProto Protocol) proto.HostConfig_Protocol {
|
||||
switch configProto {
|
||||
case UDP:
|
||||
return proto.HostConfig_UDP
|
||||
case DTLS:
|
||||
return proto.HostConfig_DTLS
|
||||
case HTTP:
|
||||
return proto.HostConfig_HTTP
|
||||
case HTTPS:
|
||||
return proto.HostConfig_HTTPS
|
||||
case TCP:
|
||||
return proto.HostConfig_TCP
|
||||
default:
|
||||
//mbragin: todo something better?
|
||||
panic(fmt.Errorf("unexpected config protocol type %v", configProto))
|
||||
}
|
||||
}
|
||||
|
||||
func toSyncResponse(config *Config, peer *Peer, peers []*Peer) *proto.SyncResponse {
|
||||
|
||||
var stuns []*proto.HostConfig
|
||||
for _, stun := range config.Stuns {
|
||||
stuns = append(stuns, &proto.HostConfig{
|
||||
Uri: stun.URI,
|
||||
Protocol: toResponseProto(stun.Proto),
|
||||
})
|
||||
}
|
||||
var turns []*proto.ProtectedHostConfig
|
||||
for _, turn := range config.Turns {
|
||||
turns = append(turns, &proto.ProtectedHostConfig{
|
||||
HostConfig: &proto.HostConfig{
|
||||
Uri: turn.URI,
|
||||
Protocol: toResponseProto(turn.Proto),
|
||||
},
|
||||
User: turn.Username,
|
||||
Password: string(turn.Password),
|
||||
})
|
||||
}
|
||||
|
||||
wtConfig := &proto.WiretrusteeConfig{
|
||||
Stuns: stuns,
|
||||
Turns: turns,
|
||||
Signal: &proto.HostConfig{
|
||||
Uri: config.Signal.URI,
|
||||
Protocol: toResponseProto(config.Signal.Proto),
|
||||
},
|
||||
}
|
||||
|
||||
pConfig := &proto.PeerConfig{
|
||||
Address: peer.IP.String(),
|
||||
}
|
||||
|
||||
remotePeers := make([]*proto.RemotePeerConfig, 0, len(peers))
|
||||
for _, rPeer := range peers {
|
||||
remotePeers = append(remotePeers, &proto.RemotePeerConfig{
|
||||
WgPubKey: rPeer.Key,
|
||||
AllowedIps: []string{fmt.Sprintf(AllowedIPsFormat, rPeer.IP)}, //todo /32
|
||||
})
|
||||
}
|
||||
|
||||
return &proto.SyncResponse{
|
||||
WiretrusteeConfig: wtConfig,
|
||||
PeerConfig: pConfig,
|
||||
RemotePeers: remotePeers,
|
||||
}
|
||||
}
|
||||
|
||||
// IsHealthy indicates whether the service is healthy
|
||||
func (s *Server) IsHealthy(ctx context.Context, req *proto.Empty) (*proto.Empty, error) {
|
||||
return &proto.Empty{}, nil
|
||||
@ -195,16 +267,14 @@ func (s *Server) closeUpdatesChannel(peerKey string) {
|
||||
}
|
||||
|
||||
// sendInitialSync sends initial proto.SyncResponse to the peer requesting synchronization
|
||||
func (s *Server) sendInitialSync(peerKey wgtypes.Key, srv proto.ManagementService_SyncServer) error {
|
||||
func (s *Server) sendInitialSync(peerKey wgtypes.Key, peer *Peer, srv proto.ManagementService_SyncServer) error {
|
||||
|
||||
peers, err := s.Store.GetPeersForAPeer(peerKey.String())
|
||||
peers, err := s.accountManager.GetPeersForAPeer(peer.Key)
|
||||
if err != nil {
|
||||
log.Warnf("error getting a list of peers for a peer %s", peerKey.String())
|
||||
log.Warnf("error getting a list of peers for a peer %s", peer.Key)
|
||||
return err
|
||||
}
|
||||
plainResp := &proto.SyncResponse{
|
||||
Peers: peers,
|
||||
}
|
||||
plainResp := toSyncResponse(s.config, peer, peers)
|
||||
|
||||
encryptedResp, err := encryption.EncryptMessage(peerKey, s.wgKey, plainResp)
|
||||
if err != nil {
|
||||
|
9
management/server/store.go
Normal file
9
management/server/store.go
Normal file
@ -0,0 +1,9 @@
|
||||
package server
|
||||
|
||||
type Store interface {
|
||||
GetPeer(peerId string) (*Peer, error)
|
||||
GetAccount(accountId string) (*Account, error)
|
||||
GetPeerAccount(peerId string) (*Account, error)
|
||||
GetAccountBySetupKey(setupKey string) (*Account, error)
|
||||
SaveAccount(account *Account) error
|
||||
}
|
25
management/server/testdata/management.json
vendored
Normal file
25
management/server/testdata/management.json
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"Stuns": [
|
||||
{
|
||||
"Proto": "udp",
|
||||
"URI": "stun:stun.wiretrustee.com:3468",
|
||||
"Username": "",
|
||||
"Password": null
|
||||
}
|
||||
],
|
||||
"Turns": [
|
||||
{
|
||||
"Proto": "udp",
|
||||
"URI": "turn:stun.wiretrustee.com:3468",
|
||||
"Username": "some_user",
|
||||
"Password": "c29tZV9wYXNzd29yZA=="
|
||||
}
|
||||
],
|
||||
"Signal": {
|
||||
"Proto": "http",
|
||||
"URI": "signal.wiretrustee.com:10000",
|
||||
"Username": "",
|
||||
"Password": null
|
||||
},
|
||||
"DataDir": ""
|
||||
}
|
9
management/server/testdata/store.json
vendored
9
management/server/testdata/store.json
vendored
@ -7,7 +7,14 @@
|
||||
"Key": "a2c8e62b-38f5-4553-b31e-dd66c696cebb"
|
||||
}
|
||||
},
|
||||
"Peers": {}
|
||||
"Network": {
|
||||
"Id": "af1c8024-ha40-4ce2-9418-34653101fc3c",
|
||||
"Net": {
|
||||
"IP": "100.64.0.0",
|
||||
"Mask": "/8AAAA=="
|
||||
},
|
||||
"Dns": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package store
|
||||
|
||||
// Account represents a unique account of the system
|
||||
type Account struct {
|
||||
Id string
|
||||
SetupKeys map[string]*SetupKey
|
||||
Peers map[string]*Peer
|
||||
}
|
||||
|
||||
// SetupKey represents a pre-authorized key used to register machines (peers)
|
||||
// One key might have multiple machines
|
||||
type SetupKey struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
// Peer represents a machine connected to the network.
|
||||
// The Peer is a Wireguard peer identified by a public key
|
||||
type Peer struct {
|
||||
// Wireguard public key
|
||||
Key string
|
||||
// A setup key this peer was registered with
|
||||
SetupKey *SetupKey
|
||||
}
|
||||
|
||||
type Store interface {
|
||||
PeerExists(peerKey string) bool
|
||||
AddPeer(setupKey string, peerKey string) error
|
||||
GetPeersForAPeer(peerKey string) ([]string, error)
|
||||
}
|
Loading…
Reference in New Issue
Block a user