fix(ipsec): исправить статус клиента с полным DN сертификата

This commit is contained in:
Denozordec committed 2026-10-10 09:42:57 +07:00
1 parent 1d61b50591
commit 2aa93ad365
16 files changed
+1517 -17

No files matched your search

+20 -5
View File
@@ -28,6 +28,7 @@ import {
selectSharedIke2Identity,
} from "./ipsec-config.js"
import { certificateRole, type CertificateRoleContext } from "./certificate-parse.js"
import { routerOsCertificateDn } from "./ipsec-certificate-dn.js"
import {
canonicalIpsecSnapshot,
type IpsecLiveIdentity,
@@ -248,10 +249,24 @@ export function mapClients(state: IpsecServerState): IpsecClientDto[] {
const sharedRosId = shared?.[".id"] ? String(shared[".id"]) : undefined
const activeByRemote = new Map<string, RosIpsecActivePeer>()
const ambiguousRemoteIds = new Set<string>()
for (const a of state.active) {
if (a.state !== "established") continue
const rid = String(a.id ?? a["remote-id"] ?? "").trim()
if (rid) activeByRemote.set(rid, a)
if (rid) {
if (activeByRemote.has(rid)) ambiguousRemoteIds.add(rid)
else activeByRemote.set(rid, a)
}
}
for (const rid of ambiguousRemoteIds) activeByRemote.delete(rid)
const subjectCounts = new Map<string, number>()
const cnCounts = new Map<string, number>()
for (const cert of state.certs) {
const subject = routerOsCertificateDn(cert)
if (subject) subjectCounts.set(subject, (subjectCounts.get(subject) ?? 0) + 1)
const cn = cert["common-name"]
if (cn) cnCounts.set(cn, (cnCounts.get(cn) ?? 0) + 1)
}
// RouterOS 7 active-peers.id contains the received value without its configured type prefix.
@@ -286,10 +301,10 @@ export function mapClients(state: IpsecServerState): IpsecClientDto[] {
const comment = identity?.comment ?? ""
const mcName = (identity?.["mode-config"] ?? "").trim()
const cn = String(cert["common-name"] ?? "").trim()
// Our issued certificates have a single CN subject; match the whole DN, never a CN substring.
const singleCn = cn && !/[,+=<>;\\"\u0000]/.test(cn) && state.certs.filter(c => c["common-name"] === cn).length === 1
? activeByRemote.get(`CN=${cn}`) : undefined
const active = (cn ? findActive(cn) : undefined) ?? singleCn
const subject = routerOsCertificateDn(cert)
const bySubject = subject && subjectCounts.get(subject) === 1 ? activeByRemote.get(subject) : undefined
const uniqueCn = cn && cnCounts.get(cn) === 1
const active = (uniqueCn ? findActive(cn) : undefined) ?? bySubject
?? (identity?.["remote-id"] ? findActive(String(identity["remote-id"]).trim()) : undefined)
out.push({
id: `${server.id}:${identity ? "identity" : "cert"}:${String(identity?.[".id"] ?? cert[".id"] ?? certName)}`,