Docker images / prepare-release (push) Successful in 15s
Docker images / backend-test (push) Successful in 2m32s
Docker images / frontend-image (push) Successful in 4m19s
Docker images / updater-image (push) Successful in 50s
Docker images / backend-image (push) Successful in 2m40s
Docker images / notify-webhook (push) Skipped
Docker images / publish-release (push) Successful in 8s
- мастер инициализации сервера: CA и серверный сертификаты, peer/profile/proposal, пул, mode-config, policy-template, managed NAT masquerade - клиенты по сертификату (RSA) и PSK: статический IP или из пула, онлайн-статус по active-peers - скачивание .p12 и strongSwan .sswan с инструкцией, перекачка с новой passphrase - история изменений (config_revisions, секция ipsec) и restore только managed-объектов - привязка IPsec-клиентов к пользователям приложения по Common Name - страница /ipsec с KPI и вкладками Клиенты/Сервер/CLI, сайдбар, command palette
192 lines
7.4 KiB
TypeScript
192 lines
7.4 KiB
TypeScript
import { z } from "zod"
|
||
|
||
export const ipsecAuthMethodSchema = z.enum(["certificate", "pre-shared-key"])
|
||
|
||
/** Клиент IKEv2 — /ip/ipsec/identity (+ опциональный персональный mode-config). */
|
||
export const ipsecClientDtoSchema = z.object({
|
||
id: z.string().min(1),
|
||
rosId: z.string().min(1),
|
||
serverId: z.string().min(1),
|
||
serverName: z.string(),
|
||
/** Управляемое имя клиента (из managed-комментария identity). */
|
||
name: z.string(),
|
||
authMethod: ipsecAuthMethodSchema,
|
||
certificateName: z.string().optional(),
|
||
commonName: z.string().optional(),
|
||
remoteId: z.string().optional(),
|
||
/** Статический IP клиента (персональный mode-config), undefined — из общего пула. */
|
||
staticIp: z.string().optional(),
|
||
modeConfigName: z.string().optional(),
|
||
peerName: z.string().optional(),
|
||
online: z.boolean(),
|
||
activeAddress: z.string().optional(),
|
||
activeSince: z.string().optional(),
|
||
disabled: z.boolean(),
|
||
comment: z.string().optional(),
|
||
/** Создан менеджером (managed-комментарий). */
|
||
managed: z.boolean(),
|
||
})
|
||
|
||
/** Слушатель IKEv2 — /ip/ipsec/peer (passive). */
|
||
export const ipsecPeerDtoSchema = z.object({
|
||
id: z.string().min(1),
|
||
rosId: z.string().min(1),
|
||
serverId: z.string().min(1),
|
||
serverName: z.string(),
|
||
name: z.string(),
|
||
address: z.string().optional(),
|
||
exchangeMode: z.string().optional(),
|
||
passive: z.boolean().optional(),
|
||
certificate: z.string().optional(),
|
||
profile: z.string().optional(),
|
||
disabled: z.boolean(),
|
||
comment: z.string().optional(),
|
||
managed: z.boolean(),
|
||
})
|
||
|
||
export const ipsecModeConfigDtoSchema = z.object({
|
||
id: z.string().min(1),
|
||
rosId: z.string().min(1),
|
||
serverId: z.string().min(1),
|
||
name: z.string(),
|
||
/** Общий пул (shared) или персональный статический адрес (per-user). */
|
||
addressPool: z.string().optional(),
|
||
address: z.string().optional(),
|
||
splitDns: z.string().optional(),
|
||
staticDns: z.string().optional(),
|
||
comment: z.string().optional(),
|
||
managed: z.boolean(),
|
||
})
|
||
|
||
export const ipsecPoolDtoSchema = z.object({
|
||
id: z.string().min(1),
|
||
rosId: z.string().min(1),
|
||
serverId: z.string().min(1),
|
||
name: z.string(),
|
||
ranges: z.string(),
|
||
comment: z.string().optional(),
|
||
managed: z.boolean(),
|
||
})
|
||
|
||
export const ipsecCertInfoDtoSchema = z.object({
|
||
name: z.string(),
|
||
commonName: z.string().optional(),
|
||
keySize: z.string().optional(),
|
||
fingerprint: z.string().optional(),
|
||
expiresAt: z.string().optional(),
|
||
trusted: z.boolean().optional(),
|
||
hasPrivateKey: z.boolean().optional(),
|
||
role: z.enum(["ca", "server", "client", "other"]).optional(),
|
||
managed: z.boolean(),
|
||
})
|
||
|
||
/** Сводка IKEv2-сервера на одном роутере. */
|
||
export const ipsecServerSummaryDtoSchema = z.object({
|
||
serverId: z.string().min(1),
|
||
serverName: z.string(),
|
||
serverCountry: z.string().optional(),
|
||
/** Managed-набор (CA + серверный серт + peer + mode-config) инициализирован. */
|
||
initialized: z.boolean(),
|
||
serverEndpoint: z.string().optional(),
|
||
peer: ipsecPeerDtoSchema.optional(),
|
||
pool: ipsecPoolDtoSchema.optional(),
|
||
sharedModeConfig: ipsecModeConfigDtoSchema.optional(),
|
||
caCert: ipsecCertInfoDtoSchema.optional(),
|
||
serverCert: ipsecCertInfoDtoSchema.optional(),
|
||
natRuleManaged: z.boolean(),
|
||
clientsTotal: z.number().int().nonnegative(),
|
||
clientsOnline: z.number().int().nonnegative(),
|
||
certs: z.array(ipsecCertInfoDtoSchema).optional(),
|
||
})
|
||
|
||
export const ipsecListResponseSchema = z.object({
|
||
servers: z.array(ipsecServerSummaryDtoSchema),
|
||
clients: z.array(ipsecClientDtoSchema),
|
||
failures: z
|
||
.array(
|
||
z.object({
|
||
serverId: z.string(),
|
||
serverName: z.string().optional(),
|
||
error: z.string(),
|
||
}),
|
||
)
|
||
.optional(),
|
||
})
|
||
|
||
export const ipsecInitRequestSchema = z.object({
|
||
serverId: z.union([z.string(), z.number()]),
|
||
/** Домен или IP для CN/SAN серверного сертификата (к нему подключаются клиенты). */
|
||
serverEndpoint: z.string().min(1),
|
||
/** Подсеть пула клиентов; из неё pool ranges .2–.254. */
|
||
poolCidr: z.string().regex(/^[0-9a-fA-F.:/]+$/).default("10.77.0.0/24"),
|
||
dns: z.string().optional(),
|
||
caDaysValid: z.number().int().positive().default(3650),
|
||
serverDaysValid: z.number().int().positive().default(3650),
|
||
clientDaysValid: z.number().int().positive().default(1825),
|
||
/** Managed srcnat masquerade, чтобы у клиентов был интернет. */
|
||
createNatRule: z.boolean().default(true),
|
||
})
|
||
|
||
export const ipsecUserCreateRequestSchema = z.object({
|
||
serverId: z.union([z.string(), z.number()]),
|
||
/** Отображаемое имя клиента; из него slug для серта/CN. */
|
||
name: z.string().min(1).max(64),
|
||
authMethod: ipsecAuthMethodSchema.default("certificate"),
|
||
psk: z.string().min(8).optional(),
|
||
remoteId: z.string().optional(),
|
||
/** Конкретный IP клиента; без — выдаётся из пула. */
|
||
staticIp: z.string().optional(),
|
||
/** Пароль на экспортируемый .p12. */
|
||
passphrase: z.string().min(4).optional(),
|
||
daysValid: z.number().int().positive().optional(),
|
||
})
|
||
|
||
export const ipsecUserPatchSchema = z.object({
|
||
name: z.string().min(1).max(64).optional(),
|
||
/** null — вернуть выдачу из пула. */
|
||
staticIp: z.string().nullable().optional(),
|
||
psk: z.string().min(8).optional(),
|
||
remoteId: z.string().optional(),
|
||
disabled: z.boolean().optional(),
|
||
})
|
||
|
||
export const ipsecCertExportRequestSchema = z.object({
|
||
serverId: z.union([z.string(), z.number()]),
|
||
clientId: z.string().min(1),
|
||
passphrase: z.string().min(4),
|
||
})
|
||
|
||
/** Бандл для авторизации клиента: .p12 (+ strongSwan .sswan + инструкция). */
|
||
export const ipsecCertBundleSchema = z.object({
|
||
user: z.string(),
|
||
serverEndpoint: z.string().optional(),
|
||
filename: z.string(),
|
||
contentB64: z.string(),
|
||
mime: z.string().default("application/x-pkcs12"),
|
||
passphrase: z.string().optional(),
|
||
sswanFilename: z.string().optional(),
|
||
sswanContent: z.string().optional(),
|
||
instructions: z.string().optional(),
|
||
})
|
||
|
||
export const ipsecUserCreatedSchema = z.object({
|
||
client: ipsecClientDtoSchema,
|
||
/** Одноразовый бандл сертификата (для cert-клиентов). */
|
||
bundle: ipsecCertBundleSchema.optional(),
|
||
})
|
||
|
||
export type IpsecAuthMethod = z.infer<typeof ipsecAuthMethodSchema>
|
||
export type IpsecClientDto = z.infer<typeof ipsecClientDtoSchema>
|
||
export type IpsecPeerDto = z.infer<typeof ipsecPeerDtoSchema>
|
||
export type IpsecModeConfigDto = z.infer<typeof ipsecModeConfigDtoSchema>
|
||
export type IpsecPoolDto = z.infer<typeof ipsecPoolDtoSchema>
|
||
export type IpsecCertInfoDto = z.infer<typeof ipsecCertInfoDtoSchema>
|
||
export type IpsecServerSummaryDto = z.infer<typeof ipsecServerSummaryDtoSchema>
|
||
export type IpsecListResponse = z.infer<typeof ipsecListResponseSchema>
|
||
export type IpsecInitRequest = z.infer<typeof ipsecInitRequestSchema>
|
||
export type IpsecUserCreateRequest = z.infer<typeof ipsecUserCreateRequestSchema>
|
||
export type IpsecUserPatch = z.infer<typeof ipsecUserPatchSchema>
|
||
export type IpsecCertExportRequest = z.infer<typeof ipsecCertExportRequestSchema>
|
||
export type IpsecCertBundle = z.infer<typeof ipsecCertBundleSchema>
|
||
export type IpsecUserCreated = z.infer<typeof ipsecUserCreatedSchema>
|