mirror of
https://github.com/netbirdio/netbird.git
synced 2025-08-14 09:18:51 +02:00
Report offline peers to agents (#728)
The peer login expiration ACL check introduced in #714 filters out peers that are expired and agents receive a network map without that expired peers. However, the agents should see those peers in status "Disconnected". This PR extends the Agent <-> Management protocol by introducing a new field OfflinePeers that contain expired peers. Agents keep track of those and display then just in the Status response.
This commit is contained in:
@ -311,9 +311,11 @@ func (a *Account) GetPeerNetworkMap(peerID, dnsDomain string) *NetworkMap {
|
||||
aclPeers := a.getPeersByACL(peerID)
|
||||
// exclude expired peers
|
||||
var peersToConnect []*Peer
|
||||
var expiredPeers []*Peer
|
||||
for _, p := range aclPeers {
|
||||
expired, _ := p.LoginExpired(a.Settings.PeerLoginExpiration)
|
||||
if expired {
|
||||
expiredPeers = append(expiredPeers, p)
|
||||
continue
|
||||
}
|
||||
peersToConnect = append(peersToConnect, p)
|
||||
@ -337,10 +339,11 @@ func (a *Account) GetPeerNetworkMap(peerID, dnsDomain string) *NetworkMap {
|
||||
}
|
||||
|
||||
return &NetworkMap{
|
||||
Peers: peersToConnect,
|
||||
Network: a.Network.Copy(),
|
||||
Routes: routesUpdate,
|
||||
DNSConfig: dnsUpdate,
|
||||
Peers: peersToConnect,
|
||||
Network: a.Network.Copy(),
|
||||
Routes: routesUpdate,
|
||||
DNSConfig: dnsUpdate,
|
||||
OfflinePeers: expiredPeers,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,6 +418,8 @@ func toSyncResponse(config *Config, peer *Peer, turnCredentials *TURNCredentials
|
||||
|
||||
dnsUpdate := toProtocolDNSConfig(networkMap.DNSConfig)
|
||||
|
||||
offlinePeers := toRemotePeerConfig(networkMap.OfflinePeers, dnsName)
|
||||
|
||||
return &proto.SyncResponse{
|
||||
WiretrusteeConfig: wtConfig,
|
||||
PeerConfig: pConfig,
|
||||
@ -427,6 +429,7 @@ func toSyncResponse(config *Config, peer *Peer, turnCredentials *TURNCredentials
|
||||
Serial: networkMap.Network.CurrentSerial(),
|
||||
PeerConfig: pConfig,
|
||||
RemotePeers: remotePeers,
|
||||
OfflinePeers: offlinePeers,
|
||||
RemotePeersIsEmpty: len(remotePeers) == 0,
|
||||
Routes: routesUpdate,
|
||||
DNSConfig: dnsUpdate,
|
||||
|
@ -75,7 +75,7 @@ func getServerKey(client mgmtProto.ManagementServiceClient) (*wgtypes.Key, error
|
||||
|
||||
func Test_SyncProtocol(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
err := util.CopyFileContents("testdata/store.json", filepath.Join(dir, "store.json"))
|
||||
err := util.CopyFileContents("testdata/store_with_expired_peers.json", filepath.Join(dir, "store.json"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -117,6 +117,7 @@ func Test_SyncProtocol(t *testing.T) {
|
||||
|
||||
defer clientConn.Close()
|
||||
|
||||
// there are two peers already in the store, add two more
|
||||
peers, err := registerPeers(2, client)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -129,7 +130,7 @@ func Test_SyncProtocol(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
// take the first registered peer as a base for the test
|
||||
// take the first registered peer as a base for the test. Total four.
|
||||
key := *peers[0]
|
||||
|
||||
message, err := encryption.EncryptMessage(*serverKey, key, &mgmtProto.SyncRequest{})
|
||||
@ -242,8 +243,18 @@ func Test_SyncProtocol(t *testing.T) {
|
||||
t.Fatal("expecting SyncResponse to have non-nil NetworkMap")
|
||||
}
|
||||
|
||||
if len(networkMap.GetRemotePeers()) != 1 {
|
||||
t.Fatal("expecting SyncResponse to have NetworkMap with 1 remote peer")
|
||||
if len(networkMap.GetRemotePeers()) != 3 {
|
||||
t.Fatal("expecting SyncResponse to have NetworkMap with 3 remote peers")
|
||||
}
|
||||
|
||||
// expired peers come separately.
|
||||
if len(networkMap.GetOfflinePeers()) != 1 {
|
||||
t.Fatal("expecting SyncResponse to have NetworkMap with 1 offline peer")
|
||||
}
|
||||
|
||||
expiredPeerPubKey := "RlSy2vzoG2HyMBTUImXOiVhCBiiBa5qD5xzMxkiFDW4="
|
||||
if networkMap.GetOfflinePeers()[0].WgPubKey != expiredPeerPubKey {
|
||||
t.Fatalf("expecting SyncResponse to have NetworkMap with 1 offline peer with a key %s", expiredPeerPubKey)
|
||||
}
|
||||
|
||||
if networkMap.GetPeerConfig() == nil {
|
||||
|
@ -127,6 +127,7 @@ var _ = Describe("Management service", func() {
|
||||
actualTURN := resp.WiretrusteeConfig.Turns[0]
|
||||
Expect(len(actualTURN.User) > 0).To(BeTrue())
|
||||
Expect(actualTURN.HostConfig).To(BeEquivalentTo(expectedTRUNHost))
|
||||
Expect(len(resp.NetworkMap.OfflinePeers) == 0).To(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -23,10 +23,11 @@ const (
|
||||
)
|
||||
|
||||
type NetworkMap struct {
|
||||
Peers []*Peer
|
||||
Network *Network
|
||||
Routes []*route.Route
|
||||
DNSConfig nbdns.Config
|
||||
Peers []*Peer
|
||||
Network *Network
|
||||
Routes []*route.Route
|
||||
DNSConfig nbdns.Config
|
||||
OfflinePeers []*Peer
|
||||
}
|
||||
|
||||
type Network struct {
|
||||
|
126
management/server/testdata/store_with_expired_peers.json
vendored
Normal file
126
management/server/testdata/store_with_expired_peers.json
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
{
|
||||
"Accounts": {
|
||||
"bf1c8084-ba50-4ce7-9439-34653001fc3b": {
|
||||
"Id": "bf1c8084-ba50-4ce7-9439-34653001fc3b",
|
||||
"Domain": "test.com",
|
||||
"DomainCategory": "private",
|
||||
"IsDomainPrimaryAccount": true,
|
||||
"SetupKeys": {
|
||||
"A2C8E62B-38F5-4553-B31E-DD66C696CEBB": {
|
||||
"Key": "A2C8E62B-38F5-4553-B31E-DD66C696CEBB",
|
||||
"Name": "Default key",
|
||||
"Type": "reusable",
|
||||
"CreatedAt": "2021-08-19T20:46:20.005936822+02:00",
|
||||
"ExpiresAt": "2321-09-18T20:46:20.005936822+02:00",
|
||||
"Revoked": false,
|
||||
"UsedTimes": 0
|
||||
|
||||
}
|
||||
},
|
||||
"Network": {
|
||||
"Id": "af1c8024-ha40-4ce2-9418-34653101fc3c",
|
||||
"Net": {
|
||||
"IP": "100.64.0.0",
|
||||
"Mask": "//8AAA=="
|
||||
},
|
||||
"Dns": null
|
||||
},
|
||||
"Peers": {
|
||||
"cfvprsrlo1hqoo49ohog": {
|
||||
"ID": "cfvprsrlo1hqoo49ohog",
|
||||
"Key": "5rvhvriKJZ3S9oxYToVj5TzDM9u9y8cxg7htIMWlYAg=",
|
||||
"SetupKey": "72546A29-6BC8-4311-BCFC-9CDBF33F1A48",
|
||||
"IP": "100.64.114.31",
|
||||
"Meta": {
|
||||
"Hostname": "f2a34f6a4731",
|
||||
"GoOS": "linux",
|
||||
"Kernel": "Linux",
|
||||
"Core": "11",
|
||||
"Platform": "unknown",
|
||||
"OS": "Debian GNU/Linux",
|
||||
"WtVersion": "0.12.0",
|
||||
"UIVersion": ""
|
||||
},
|
||||
"Name": "f2a34f6a4731",
|
||||
"DNSLabel": "f2a34f6a4731",
|
||||
"Status": {
|
||||
"LastSeen": "2023-03-02T09:21:02.189035775+01:00",
|
||||
"Connected": false,
|
||||
"LoginExpired": false
|
||||
},
|
||||
"UserID": "",
|
||||
"SSHKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILzUUSYG/LGnV8zarb2SGN+tib/PZ+M7cL4WtTzUrTpk",
|
||||
"SSHEnabled": false,
|
||||
"LoginExpirationEnabled": true,
|
||||
"LastLogin": "2023-03-01T19:48:19.817799698+01:00"
|
||||
},
|
||||
"cg05lnblo1hkg2j514p0": {
|
||||
"ID": "cg05lnblo1hkg2j514p0",
|
||||
"Key": "RlSy2vzoG2HyMBTUImXOiVhCBiiBa5qD5xzMxkiFDW4=",
|
||||
"SetupKey": "",
|
||||
"IP": "100.64.39.54",
|
||||
"Meta": {
|
||||
"Hostname": "expiredhost",
|
||||
"GoOS": "linux",
|
||||
"Kernel": "Linux",
|
||||
"Core": "22.04",
|
||||
"Platform": "x86_64",
|
||||
"OS": "Ubuntu",
|
||||
"WtVersion": "development",
|
||||
"UIVersion": ""
|
||||
},
|
||||
"Name": "expiredhost",
|
||||
"DNSLabel": "expiredhost",
|
||||
"Status": {
|
||||
"LastSeen": "2023-03-02T09:19:57.276717255+01:00",
|
||||
"Connected": false,
|
||||
"LoginExpired": true
|
||||
},
|
||||
"UserID": "edafee4e-63fb-11ec-90d6-0242ac120003",
|
||||
"SSHKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMbK5ZXJsGOOWoBT4OmkPtgdPZe2Q7bDuS/zjn2CZxhK",
|
||||
"SSHEnabled": false,
|
||||
"LoginExpirationEnabled": true,
|
||||
"LastLogin": "2023-03-02T09:14:21.791679181+01:00"
|
||||
},
|
||||
"cg3161rlo1hs9cq94gdg": {
|
||||
"ID": "cg3161rlo1hs9cq94gdg",
|
||||
"Key": "mVABSKj28gv+JRsf7e0NEGKgSOGTfU/nPB2cpuG56HU=",
|
||||
"SetupKey": "",
|
||||
"IP": "100.64.117.96",
|
||||
"Meta": {
|
||||
"Hostname": "testhost",
|
||||
"GoOS": "linux",
|
||||
"Kernel": "Linux",
|
||||
"Core": "22.04",
|
||||
"Platform": "x86_64",
|
||||
"OS": "Ubuntu",
|
||||
"WtVersion": "development",
|
||||
"UIVersion": ""
|
||||
},
|
||||
"Name": "testhost",
|
||||
"DNSLabel": "testhost",
|
||||
"Status": {
|
||||
"LastSeen": "2023-03-06T18:21:27.252010027+01:00",
|
||||
"Connected": false,
|
||||
"LoginExpired": false
|
||||
},
|
||||
"UserID": "edafee4e-63fb-11ec-90d6-0242ac120003",
|
||||
"SSHKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINWvvUkFFcrj48CWTkNUb/do/n52i1L5dH4DhGu+4ZuM",
|
||||
"SSHEnabled": false,
|
||||
"LoginExpirationEnabled": false,
|
||||
"LastLogin": "2023-03-07T09:02:47.442857106+01:00"
|
||||
}
|
||||
},
|
||||
"Users": {
|
||||
"edafee4e-63fb-11ec-90d6-0242ac120003": {
|
||||
"Id": "edafee4e-63fb-11ec-90d6-0242ac120003",
|
||||
"Role": "admin"
|
||||
},
|
||||
"f4f6d672-63fb-11ec-90d6-0242ac120003": {
|
||||
"Id": "f4f6d672-63fb-11ec-90d6-0242ac120003",
|
||||
"Role": "user"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user