fix(ipsec): показывать подключённых клиентов и адрес mode-config

This commit is contained in:
Denozordec committed 2026-10-09 15:14:41 +07:00
1 parent f80d9b7637
commit b9a8615b8b
8 files changed
+204 -14

No files matched your search

+18 -8
View File
@@ -108,6 +108,11 @@ export interface RosIpsecActivePeer {
"remote-id"?: string
identity?: string
established?: string
id?: string
state?: string
"remote-address"?: string
"dynamic-address"?: string
uptime?: string
}
type RosCertRow = Record<string, string | undefined>
@@ -238,10 +243,15 @@ export function mapClients(state: IpsecServerState): IpsecClientDto[] {
const activeByRemote = new Map<string, RosIpsecActivePeer>()
for (const a of state.active) {
const rid = String(a["remote-id"] ?? "").trim()
if (a.state !== "established") continue
const rid = String(a.id ?? a["remote-id"] ?? "").trim()
if (rid) activeByRemote.set(rid, a)
}
// RouterOS 7 active-peers.id contains the received value without its configured type prefix.
const findActive = (remoteId: string) => activeByRemote.get(remoteId)
?? activeByRemote.get(remoteId.replace(/^(key-id|fqdn|user-fqdn|address):/, ""))
const identityByRemoteCert = new Map<string, RosIpsecIdentity>()
for (const i of state.identities) {
const rc = (i["remote-certificate"] ?? "").trim()
@@ -270,8 +280,8 @@ export function mapClients(state: IpsecServerState): IpsecClientDto[] {
const comment = identity?.comment ?? ""
const mcName = (identity?.["mode-config"] ?? "").trim()
const cn = String(cert["common-name"] ?? "").trim()
const active = (cn ? activeByRemote.get(cn) : undefined)
?? (identity?.["remote-id"] ? activeByRemote.get(String(identity["remote-id"]).trim()) : undefined)
const active = (cn ? findActive(cn) : undefined)
?? (identity?.["remote-id"] ? findActive(String(identity["remote-id"]).trim()) : undefined)
out.push({
id: `${server.id}:${identity ? "identity" : "cert"}:${String(identity?.[".id"] ?? cert[".id"] ?? certName)}`,
rosId: `${identity ? "identity" : "cert"}:${String(identity?.[".id"] ?? cert[".id"] ?? certName)}`,
@@ -289,8 +299,8 @@ export function mapClients(state: IpsecServerState): IpsecClientDto[] {
modeConfigName: mcName || undefined,
peerName: (identity?.peer ?? "").trim() || undefined,
online: Boolean(active),
activeAddress: active?.address || undefined,
activeSince: active?.established || undefined,
activeAddress: active?.["dynamic-address"] || active?.["remote-address"] || active?.address || undefined,
activeSince: active?.uptime || active?.established || undefined,
disabled: asBool(identity?.disabled),
comment: comment || undefined,
managed: isUser || isIpsecManagedComment(comment),
@@ -306,7 +316,7 @@ export function mapClients(state: IpsecServerState): IpsecClientDto[] {
if (!managed && !isIke2RemoteAccessIdentity(i, ike2PeerNames)) continue
const mcName = (i["mode-config"] ?? "").trim()
const remoteId = (i["remote-id"] ?? "").trim()
const active = remoteId ? activeByRemote.get(remoteId) : undefined
const active = remoteId ? findActive(remoteId) : undefined
out.push({
id: `${server.id}:identity:${rosId}`,
rosId: `identity:${rosId}`,
@@ -320,8 +330,8 @@ export function mapClients(state: IpsecServerState): IpsecClientDto[] {
modeConfigName: mcName || undefined,
peerName: (i.peer ?? "").trim() || undefined,
online: Boolean(active),
activeAddress: active?.address || undefined,
activeSince: active?.established || undefined,
activeAddress: active?.["dynamic-address"] || active?.["remote-address"] || active?.address || undefined,
activeSince: active?.uptime || active?.established || undefined,
disabled: asBool(i.disabled),
comment: i.comment || undefined,
managed,
+17
View File
@@ -75,4 +75,21 @@ assert.equal(mapClients(state).find(c => c.certName === "client")?.name, "Existi
let foreignCertificateWrites = 0
await assert.rejects(removeManagedIpsecServer({ get: async (path: string) => path === "/certificate" ? [{ ".id": "*CA", name: "ipsec-ca" }, { ".id": "*FOREIGN", name: "external-client", ca: "ipsec-ca" }] : [], delete: async () => { foreignCertificateWrites++ } } as unknown as MikrotikClient, true), /чужой сертификат/)
assert.equal(foreignCertificateWrites, 0); checks++
const sessionState = { ...state, certs: [], identities: [{ ".id": "*SESSION", peer: "ike", "auth-method": "pre-shared-key", "remote-id": "key-id:alice", comment: ipsecManagedComment("user=Alice") }], active: [] } as typeof state
for (const phase of ["starting", "established", "dying", undefined]) {
sessionState.active = [{ ".id": "*ACTIVE", id: "alice", state: phase, "remote-address": "192.0.2.2", "dynamic-address": "198.18.78.10", uptime: "1m" }]
const client = mapClients(sessionState)[0]!
assert.equal(client.online, phase === "established")
assert.equal(client.activeAddress, phase === "established" ? "198.18.78.10" : undefined)
assert.equal(client.activeSince, phase === "established" ? "1m" : undefined); checks++
}
sessionState.active = [{ ".id": "*ACTIVE", id: "key-id:other", state: "established", "remote-address": "192.0.2.2" }]
assert.equal(mapClients(sessionState)[0]?.online, false); checks++
sessionState.active = [{ ".id": "*ACTIVE", "remote-id": "key-id:alice", state: "established", "remote-address": "192.0.2.2", uptime: "2m" }]
assert.equal(mapClients(sessionState)[0]?.activeAddress, "192.0.2.2"); checks++
for (const prefix of ["fqdn", "user-fqdn", "address", "unknown"]) {
sessionState.identities[0]!["remote-id"] = prefix + ":alice"
sessionState.active = [{ ".id": "*ACTIVE", id: "alice", state: "established" }]
assert.equal(mapClients(sessionState)[0]?.online, prefix !== "unknown"); checks++
}
console.log(`ipsec-state: ${checks} checks passed`)
+3 -1
View File
@@ -1,6 +1,8 @@
# UX/UI: протокол внешней приёмки 12.5
Статус на2026-10-09: backend/frontend ux-ipsec77, backend healthy; основной блок IPsec77 и VXLAN76 приняты в описанных границах. В12.5.67 исправленный Peer .conf принят как клиентский шаблон: API6/6, browser4/4, server endpoint и placeholders; настоящий RSC roundtrip через UI/native/handshake/Ping принят в12.5.68, .conf с явнымName/отказы400/409/сохранение формы приняты в70; поздний native rejection/подтверждённая компенсация/retry приняты в72; изолированный audit INSERT permission denial принят в74; остальные неизвестные исходы/DB faults открыты. Мобильная ширина WireGuard Sheets принята в12.5.64. Мобильная GRE форма и native сохранение на обоих CHR приняты в12.5.57. WireGuard handshake/короткий Ping/native API/read-only UI приняты в границах12.5.58; 12.5.59 воспроизвёл оставшиеся peers/IP; 12.5.60 развернул исправление и принял обычное удаление own WG интерфейса с peer/IPv4 адресом на обоих CHR. 12.5.62 принял полный WireGuard UI create/peer/disable/enable/Ping/delete на обоих CHR; устойчивое меню развёрнуто. Устойчивость меню GRE при live refresh на обоих CHR принята в12.5.55. GRE peer metadata и реальный lifecycle/API/UI/двусторонний Ping подтверждены в12.5.53. Browser retry/checkpoint на реальном HTTP/PG принят в границах12.5.43–45; Telegram sender responses подменены, реальная доставка не проверена. PG-1/2/3/4/5 приняты в описанных границах, PG-6 integrated для одного isolated instance, PG-7 real JWT/processcounts и browser restore passed. PG-8 real PG/native и browser unknown→history done приняты с fault injection после настоящего COMMIT. ROS-8/9 real API/SQL/native приняты в границах12.5.23; browser pair/duration change и delete приняты в12.5.24. ROS-2 authentication failure принят в12.5.25. PortalSSO, физический TCP disconnect, мультиэкземпляры и остальные ROS/Q/интеграции остаются открытыми. [Паспорт](ux-ui-test-server.md), [журнал](ux-ui-progress.md). VXLAN75: собственная native пара/Ping/catalog/URL/export приняты, create/delete API отсутствует; selected baseline восстановлен.
Статус на2026-10-09: backend ux-ipsec78/frontend ux-ipsec77, backend healthy; основной блок IPsec77 и VXLAN76 приняты в описанных границах. В12.5.67 исправленный Peer .conf принят как клиентский шаблон: API6/6, browser4/4, server endpoint и placeholders; настоящий RSC roundtrip через UI/native/handshake/Ping принят в12.5.68, .conf с явнымName/отказы400/409/сохранение формы приняты в70; поздний native rejection/подтверждённая компенсация/retry приняты в72; изолированный audit INSERT permission denial принят в74; остальные неизвестные исходы/DB faults открыты. Мобильная ширина WireGuard Sheets принята в12.5.64. Мобильная GRE форма и native сохранение на обоих CHR приняты в12.5.57. WireGuard handshake/короткий Ping/native API/read-only UI приняты в границах12.5.58; 12.5.59 воспроизвёл оставшиеся peers/IP; 12.5.60 развернул исправление и принял обычное удаление own WG интерфейса с peer/IPv4 адресом на обоих CHR. 12.5.62 принял полный WireGuard UI create/peer/disable/enable/Ping/delete на обоих CHR; устойчивое меню развёрнуто. Устойчивость меню GRE при live refresh на обоих CHR принята в12.5.55. GRE peer metadata и реальный lifecycle/API/UI/двусторонний Ping подтверждены в12.5.53. Browser retry/checkpoint на реальном HTTP/PG принят в границах12.5.43–45; Telegram sender responses подменены, реальная доставка не проверена. PG-1/2/3/4/5 приняты в описанных границах, PG-6 integrated для одного isolated instance, PG-7 real JWT/processcounts и browser restore passed. PG-8 real PG/native и browser unknown→history done приняты с fault injection после настоящего COMMIT. ROS-8/9 real API/SQL/native приняты в границах12.5.23; browser pair/duration change и delete приняты в12.5.24. ROS-2 authentication failure принят в12.5.25. PortalSSO, физический TCP disconnect, мультиэкземпляры и остальные ROS/Q/интеграции остаются открытыми. [Паспорт](ux-ui-test-server.md), [журнал](ux-ui-progress.md). VXLAN75: собственная native пара/Ping/catalog/URL/export приняты, create/delete API отсутствует; selected baseline восстановлен.
IPsec78: реальный PSK responder established, mode-config198.18.78.10 и online=true подтверждены API; точные собственные объекты удалены. Сертификатный/DN online, late failure и history restore остаются открытыми. [Отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json), [журнал](ux-ui-progress.md).
## Паспорт стенда
+1 -1
View File
@@ -1,6 +1,6 @@
# План реализации UX/UI по пятичасовым окнам
Актуальное продолжение 2026-10-09: 12.5.77 завершил укрупнённый основной блок IPsec: достоверное чтение, запрет опроса выключенных устройств, совместимый RouterOS7 мастер, раздельные ID клиентов, безопаснее удаление, URL устройства/вкладки, Docker обеих частей и реальная приёмка. Local30/30 + context6/6 + backend67, live browser4/4, PSK и сертификатный защищённый GRE/Ping3/3 на двух CHR; cleanup/DB controls passed. Runtime backend/frontend ux-ipsec77, version1.0.0-test.ipsec77. Следующий12.5.78 — остаточная профильная приёмка IPsec: сопоставление active-peer/online, выдача mode-config, поздние ошибки операций и история восстановления; затем маршрутизация. Этап12.5 открыт.
Актуальное продолжение 2026-10-09: 12.5.78 подтвердил реальное PSK IKEv2 подключение с выдачей mode-config и исправил ложный offline в каталоге клиентов. Backend ux-ipsec78, frontend ux-ipsec77; 77 backend-проверок, TypeScript/ESLint, одна backend Docker сборка и native/API приёмка; собственные объекты удалены. Следующий12.5.79 — сертификатный клиент/выдача mode-config, затем поздние ошибки операций и история восстановления. Этап12.5 открыт.
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-09. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
+16 -2
View File
@@ -1,6 +1,6 @@
# UX/UI: журнал реализации
Актуальное продолжение 2026-10-09: 12.5.77 завершил укрупнённый основной блок IPsec: достоверное чтение, запрет опроса выключенных устройств, совместимый RouterOS7 мастер, раздельные ID клиентов, безопаснее удаление, URL устройства/вкладки, Docker обеих частей и реальная приёмка. Local30/30 + context6/6 + backend67, live browser4/4, PSK и сертификатный защищённый GRE/Ping3/3 на двух CHR; cleanup/DB controls passed. Runtime backend/frontend ux-ipsec77, version1.0.0-test.ipsec77. Следующий12.5.78 — остаточная профильная приёмка IPsec: сопоставление active-peer/online, выдача mode-config, поздние ошибки операций и история восстановления; затем маршрутизация. Этап12.5 открыт.
Актуальное продолжение 2026-10-09: 12.5.78 подтвердил реальное PSK IKEv2 подключение с выдачей mode-config и исправил ложный offline в каталоге клиентов. Backend ux-ipsec78, frontend ux-ipsec77; 77 backend-проверок, TypeScript/ESLint, одна backend Docker сборка и native/API приёмка; собственные объекты удалены. Следующий12.5.79 — сертификатный клиент/выдача mode-config, затем поздние ошибки операций и история восстановления. Этап12.5 открыт.
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
@@ -36,7 +36,21 @@
| 10 | Маршрутизация, диагностика, карта и терминал | Завершён в границах локальной приёмки 2026-10-01; блоки 10.1–10.71, внешние ограничения в 10.71 |
| 11А | Пользователи, контейнеры, сертификаты и резервные копии | Завершён в границах локальной приёмки 2026-10-01; 11А.1–11А.33, внешние ограничения в 11А.33 |
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–77 и ограничения ниже. Runtime backend/frontend ux-ipsec77. |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–78 и ограничения ниже. Runtime backend ux-ipsec78/frontend ux-ipsec77. |
## 12.5.78 — IPsec: реальный online и адрес mode-config (2026-10-09)
**Результат.** Установленный PSK IKEv2 клиент отображался offline: RouterOS7 возвращает active-peers.id без префикса key-id:, а старый mapper ожидал remote-id; address/established также не соответствовали реальному ответу. Теперь используются id, state=established, dynamic-address (при наличии), remote-address и uptime. Для настроенного remote-id распознаются только известные префиксы key-id/fqdn/user-fqdn/address; starting/dying/отсутствующее состояние не подтверждают online. Изменены только ipsec-live.ts и профильный тест; UI-компоненты сохранены.
**Реальное подтверждение.** Собственный responder на194.226.121.150 и initiator на104.165.244.7: PSK, IKEv2, SHA256/AES256/modp2048, отдельные profile/proposal/group/template/mode-config/pool/peer/identity. На responder RouterOS и развёрнутый GET /api/ipsec?serverId=1 подтвердили established, online=true, activeAddress=198.18.78.10, activeSince=0s. Это проверка выдачи адреса и корреляции PSK, не NAT/интернет/throughput. На initiator remote-id=auto не связывается с персональным клиентом, его online=false не считается принятой корреляцией. Сертификатный/DN вариант остаётся открытым. [Очищенный отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json).
**Проверки и очистка.** npm --prefix backend run test:ipsec: config passed +77 state checks; backend TypeScript, scoped ESLint, diff check passed. Native/API сценарий прошёл на новом backend. До удаления проверены точные ID и атрибуты всех собственных объектов; после — исходные ID восьми коллекций совпали на обоих CHR. Пароли не менялись; flash не затрагивался. Первые три попытки настройки fixture завершились authentication failure; чтение IPsec logs показало identity not found. Удаление избыточных явных responder my-id / initiator remote-id восстановило переговоры; это настройка тестовой пары, приложение не меняет my-id этим блоком.
**Runtime и происхождение.** Единственная backend production сборка/deploy: mmapp-test/backend:ux-ipsec78, version1.0.0-test.ipsec78, image sha256:d25bb95996e7b917c8829a40e5d90cdcd75a4909e4a4654fcfc818f617262d81, healthy. Frontend остаётся ux-ipsec77; его сборка и общая UI-регрессия не повторялись, поскольку frontend не изменён. Backend context основан на предыдущем проверенном ipsec77 (production соответствует f80d9b7), с заменой ipsec-live.ts; SHA256 runtime исходника29b6843f9b6c80cc83af61ec44f3fdc99759ea656ba126722be3eb5f03501b0b совпал локально/удалённо. Архив двух backend-файлов3bf89cbefc57c3d0002da7285abaa300544700eb3ebeb9e5a83ad4622396ac3a; в нём тест на73 checks, ещё4 проверки префиксов добавлены локально после старта сборки и прошли — это не изменение production кода. Образ не заявляется сборкой из итогового Git SHA; label revision=ipsec78. Backup .env сохранён приватно на сервере; миграций БД нет.
**Организация.** По замечанию пользователя о длительности предыдущего блока: одна подтверждённая проблема, профильные проверки, одна backend сборка, без повторной frontend сборки и полного набора E2E. Расход пятичасового окна на контрольной точке8%; это квота, не длительность работы. Один локальный коммит без push. Следующий шаг12.5.79: проверить сертификатный active-peer/DN и mode-config, затем late failure receipts/DB/transport и history restore. Остальные ограничения12.5.77 сохраняются.
Референс: [RouterOS IPsec — Active Peers](https://help.mikrotik.com/docs/spaces/ROS/pages/11993097/IPsec), поля state/dynamic-address/remote-address/uptime. Приёмка подтверждена собственным native ответом и API, а не одной документацией.
## 12.5.77 — IPsec: основной раздел, RouterOS7 и реальная профильная приёмка (2026-10-09)
+14
View File
@@ -1884,3 +1884,17 @@ flowchart LR
```
Остаточные границы: online/active-peer корреляция, настоящая выдача mode-config, NAT/интернет, IPv6, Windows/macOS/iOS/Android подключения, late failure receipts/DB/transport, history restore, многопроцессность, IPsec-specific live JWT/RBAC и throughput не приняты этим блоком. Основной раздел внедрён и принят в перечисленных сценариях; этап12.5 и эти профильные ограничения остаются открытыми.
## 12.5.78 — IPsec: реальный online и адрес mode-config (2026-10-09)
**Результат.** Установленный PSK IKEv2 клиент отображался offline: RouterOS7 возвращает active-peers.id без префикса key-id:, а старый mapper ожидал remote-id; address/established также не соответствовали реальному ответу. Теперь используются id, state=established, dynamic-address (при наличии), remote-address и uptime. Для настроенного remote-id распознаются только известные префиксы key-id/fqdn/user-fqdn/address; starting/dying/отсутствующее состояние не подтверждают online. Изменены только ipsec-live.ts и профильный тест; UI-компоненты сохранены.
**Реальное подтверждение.** Собственный responder на194.226.121.150 и initiator на104.165.244.7: PSK, IKEv2, SHA256/AES256/modp2048, отдельные profile/proposal/group/template/mode-config/pool/peer/identity. На responder RouterOS и развёрнутый GET /api/ipsec?serverId=1 подтвердили established, online=true, activeAddress=198.18.78.10, activeSince=0s. Это проверка выдачи адреса и корреляции PSK, не NAT/интернет/throughput. На initiator remote-id=auto не связывается с персональным клиентом, его online=false не считается принятой корреляцией. Сертификатный/DN вариант остаётся открытым. [Очищенный отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json).
**Проверки и очистка.** npm --prefix backend run test:ipsec: config passed +77 state checks; backend TypeScript, scoped ESLint, diff check passed. Native/API сценарий прошёл на новом backend. До удаления проверены точные ID и атрибуты всех собственных объектов; после — исходные ID восьми коллекций совпали на обоих CHR. Пароли не менялись; flash не затрагивался. Первые три попытки настройки fixture завершились authentication failure; чтение IPsec logs показало identity not found. Удаление избыточных явных responder my-id / initiator remote-id восстановило переговоры; это настройка тестовой пары, приложение не меняет my-id этим блоком.
**Runtime и происхождение.** Единственная backend production сборка/deploy: mmapp-test/backend:ux-ipsec78, version1.0.0-test.ipsec78, image sha256:d25bb95996e7b917c8829a40e5d90cdcd75a4909e4a4654fcfc818f617262d81, healthy. Frontend остаётся ux-ipsec77; его сборка и общая UI-регрессия не повторялись, поскольку frontend не изменён. Backend context основан на предыдущем проверенном ipsec77 (production соответствует f80d9b7), с заменой ipsec-live.ts; SHA256 runtime исходника29b6843f9b6c80cc83af61ec44f3fdc99759ea656ba126722be3eb5f03501b0b совпал локально/удалённо. Архив двух backend-файлов3bf89cbefc57c3d0002da7285abaa300544700eb3ebeb9e5a83ad4622396ac3a; в нём тест на73 checks, ещё4 проверки префиксов добавлены локально после старта сборки и прошли — это не изменение production кода. Образ не заявляется сборкой из итогового Git SHA; label revision=ipsec78. Backup .env сохранён приватно на сервере; миграций БД нет.
**Организация.** По замечанию пользователя о длительности предыдущего блока: одна подтверждённая проблема, профильные проверки, одна backend сборка, без повторной frontend сборки и полного набора E2E. Расход пятичасового окна на контрольной точке8%; это квота, не длительность работы. Один локальный коммит без push. Следующий шаг12.5.79: проверить сертификатный active-peer/DN и mode-config, затем late failure receipts/DB/transport и history restore. Остальные ограничения12.5.77 сохраняются.
Референс: [RouterOS IPsec — Active Peers](https://help.mikrotik.com/docs/spaces/ROS/pages/11993097/IPsec), поля state/dynamic-address/remote-address/uptime. Приёмка подтверждена собственным native ответом и API, а не одной документацией.
+4 -2
View File
@@ -1,6 +1,6 @@
# Тестовый сервер UX/UI — 2026-10-09
Сервер161.104.46.222 предоставлен для временного тестирования. Backend/frontend ux-ipsec77/version1.0.0-test.ipsec77; backend/PG healthy, frontend HTTP/browser passed. Основной блок IPsec77 принят в границах журнала, own fixtures/fake DB rows удалены; каталог flash CHR2 сохранён из-за неподтверждённого ownership. SSH/оба CHR доступны, пароли прежние.
Сервер161.104.46.222 предоставлен для временного тестирования. Backend ux-ipsec78/version1.0.0-test.ipsec78, frontend ux-ipsec77/version1.0.0-test.ipsec77; backend/PG healthy, frontend HTTP/browser passed. Основной блок IPsec77 принят в границах журнала, own fixtures/fake DB rows удалены; каталог flash CHR2 сохранён из-за неподтверждённого ownership. SSH/оба CHR доступны, пароли прежние.
| Параметр | Проверенное состояние |
| --- | --- |
@@ -14,10 +14,12 @@
| PostgreSQL | postgres:18-alpine,18.6;mmapp-test-postgres healthy;SELECT version() passed |
| Данные | Отдельный Compose project mmapp-test,том mmapp-test_mmapp-pgdata и каталог ./data |
| Доступ | PostgreSQL не публикуется;frontend3000/backend8000 привязаны к127.0.0.1 после запуска |
| Образы приложения | mmapp-test/backend:ux-ipsec77 и mmapp-test/frontend:ux-ipsec77; запущены |
| Образы приложения | mmapp-test/backend:ux-ipsec78 и mmapp-test/frontend:ux-ipsec77; запущены |
Compose SHA256:3052bd6ab5d9865f97605cebfb5ff27a4410cd3357b81153a65a87fb7c92582f. OptionalBACKEND_IMAGE_TAG позволяетобновлятьbackendотдельно. Локальный и удалённый файлы совпали. Шаблоны: [Compose](../deploy/docker-compose.test.yml), [env без секретов](../deploy/env.test.example).
IPsec78: PSK active-peer/online и mode-config приняты через native и развёрнутый API; точные собственные ID удалены, восемь коллекций восстановлены. Одна backend сборка, без изменения frontend; подробности и границы — в12.5.78 журнала.
## Развёртывание приложения
Чистые frontend/backend build contexts подготовлены по .gitea/workflows/docker.yml из закреплённого Git HEAD;образы собраны на сервере без push. Локально docker CLI сейчас отсутствует, на сервере доступен Docker. В корневом .dockerignore исключён backend, поэтому обычный backend build из корня не повторяет CI: использовать отдельный backend context, как main workflow. Не передавать .env.local,backend/.env,ключи и локальные node_modules/.next.
@@ -0,0 +1,131 @@
{
"date": "2026-10-09",
"name": "mm-ipsec78-1791533486215",
"observations": [
{
"serverId": 1,
"identities": [
{
"peer": "mm-ipsec78-1791533486215",
"remote-id": "key-id:mm-ipsec78-1791533486215",
"auth-method": "pre-shared-key"
}
],
"active": [
{
"keys": [
".id",
"comment",
"dynamic-address",
"id",
"last-seen",
"local-address",
"natt-peer",
"ph2-total",
"port",
"ppk",
"remote-address",
"responder",
"rx-bytes",
"rx-packets",
"side",
"spii",
"spir",
"state",
"tx-bytes",
"tx-packets",
"uptime"
],
".id": "*1",
"id": "mm-ipsec78-1791533486215",
"state": "established",
"remote-address": "104.165.244.7",
"dynamic-address": "198.18.78.10",
"uptime": "0s",
"side": "responder"
}
],
"catalog": [
{
"name": "mm-ipsec78-1791533486215",
"remoteId": "key-id:mm-ipsec78-1791533486215",
"online": true,
"activeAddress": "198.18.78.10",
"activeSince": "0s"
}
]
},
{
"serverId": 2,
"identities": [
{
"peer": "mm-ipsec78-1791533486215",
"my-id": "key-id:mm-ipsec78-1791533486215",
"auth-method": "pre-shared-key"
}
],
"active": [
{
"keys": [
".id",
"comment",
"id",
"last-seen",
"local-address",
"natt-peer",
"ph2-total",
"port",
"ppk",
"remote-address",
"responder",
"rx-bytes",
"rx-packets",
"side",
"spii",
"spir",
"state",
"tx-bytes",
"tx-packets",
"uptime"
],
".id": "*1",
"id": "194.226.121.150",
"state": "established",
"remote-address": "194.226.121.150",
"uptime": "0s",
"side": "initiator"
}
],
"catalog": [
{
"name": "mm-ipsec78-1791533486215",
"online": false
}
]
}
],
"cleanup": [
{
"serverId": 1,
"/ip/ipsec/identity": true,
"/ip/ipsec/peer": true,
"/ip/ipsec/policy": true,
"/ip/ipsec/policy/group": true,
"/ip/ipsec/mode-config": true,
"/ip/pool": true,
"/ip/ipsec/proposal": true,
"/ip/ipsec/profile": true
},
{
"serverId": 2,
"/ip/ipsec/identity": true,
"/ip/ipsec/peer": true,
"/ip/ipsec/policy": true,
"/ip/ipsec/policy/group": true,
"/ip/ipsec/mode-config": true,
"/ip/pool": true,
"/ip/ipsec/proposal": true,
"/ip/ipsec/profile": true
}
]
}