fix(ipsec): показывать неопределённый статус при общих Remote ID
This commit is contained in:
1 parent
7815e00a1c
commit
cb6ec09312
20 files changed
+1077
-15
No files matched your search
@@ -286,6 +286,13 @@ export function mapClients(state: IpsecServerState): IpsecClientDto[] {
|
||||
}
|
||||
|
||||
const out: IpsecClientDto[] = []
|
||||
const sessionClaims = new Map<RosIpsecActivePeer, IpsecClientDto[]>()
|
||||
const claimSession = (active: RosIpsecActivePeer | undefined) => {
|
||||
if (!active) return
|
||||
const claims = sessionClaims.get(active) ?? []
|
||||
claims.push(out[out.length - 1]!)
|
||||
sessionClaims.set(active, claims)
|
||||
}
|
||||
|
||||
// 1. Клиентские сертификаты (роль client), подписанные нашим CA / выданные менеджером / referenced identity.
|
||||
for (const cert of state.certs) {
|
||||
@@ -332,6 +339,7 @@ export function mapClients(state: IpsecServerState): IpsecClientDto[] {
|
||||
comment: comment || undefined,
|
||||
managed: isUser || isIpsecManagedComment(comment),
|
||||
})
|
||||
claimSession(active)
|
||||
}
|
||||
|
||||
// 2. PSK-identity (managed или IKEv2 remote-access).
|
||||
@@ -363,8 +371,20 @@ export function mapClients(state: IpsecServerState): IpsecClientDto[] {
|
||||
comment: i.comment || undefined,
|
||||
managed,
|
||||
})
|
||||
claimSession(active)
|
||||
}
|
||||
|
||||
// The native snapshot does not identify the configured identity/auth type.
|
||||
// Never assign one observed session/address to multiple catalog clients.
|
||||
for (const claims of sessionClaims.values()) {
|
||||
if (claims.length < 2) continue
|
||||
for (const client of claims) {
|
||||
client.online = false
|
||||
client.sessionAmbiguous = true
|
||||
client.activeAddress = undefined
|
||||
client.activeSince = undefined
|
||||
}
|
||||
}
|
||||
return out.sort((a, b) => a.name.localeCompare(b.name))
|
||||
}
|
||||
|
||||
@@ -443,6 +463,7 @@ export function mapServerSummary(state: IpsecServerState, clients: IpsecClientDt
|
||||
natRuleManaged,
|
||||
clientsTotal: clients.length,
|
||||
clientsOnline: clients.filter((c) => c.online).length,
|
||||
...(clients.some(c => c.sessionAmbiguous) ? { clientsSessionAmbiguous: clients.filter(c => c.sessionAmbiguous).length } : {}),
|
||||
certs: relevantCerts.map((c) => mapCertificate(c, roleCtx)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,4 +152,21 @@ namespaceState.active[0]!.id = "explicit.example"
|
||||
assert.equal(mapClients(namespaceState).find(c => c.certName === "ipsec-user-plain")?.online, true); checks++
|
||||
namespaceState.identities[0]!["remote-id"] = "unknown:explicit.example"
|
||||
assert.equal(mapClients(namespaceState).find(c => c.certName === "ipsec-user-plain")?.online, false); checks++
|
||||
const aliasesState = { ...sessionState, active: [{ ".id": "*ALIASED", id: "shared.example", state: "established", "dynamic-address": "198.18.112.250", uptime: "1m" }] } as typeof state
|
||||
for (const secondId of ["fqdn:shared.example", "key-id:shared.example"]) {
|
||||
aliasesState.identities = ["fqdn:shared.example", secondId].map((remoteId, n) => ({ ".id": "*PSK" + n, peer: "ike", "auth-method": "pre-shared-key", "remote-id": remoteId, comment: ipsecManagedComment("user=PSK" + n) }))
|
||||
const clients = mapClients(aliasesState)
|
||||
assert.equal(clients.length, 2)
|
||||
assert(clients.every(c => c.sessionAmbiguous && !c.online && !c.activeAddress && !c.activeSince)); checks++
|
||||
const summary = mapServerSummary(aliasesState, clients)
|
||||
assert.equal(summary.clientsOnline, 0); assert.equal(summary.clientsSessionAmbiguous, 2); checks++
|
||||
}
|
||||
aliasesState.certs = [{ ".id": "*CERTALIAS", name: "ipsec-user-aliased", "common-name": "certificate", ca: "ca", "key-usage": "tls-client" }]
|
||||
aliasesState.identities[0] = { ".id": "*CERTIDENTITY", peer: "ike", "auth-method": "digital-signature", "remote-certificate": "ipsec-user-aliased", "remote-id": "fqdn:shared.example" }
|
||||
assert(mapClients(aliasesState).every(c => c.sessionAmbiguous && !c.online && !c.activeAddress)); checks++
|
||||
aliasesState.identities[1]!["remote-id"] = "key-id:unrelated"
|
||||
const uniqueClients = mapClients(aliasesState)
|
||||
assert.equal(uniqueClients.find(c => c.kind === "cert")?.online, true)
|
||||
assert.equal(uniqueClients.find(c => c.kind === "psk")?.online, false)
|
||||
assert(uniqueClients.every(c => !c.sessionAmbiguous)); checks++
|
||||
console.log(`ipsec-state: ${checks} checks passed`)
|
||||
Reference in new issue
Block a user