814 lines
41 KiB
TypeScript
814 lines
41 KiB
TypeScript
export type ServerStatus = "online" | "offline" | "degraded"
|
||
export type ServerType = "jump-host" | "exit-node" | "home-router"
|
||
|
||
export interface WanUplink {
|
||
id: string
|
||
name: string // "WAN1-RT"
|
||
isp: string // "Rostelecom"
|
||
iface: string // "ether1"
|
||
ip: string // external IP
|
||
maxDl: number // Mbps
|
||
maxUl: number // Mbps
|
||
}
|
||
|
||
// ─── WireGuard ───────────────────────────────────────────────────────────────
|
||
|
||
export interface WireGuardPeer {
|
||
publicKey: string
|
||
allowedIps: string[]
|
||
endpoint?: string // "1.2.3.4:13231"
|
||
latestHandshake?: string // "2 минуты назад"
|
||
transferRx?: number // bytes
|
||
transferTx?: number // bytes
|
||
persistent?: boolean
|
||
comment?: string
|
||
}
|
||
|
||
export interface WireGuardInterface {
|
||
id: string
|
||
name: string // e.g. "wg-msk-spb"
|
||
listenPort: number // default 13231
|
||
mtu: number // 1420 default in ROS 7.x
|
||
peers: WireGuardPeer[]
|
||
comment: string
|
||
enabled: boolean
|
||
status: "up" | "down"
|
||
}
|
||
|
||
export interface Server {
|
||
id: string
|
||
name: string
|
||
host: string // management IP / API address
|
||
model: string
|
||
os: string
|
||
site: string
|
||
country: string // ISO 3166-1 alpha-2, e.g. "RU", "DE"
|
||
asn: string
|
||
type: ServerType
|
||
enabled: boolean
|
||
status: ServerStatus
|
||
latency: number | null
|
||
sessions: number
|
||
comment?: string
|
||
// RouterOS 7.x extras
|
||
ipv6Address?: string // global or link-local
|
||
wireGuardIfaces?: WireGuardInterface[]
|
||
vrfNames?: string[] // VRF instances on this router
|
||
rpkiEnabled?: boolean
|
||
// home-router specific
|
||
wanUplinks?: WanUplink[]
|
||
lanSubnet?: string // e.g. "192.168.10.0/24"
|
||
// snapshot / poll data (как GET /api/servers — последний poll MikroTik)
|
||
uptime?: string
|
||
cpuLoad?: number
|
||
/** байты, поля RouterOS resource */
|
||
freeMemory?: number
|
||
totalMemory?: number
|
||
polledAt?: string
|
||
}
|
||
|
||
export interface FlowspecRule {
|
||
id: string
|
||
dstPrefix?: string
|
||
srcPrefix?: string
|
||
ipProto?: string
|
||
dstPort?: string
|
||
action: "rate-limit" | "discard" | "redirect"
|
||
rate?: number // Mbps, for rate-limit
|
||
comment?: string
|
||
}
|
||
|
||
export interface Filter {
|
||
id: string
|
||
name: string
|
||
domains: number
|
||
ips: number
|
||
asns: number
|
||
servers: string[]
|
||
enabled: boolean
|
||
updated: string
|
||
communities: string[]
|
||
gateway: string
|
||
// RouterOS 7.x extras
|
||
largeCommunities?: string[] // RFC 8092 format "AS:VALUE1:VALUE2"
|
||
rpkiValid?: boolean // filter only RPKI-valid routes
|
||
flowspecRules?: FlowspecRule[]
|
||
}
|
||
|
||
export interface Domain {
|
||
id: string
|
||
domain: string
|
||
resolvedIp: string
|
||
asn: string
|
||
purpose: string
|
||
filter: string
|
||
updated: string
|
||
enabled: boolean
|
||
}
|
||
|
||
export interface IpRange {
|
||
id: string
|
||
cidr: string
|
||
asn: string
|
||
country: string
|
||
purpose: string
|
||
filter: string
|
||
updated: string
|
||
enabled: boolean
|
||
}
|
||
|
||
export interface Asn {
|
||
id: string
|
||
asn: string
|
||
org: string
|
||
country: string
|
||
prefixes: number
|
||
filter: string
|
||
updated: string
|
||
enabled: boolean
|
||
}
|
||
|
||
export type FirewallAction =
|
||
| "accept" | "drop" | "reject" | "mark-routing" | "mark-conn"
|
||
| "masquerade" | "src-nat" | "dst-nat"
|
||
| "fasttrack-connection" | "nfqueue" | "passthrough" | "return"
|
||
| "add-src-to-address-list" | "add-dst-to-address-list"
|
||
|
||
export interface FirewallRule {
|
||
id: string
|
||
chain: string
|
||
action: FirewallAction | string
|
||
proto: string
|
||
src: string
|
||
dst: string
|
||
port: string
|
||
iface: string
|
||
comment: string
|
||
enabled: boolean
|
||
hits: number
|
||
// RouterOS 7.x extras
|
||
family?: "ip" | "ip6" | "any"
|
||
tlsHost?: string // tls-host matcher (SNI)
|
||
connRateLimit?: string // connection-rate e.g. "100/s"
|
||
layer7Proto?: string // /ip firewall layer7-protocol
|
||
nfqueueId?: number
|
||
log?: boolean
|
||
logPrefix?: string
|
||
}
|
||
|
||
export interface Backup {
|
||
id: string
|
||
server: string
|
||
filename: string
|
||
size: string
|
||
created: string
|
||
kind: "auto" | "manual"
|
||
notes: string
|
||
}
|
||
|
||
// ─── VXLAN ───────────────────────────────────────────────────────────────────
|
||
|
||
export interface VxlanTunnel {
|
||
id: string
|
||
name: string // "vxlan-overlay-1"
|
||
vni: number // 0–16777215
|
||
port: number // source port (default 0 = auto)
|
||
dstPort: number // destination port (default 8472)
|
||
serverId: string
|
||
vtepIp: string // VTEP address on the server
|
||
remoteVteps: string[] // remote VTEP IPs (unicast-flood)
|
||
l2mtu: number
|
||
arpProxy: boolean
|
||
macLearning: boolean
|
||
comment: string
|
||
enabled: boolean
|
||
status: "up" | "down"
|
||
}
|
||
|
||
// ─── VRF ─────────────────────────────────────────────────────────────────────
|
||
|
||
export interface VrfInstance {
|
||
id: string
|
||
name: string // VRF name
|
||
serverId: string
|
||
interfaces: string[] // list of interfaces in this VRF
|
||
routingTable: string // associated routing table
|
||
comment: string
|
||
}
|
||
|
||
// ─── Container (RouterOS 7.4+) ───────────────────────────────────────────────
|
||
|
||
export interface RouterContainer {
|
||
id: string
|
||
name: string
|
||
serverId: string
|
||
image: string // e.g. "nginx:alpine"
|
||
tag: string
|
||
status: "running" | "stopped" | "error"
|
||
envs: { key: string; value: string }[]
|
||
mounts: { dst: string; src?: string }[]
|
||
interfaces: string[] // veth interface names
|
||
cmd?: string
|
||
startOnBoot: boolean
|
||
comment: string
|
||
uptime?: string
|
||
cpu?: number // CPU % 0-100
|
||
memMb?: number // MB
|
||
}
|
||
|
||
// ─── Certificate ─────────────────────────────────────────────────────────────
|
||
|
||
export type CertUsage = "server" | "client" | "ca" | "crl-sign"
|
||
export type CertStatus = "valid" | "expired" | "revoked"
|
||
|
||
export interface RouterCertificate {
|
||
id: string
|
||
name: string
|
||
serverId: string
|
||
commonName: string
|
||
sans: string[]
|
||
issuedBy: string
|
||
validFrom: string
|
||
validUntil: string
|
||
daysLeft: number
|
||
keySize: number
|
||
usage: CertUsage[]
|
||
trusted: boolean
|
||
status: CertStatus
|
||
}
|
||
|
||
export interface PingProbe {
|
||
id: string
|
||
srcServerId: string // which server sends the ping
|
||
srcInterface?: string // optional interface name on source router
|
||
name: string
|
||
target: string
|
||
filter: string
|
||
rtt: number | null
|
||
loss: number
|
||
status: "up" | "warn" | "down"
|
||
series: number[]
|
||
enabled: boolean
|
||
/** Показывать в блоке «Активные пробы» на дашборде (звезда в мониторинге) */
|
||
showOnDashboard?: boolean
|
||
}
|
||
|
||
export interface SystemEvent {
|
||
id: string
|
||
sev: "destructive" | "warning" | "info"
|
||
title: string
|
||
message: string
|
||
when: string
|
||
}
|
||
|
||
function spark(n: number, base: number, range: number): number[] {
|
||
let s = base * 1000 + range
|
||
return Array.from({ length: n }, () => {
|
||
s = (s * 9301 + 49297) % 233280
|
||
const r = s / 233280
|
||
return Math.max(1, Math.round(base + (r - 0.5) * range * 2))
|
||
})
|
||
}
|
||
|
||
export const servers: Server[] = [
|
||
{
|
||
id: "srv1", name: "mt-msk-core-01", host: "10.0.0.1", model: "CCR2004-1G-12S+2XS", os: "7.20.1",
|
||
site: "MSK", country: "RU", asn: "AS65001", type: "jump-host", enabled: true, status: "online", latency: 12, sessions: 4,
|
||
ipv6Address: "2a01:4f8:1c1c:a1b2::1",
|
||
rpkiEnabled: true,
|
||
vrfNames: ["mgmt", "bypass"],
|
||
wireGuardIfaces: [
|
||
{
|
||
id: "wg1", name: "wg-msk-spb", listenPort: 13231, mtu: 1420, comment: "MSK → SPB overlay", enabled: true, status: "up",
|
||
peers: [
|
||
{ publicKey: "SPBPublicKeyBase64AAAAAAAAAAAAAAAAAAAAAA=", allowedIps: ["10.210.0.2/32","192.168.20.0/24"], endpoint: "10.0.1.1:13231", latestHandshake: "2 мин назад", transferRx: 182_400_000, transferTx: 64_800_000, persistent: true },
|
||
],
|
||
},
|
||
{
|
||
id: "wg2", name: "wg-msk-fra", listenPort: 13232, mtu: 1420, comment: "MSK → FRA overlay", enabled: true, status: "up",
|
||
peers: [
|
||
{ publicKey: "FRAPublicKeyBase64AAAAAAAAAAAAAAAAAAAAAA=", allowedIps: ["10.210.0.6/32"], endpoint: "10.0.2.1:13231", latestHandshake: "1 мин назад", transferRx: 421_000_000, transferTx: 210_000_000, persistent: true },
|
||
],
|
||
},
|
||
],
|
||
},
|
||
{
|
||
id: "srv2", name: "mt-spb-edge-01", host: "10.0.1.1", model: "CCR2116-12G-4S+", os: "7.20.1",
|
||
site: "SPB", country: "RU", asn: "AS65002", type: "exit-node", enabled: true, status: "online", latency: 28, sessions: 6,
|
||
ipv6Address: "2a01:4f8:1c2c:b2c3::1",
|
||
rpkiEnabled: true,
|
||
wireGuardIfaces: [
|
||
{
|
||
id: "wg3", name: "wg-spb-msk", listenPort: 13231, mtu: 1420, comment: "SPB → MSK overlay", enabled: true, status: "up",
|
||
peers: [
|
||
{ publicKey: "MSKPublicKeyBase64AAAAAAAAAAAAAAAAAAAAAA=", allowedIps: ["10.210.0.1/32"], endpoint: "10.0.0.1:13231", latestHandshake: "2 мин назад", transferRx: 64_800_000, transferTx: 182_400_000, persistent: true },
|
||
],
|
||
},
|
||
],
|
||
},
|
||
{
|
||
id: "srv3", name: "mt-fra-edge-01", host: "10.0.2.1", model: "CCR2004-16G-2S+", os: "7.20.1",
|
||
site: "FRA", country: "DE", asn: "AS65003", type: "exit-node", enabled: true, status: "online", latency: 41, sessions: 3,
|
||
ipv6Address: "2a01:4f8:1c3c:c3d4::1",
|
||
rpkiEnabled: true,
|
||
wireGuardIfaces: [
|
||
{
|
||
id: "wg4", name: "wg-fra-msk", listenPort: 13231, mtu: 1420, comment: "FRA → MSK overlay", enabled: true, status: "up",
|
||
peers: [
|
||
{ publicKey: "MSKPublicKeyBase64AAAAAAAAAAAAAAAAAAAAAA=", allowedIps: ["10.210.0.1/32"], endpoint: "10.0.0.1:13232", latestHandshake: "1 мин назад", transferRx: 210_000_000, transferTx: 421_000_000, persistent: true },
|
||
],
|
||
},
|
||
],
|
||
},
|
||
{
|
||
id: "srv4", name: "mt-ams-edge-01", host: "10.0.3.1", model: "RB5009UG+S+IN", os: "7.19.3",
|
||
site: "AMS", country: "NL", asn: "AS65004", type: "exit-node", enabled: true, status: "degraded", latency: 88, sessions: 2,
|
||
},
|
||
{
|
||
id: "srv5", name: "mt-sgp-edge-01", host: "10.0.4.1", model: "CCR2004-1G-12S+2XS", os: "7.14.2",
|
||
site: "SGP", country: "SG", asn: "AS65005", type: "exit-node", enabled: false, status: "offline", latency: null, sessions: 0,
|
||
},
|
||
{
|
||
id: "srv6", name: "mt-ams-test-01", host: "10.0.3.2", model: "hEX S", os: "7.20.1",
|
||
site: "AMS", country: "NL", asn: "AS65006", type: "jump-host", enabled: true, status: "online", latency: 92, sessions: 1,
|
||
},
|
||
{
|
||
id: "srv7", name: "mt-msk-lab-01", host: "10.0.0.7", model: "RB5009UG+S+IN", os: "7.20.1",
|
||
site: "MSK", country: "RU", asn: "AS65007", type: "jump-host", enabled: true, status: "online", latency: 14, sessions: 2,
|
||
vrfNames: ["lab"],
|
||
},
|
||
{
|
||
id: "home1", name: "home-msk-01", host: "192.168.10.1", model: "hEX S (RB760iGS)", os: "7.20.1",
|
||
site: "MSK", country: "RU", asn: "", type: "home-router", enabled: true, status: "online", latency: 3, sessions: 0,
|
||
comment: "MSK офис — основной роутер",
|
||
lanSubnet: "192.168.10.0/24",
|
||
wanUplinks: [
|
||
{ id: "w1a", name: "WAN1-RT", isp: "Rostelecom", iface: "ether1", ip: "94.25.168.1", maxDl: 500, maxUl: 500 },
|
||
{ id: "w1b", name: "WAN2-BL", isp: "Beeline", iface: "ether2", ip: "85.174.12.1", maxDl: 100, maxUl: 100 },
|
||
],
|
||
},
|
||
{
|
||
id: "home2", name: "home-spb-01", host: "192.168.20.1", model: "RB5009UG+S+IN", os: "7.20.1",
|
||
site: "SPB", country: "RU", asn: "", type: "home-router", enabled: true, status: "online", latency: 5, sessions: 0,
|
||
comment: "SPB офис — основной роутер",
|
||
lanSubnet: "192.168.20.0/24",
|
||
wanUplinks: [
|
||
{ id: "w2a", name: "WAN1-MTS", isp: "МТС", iface: "ether1", ip: "178.214.4.1", maxDl: 300, maxUl: 300 },
|
||
{ id: "w2b", name: "WAN2-ERT", isp: "ЭР-Телеком", iface: "ether2", ip: "95.31.14.1", maxDl: 200, maxUl: 150 },
|
||
],
|
||
},
|
||
]
|
||
|
||
export const filters: Filter[] = [
|
||
{
|
||
id: "f1", name: "youtube-bypass", domains: 1842, ips: 4218, asns: 12,
|
||
servers: ["srv1","srv2","srv3","srv4"], enabled: true, updated: "12 мин назад",
|
||
communities: ["65001:100","65001:200"], gateway: "10.0.0.1",
|
||
largeCommunities: ["65001:100:1","65001:100:2"],
|
||
rpkiValid: true,
|
||
},
|
||
{
|
||
id: "f2", name: "streaming-eu", domains: 612, ips: 2104, asns: 8,
|
||
servers: ["srv2","srv3","srv4"], enabled: true, updated: "2 ч назад",
|
||
communities: ["65001:200"], gateway: "10.0.1.1",
|
||
largeCommunities: ["65001:200:1"],
|
||
rpkiValid: true,
|
||
},
|
||
{
|
||
id: "f3", name: "cdn-bypass", domains: 4218, ips: 18211, asns: 22,
|
||
servers: ["srv1","srv2","srv3","srv4","srv6"], enabled: true, updated: "1 ч назад",
|
||
communities: ["65001:300","65002:100"], gateway: "10.0.0.1",
|
||
flowspecRules: [
|
||
{ id: "fs1", dstPrefix: "104.16.0.0/12", ipProto: "tcp", dstPort: "443", action: "rate-limit", rate: 100, comment: "CF rate-limit" },
|
||
],
|
||
},
|
||
{ id: "f4", name: "social-block-school", domains: 84, ips: 412, asns: 4, servers: ["srv1","srv7"], enabled: false, updated: "3 дн назад", communities: ["65007:999"], gateway: "" },
|
||
{ id: "f5", name: "office-direct", domains: 142, ips: 884, asns: 6, servers: ["srv1","srv2","srv3","srv4","srv6","srv7"], enabled: true, updated: "4 ч назад", communities: ["65001:400"], gateway: "10.0.0.1" },
|
||
{ id: "f6", name: "gaming-low-latency", domains: 88, ips: 1212, asns: 14, servers: ["srv1","srv2","srv3","srv7"], enabled: true, updated: "24 мин назад", communities: ["65001:500","65002:200"], gateway: "10.0.2.1" },
|
||
]
|
||
|
||
export const domains: Domain[] = [
|
||
{ id: "d1", domain: "youtube.com", purpose: "streaming", filter: "youtube-bypass", resolvedIp: "142.250.74.110", asn: "AS15169", updated: "12 мин", enabled: true },
|
||
{ id: "d2", domain: "googlevideo.com", purpose: "streaming", filter: "youtube-bypass", resolvedIp: "142.250.74.142", asn: "AS15169", updated: "12 мин", enabled: true },
|
||
{ id: "d3", domain: "ytimg.com", purpose: "streaming", filter: "youtube-bypass", resolvedIp: "172.217.16.46", asn: "AS15169", updated: "12 мин", enabled: true },
|
||
{ id: "d4", domain: "netflix.com", purpose: "streaming", filter: "streaming-eu", resolvedIp: "54.246.79.9", asn: "AS2906", updated: "2 ч", enabled: true },
|
||
{ id: "d5", domain: "nflxvideo.net", purpose: "streaming", filter: "streaming-eu", resolvedIp: "45.57.32.18", asn: "AS2906", updated: "2 ч", enabled: true },
|
||
{ id: "d6", domain: "cloudflare.com", purpose: "cdn", filter: "cdn-bypass", resolvedIp: "104.16.132.229", asn: "AS13335", updated: "1 ч", enabled: true },
|
||
{ id: "d7", domain: "akamaized.net", purpose: "cdn", filter: "cdn-bypass", resolvedIp: "23.46.18.94", asn: "AS20940", updated: "1 ч", enabled: true },
|
||
{ id: "d8", domain: "fastly.net", purpose: "cdn", filter: "cdn-bypass", resolvedIp: "151.101.1.95", asn: "AS54113", updated: "1 ч", enabled: true },
|
||
{ id: "d9", domain: "twitch.tv", purpose: "streaming", filter: "streaming-eu", resolvedIp: "52.223.241.72", asn: "AS16509", updated: "2 ч", enabled: false },
|
||
{ id: "d10", domain: "discord.com", purpose: "voip", filter: "gaming-low-latency", resolvedIp: "162.159.135.232", asn: "AS13335", updated: "24 мин", enabled: true },
|
||
{ id: "d11", domain: "steam.com", purpose: "gaming", filter: "gaming-low-latency", resolvedIp: "23.45.139.40", asn: "AS20940", updated: "24 мин", enabled: true },
|
||
{ id: "d12", domain: "epicgames.com", purpose: "gaming", filter: "gaming-low-latency", resolvedIp: "34.205.247.51", asn: "AS16509", updated: "24 мин", enabled: true },
|
||
]
|
||
|
||
export const ipRanges: IpRange[] = [
|
||
{ id: "i1", cidr: "142.250.0.0/15", purpose: "streaming", filter: "youtube-bypass", asn: "AS15169", country: "US", updated: "12 мин", enabled: true },
|
||
{ id: "i2", cidr: "172.217.0.0/16", purpose: "streaming", filter: "youtube-bypass", asn: "AS15169", country: "US", updated: "12 мин", enabled: true },
|
||
{ id: "i3", cidr: "104.16.0.0/12", purpose: "cdn", filter: "cdn-bypass", asn: "AS13335", country: "US", updated: "1 ч", enabled: true },
|
||
{ id: "i4", cidr: "23.32.0.0/11", purpose: "cdn", filter: "cdn-bypass", asn: "AS20940", country: "US", updated: "1 ч", enabled: true },
|
||
{ id: "i5", cidr: "151.101.0.0/16", purpose: "cdn", filter: "cdn-bypass", asn: "AS54113", country: "US", updated: "1 ч", enabled: true },
|
||
{ id: "i6", cidr: "54.246.0.0/16", purpose: "streaming", filter: "streaming-eu", asn: "AS2906", country: "IE", updated: "2 ч", enabled: true },
|
||
{ id: "i7", cidr: "45.57.0.0/16", purpose: "streaming", filter: "streaming-eu", asn: "AS2906", country: "NL", updated: "2 ч", enabled: true },
|
||
{ id: "i8", cidr: "162.159.128.0/19", purpose: "voip", filter: "gaming-low-latency", asn: "AS13335", country: "US", updated: "24 мин", enabled: true },
|
||
{ id: "i9", cidr: "52.223.240.0/20", purpose: "streaming", filter: "streaming-eu", asn: "AS16509", country: "IE", updated: "2 ч", enabled: false },
|
||
]
|
||
|
||
export const asns: Asn[] = [
|
||
{ id: "a1", asn: "AS15169", org: "GOOGLE", country: "US", prefixes: 842, filter: "youtube-bypass", updated: "12 мин", enabled: true },
|
||
{ id: "a2", asn: "AS13335", org: "CLOUDFLARENET", country: "US", prefixes: 1284, filter: "cdn-bypass", updated: "1 ч", enabled: true },
|
||
{ id: "a3", asn: "AS16509", org: "AMAZON-02", country: "US", prefixes: 4128, filter: "streaming-eu", updated: "2 ч", enabled: true },
|
||
{ id: "a4", asn: "AS20940", org: "AKAMAI-ASN1", country: "US", prefixes: 614, filter: "cdn-bypass", updated: "1 ч", enabled: true },
|
||
{ id: "a5", asn: "AS54113", org: "FASTLY", country: "US", prefixes: 122, filter: "cdn-bypass", updated: "1 ч", enabled: true },
|
||
{ id: "a6", asn: "AS2906", org: "AS-SSI (Netflix)", country: "US", prefixes: 88, filter: "streaming-eu", updated: "2 ч", enabled: true },
|
||
{ id: "a7", asn: "AS32934", org: "FACEBOOK", country: "US", prefixes: 412, filter: "social-block-school",updated: "3 дн", enabled: false },
|
||
{ id: "a8", asn: "AS8075", org: "MICROSOFT-CORP", country: "US", prefixes: 882, filter: "office-direct", updated: "4 ч", enabled: true },
|
||
]
|
||
|
||
export const firewallRules: FirewallRule[] = [
|
||
{ id: "fw1", chain: "forward", action: "accept", proto: "tcp", src: "youtube-bypass", dst: "0.0.0.0/0", port: "443", iface: "wan-bgp", comment: "YouTube bypass traffic", enabled: true, hits: 188421 },
|
||
{ id: "fw2", chain: "forward", action: "mark-routing", proto: "tcp", src: "10.10.0.0/24", dst: "cdn-bypass", port: "—", iface: "lan", comment: "CDN routing mark", enabled: true, hits: 4128821 },
|
||
{ id: "fw3", chain: "srcnat", action: "masquerade", proto: "all", src: "10.10.0.0/16", dst: "0.0.0.0/0", port: "—", iface: "wan-msk", comment: "Main NAT rule", enabled: true, hits: 12889241 },
|
||
{ id: "fw4", chain: "forward", action: "drop", proto: "tcp", src: "0.0.0.0/0", dst: "social-block-school", port: "—", iface: "lan-school", comment: "School social block", enabled: true, hits: 4218 },
|
||
{ id: "fw5", chain: "input", action: "accept", proto: "tcp", src: "10.10.0.0/16", dst: "—", port: "22,443,8291",iface: "—", comment: "Management access", enabled: true, hits: 18412 },
|
||
{ id: "fw6", chain: "input", action: "drop", proto: "tcp", src: "0.0.0.0/0", dst: "—", port: "22", iface: "wan-msk", comment: "Block SSH from WAN", enabled: true, hits: 882412 },
|
||
]
|
||
|
||
export const backups: Backup[] = [
|
||
{ id: "b1", server: "mt-msk-core-01", filename: "mt-msk-core-01_2026-04-26_03-00.rsc", size: "124 КБ", created: "Сегодня, 03:00", kind: "auto", notes: "снапшот перед обновлением" },
|
||
{ id: "b2", server: "mt-msk-core-01", filename: "mt-msk-core-01_2026-04-25_03-00.rsc", size: "124 КБ", created: "Вчера, 03:00", kind: "auto", notes: "" },
|
||
{ id: "b3", server: "mt-spb-edge-01", filename: "mt-spb-edge-01_2026-04-26_03-00.rsc", size: "88 КБ", created: "Сегодня, 03:00", kind: "auto", notes: "" },
|
||
{ id: "b4", server: "mt-fra-edge-01", filename: "mt-fra-edge-01_2026-04-26_manual.rsc",size: "92 КБ", created: "Сегодня, 14:18", kind: "manual", notes: "перед изменением BGP" },
|
||
{ id: "b5", server: "mt-ams-edge-01", filename: "mt-ams-edge-01_2026-04-25_03-00.rsc", size: "64 КБ", created: "Вчера, 03:00", kind: "auto", notes: "" },
|
||
]
|
||
|
||
export const pingProbes: PingProbe[] = [
|
||
// srv1 — mt-msk-core-01 (JH, MSK) → основной мониторинг
|
||
{ id: "p1", srcServerId: "srv1", name: "youtube.com", target: "142.250.74.110", filter: "youtube-bypass", rtt: 18, loss: 0, status: "up", series: spark(40, 18, 4), enabled: true },
|
||
{ id: "p2", srcServerId: "srv1", name: "cloudflare.com", target: "104.16.132.229", filter: "cdn-bypass", rtt: 4, loss: 0, status: "up", series: spark(40, 4, 1), enabled: true },
|
||
{ id: "p3", srcServerId: "srv1", name: "netflix-eu", target: "54.246.79.9", filter: "streaming-eu", rtt: 28, loss: 0, status: "up", series: spark(40, 28, 5), enabled: true },
|
||
{ id: "p4", srcServerId: "srv1", name: "fastly-edge", target: "151.101.1.95", filter: "cdn-bypass", rtt: 8, loss: 0, status: "up", series: spark(40, 8, 2), enabled: true },
|
||
// srv7 — mt-msk-lab-01 (JH, MSK) → лаборатория
|
||
{ id: "p5", srcServerId: "srv7", name: "discord-voip", target: "162.159.135.232", filter: "gaming-low-latency", rtt: 12, loss: 0, status: "up", series: spark(40, 12, 2), enabled: true },
|
||
{ id: "p6", srcServerId: "srv7", name: "steam-cdn", target: "23.45.139.40", filter: "gaming-low-latency", rtt: 38, loss: 1.2, status: "warn", series: spark(40, 38, 12), enabled: true },
|
||
{ id: "p7", srcServerId: "srv7", name: "akamai-edge", target: "23.46.18.94", filter: "cdn-bypass", rtt: 22, loss: 0, status: "up", series: spark(40, 22, 4), enabled: true },
|
||
// srv2 — mt-spb-edge-01 (EN, SPB) → исходящий трафик SPB
|
||
{ id: "p8", srcServerId: "srv2", name: "youtube.com", target: "142.250.74.110", filter: "youtube-bypass", rtt: 22, loss: 0, status: "up", series: spark(40, 22, 5), enabled: true },
|
||
{ id: "p9", srcServerId: "srv2", name: "office-365", target: "104.47.0.22", filter: "office-direct", rtt: 31, loss: 0, status: "up", series: spark(40, 31, 6), enabled: false },
|
||
// srv3 — mt-fra-edge-01 (EN, FRA) → исходящий трафик Frankfurt
|
||
{ id: "p10", srcServerId: "srv3", name: "youtube.com", target: "142.250.74.110", filter: "youtube-bypass", rtt: 12, loss: 0, status: "up", series: spark(40, 12, 3), enabled: true },
|
||
{ id: "p11", srcServerId: "srv3", name: "netflix-eu", target: "54.246.79.9", filter: "streaming-eu", rtt: 9, loss: 0, status: "up", series: spark(40, 9, 2), enabled: true },
|
||
// srv4 — mt-ams-edge-01 (EN, AMS, degraded) → деградировавший узел
|
||
{ id: "p12", srcServerId: "srv4", name: "cloudflare.com", target: "104.16.132.229", filter: "cdn-bypass", rtt: 88, loss: 3.4, status: "warn", series: spark(40, 88, 22), enabled: true },
|
||
{ id: "p13", srcServerId: "srv4", name: "sgp-probe", target: "139.180.22.4", filter: "—", rtt: null,loss: 100, status: "down", series: Array(40).fill(0), enabled: true },
|
||
]
|
||
|
||
export const systemEvents: SystemEvent[] = [
|
||
{ id: "e1", sev: "destructive", title: "BGP-сессия упала", message: "mt-sgp-edge-01 · пир 139.180.22.4 · простой 2ч", when: "2ч" },
|
||
{ id: "e2", sev: "destructive", title: "Ошибка синхронизации фильтра", message: "cdn-bypass → mt-ams-edge-01 · таймаут", when: "14м" },
|
||
{ id: "e3", sev: "warning", title: "Высокая задержка на AMS", message: "среднее 88мс · порог 60мс", when: "8м" },
|
||
{ id: "e4", sev: "warning", title: "Бэкап просрочен", message: "mt-msk-lab-01 · последний 5д назад", when: "1ч" },
|
||
{ id: "e5", sev: "info", title: "Обновление BGP завершено", message: "+412 префиксов · −188 отозвано", when: "12м" },
|
||
{ id: "e6", sev: "info", title: "Фильтр youtube-bypass обновлён", message: "+88 доменов · ↑ 24 сервера", when: "12м" },
|
||
]
|
||
|
||
export const dashLatency = {
|
||
msk: spark(60, 12, 4),
|
||
spb: spark(60, 28, 6),
|
||
fra: spark(60, 41, 9),
|
||
ams: spark(60, 88, 18),
|
||
}
|
||
|
||
export const traffic = {
|
||
rx: Array.from({ length: 60 }, (_, i) => Math.round(280 + Math.sin(i / 6) * 60 + ((i * 7919) % 31))),
|
||
tx: Array.from({ length: 60 }, (_, i) => Math.round(220 + Math.sin(i / 5) * 50 + ((i * 6271) % 21))),
|
||
}
|
||
|
||
// ─── GRE ────────────────────────────────────────────────────────────────────
|
||
|
||
export type GreStatus = "up" | "down" | "degraded"
|
||
export type IpsecEncAlg = "aes-128" | "aes-192" | "aes-256"
|
||
export type IpsecAuthAlg = "sha1" | "sha256" | "sha512"
|
||
export type IpsecDhGroup = "modp1024" | "modp2048" | "modp4096" | "ecp256" | "ecp384" | "ecp521"
|
||
export type IkeVersion = "ikev1" | "ikev2"
|
||
export type DscpMode = "inherit" | number
|
||
|
||
export interface GreIpsec {
|
||
secret: string // ipsec-secret → auto-creates peer+policy+proposal
|
||
encAlg: IpsecEncAlg // proposal enc-algorithms
|
||
authAlg: IpsecAuthAlg // proposal auth-algorithms
|
||
dhGroup: IpsecDhGroup // proposal pfs-group / peer dh-group
|
||
ikeVersion: IkeVersion // peer exchange-mode
|
||
lifetime: string // proposal lifetime (e.g. "1d 00:00:00")
|
||
pfs: boolean // perfect forward secrecy
|
||
}
|
||
|
||
export interface GreTunnel {
|
||
id: string
|
||
name: string // interface name, e.g. gre-msk-spb
|
||
serverId: string // which MikroTik runs this tunnel
|
||
localAddress: string // local GRE endpoint ("0.0.0.0" = auto)
|
||
remoteAddress: string // remote GRE endpoint (required)
|
||
localInnerIp: string // /ip address on this side, e.g. 10.200.0.1/30
|
||
remoteInnerIp: string // /ip address on remote side, e.g. 10.200.0.2/30
|
||
poolId: string // which IP pool the inner IPs come from
|
||
ipsec: GreIpsec | null // null = no IPsec (plain GRE)
|
||
mtu: number // default 1476
|
||
keepaliveInterval: number // seconds, 0 = disabled
|
||
keepaliveRetries: number
|
||
dscp: DscpMode // "inherit" or 0-63
|
||
clampTcpMss: boolean
|
||
allowFastPath: boolean
|
||
comment: string
|
||
enabled: boolean
|
||
status: GreStatus
|
||
}
|
||
|
||
export interface GrePool {
|
||
id: string
|
||
name: string
|
||
cidr: string
|
||
allocated: number
|
||
total: number
|
||
comment: string
|
||
}
|
||
|
||
const defaultIpsec = (secret: string, ikeVersion: IkeVersion = "ikev2"): GreIpsec => ({
|
||
secret,
|
||
encAlg: "aes-256",
|
||
authAlg: "sha256",
|
||
dhGroup: "modp2048",
|
||
ikeVersion,
|
||
lifetime: "1d 00:00:00",
|
||
pfs: true,
|
||
})
|
||
|
||
export const grePools: GrePool[] = [
|
||
{ id: "gp1", name: "pool-gre-core", cidr: "10.200.0.0/24", allocated: 16, total: 64, comment: "Ядровые межузловые туннели" },
|
||
{ id: "gp2", name: "pool-gre-mgmt", cidr: "10.201.0.0/24", allocated: 8, total: 64, comment: "Управляющие туннели (lab, test)" },
|
||
]
|
||
|
||
export const greTunnels: GreTunnel[] = [
|
||
{
|
||
id: "gre1", name: "gre-msk-spb", serverId: "srv1",
|
||
localAddress: "10.0.0.1", remoteAddress: "10.0.1.1",
|
||
localInnerIp: "10.200.0.1/30", remoteInnerIp: "10.200.0.2/30", poolId: "gp1",
|
||
ipsec: defaultIpsec("xK9#mQ2$vLp8nR4"),
|
||
mtu: 1476, keepaliveInterval: 10, keepaliveRetries: 10,
|
||
dscp: "inherit", clampTcpMss: true, allowFastPath: true,
|
||
comment: "MSK → SPB core interconnect", enabled: true, status: "up",
|
||
},
|
||
{
|
||
id: "gre2", name: "gre-msk-fra", serverId: "srv1",
|
||
localAddress: "10.0.0.1", remoteAddress: "10.0.2.1",
|
||
localInnerIp: "10.200.0.5/30", remoteInnerIp: "10.200.0.6/30", poolId: "gp1",
|
||
ipsec: defaultIpsec("pW3@jT7!hD5kYe1"),
|
||
mtu: 1476, keepaliveInterval: 10, keepaliveRetries: 10,
|
||
dscp: "inherit", clampTcpMss: true, allowFastPath: true,
|
||
comment: "MSK → FRA core interconnect", enabled: true, status: "up",
|
||
},
|
||
{
|
||
id: "gre3", name: "gre-msk-ams", serverId: "srv1",
|
||
localAddress: "10.0.0.1", remoteAddress: "10.0.3.1",
|
||
localInnerIp: "10.200.0.9/30", remoteInnerIp: "10.200.0.10/30", poolId: "gp1",
|
||
ipsec: defaultIpsec("rN6%bF2*cM8sZa0"),
|
||
mtu: 1476, keepaliveInterval: 10, keepaliveRetries: 10,
|
||
dscp: "inherit", clampTcpMss: true, allowFastPath: false,
|
||
comment: "MSK → AMS core interconnect", enabled: true, status: "degraded",
|
||
},
|
||
{
|
||
id: "gre4", name: "gre-msk-sgp", serverId: "srv1",
|
||
localAddress: "10.0.0.1", remoteAddress: "10.0.4.1",
|
||
localInnerIp: "10.200.0.13/30", remoteInnerIp: "10.200.0.14/30", poolId: "gp1",
|
||
ipsec: defaultIpsec("qA4^eU9#wG1oXi6"),
|
||
mtu: 1476, keepaliveInterval: 10, keepaliveRetries: 10,
|
||
dscp: "inherit", clampTcpMss: true, allowFastPath: true,
|
||
comment: "MSK → SGP core interconnect", enabled: false, status: "down",
|
||
},
|
||
{
|
||
id: "gre5", name: "gre-lab-core", serverId: "srv7",
|
||
localAddress: "10.0.0.7", remoteAddress: "10.0.0.1",
|
||
localInnerIp: "10.201.0.1/30", remoteInnerIp: "10.201.0.2/30", poolId: "gp2",
|
||
ipsec: null,
|
||
mtu: 1500, keepaliveInterval: 0, keepaliveRetries: 0,
|
||
dscp: "inherit", clampTcpMss: false, allowFastPath: true,
|
||
comment: "Lab → core (internal, no IPsec)", enabled: true, status: "up",
|
||
},
|
||
{
|
||
id: "gre6", name: "gre-ams-test", serverId: "srv6",
|
||
localAddress: "10.0.3.2", remoteAddress: "10.0.3.1",
|
||
localInnerIp: "10.201.0.5/30", remoteInnerIp: "10.201.0.6/30", poolId: "gp2",
|
||
ipsec: null,
|
||
mtu: 1476, keepaliveInterval: 5, keepaliveRetries: 5,
|
||
dscp: 0, clampTcpMss: true, allowFastPath: true,
|
||
comment: "AMS test → AMS edge", enabled: true, status: "up",
|
||
},
|
||
]
|
||
|
||
// ─── Filter Rules (Community → Gateway per server) ────────────────────────────
|
||
|
||
export interface FilterRule {
|
||
id: string
|
||
community: string // BGP community, e.g. "65001:100"
|
||
communityName?: string // optional human-readable name
|
||
action?: "route" | "blackhole" // default "route"; "blackhole" → null-route (RTBH)
|
||
gateway: string // next-hop IP for filter rule; empty for blackhole
|
||
/** GRE: id туннеля / имя интерфейса; рекурсивный маршрут: `rec:<id>` строки recursive_routes на сервере */
|
||
gatewayTunnelId: string
|
||
description: string
|
||
}
|
||
|
||
export interface ServerFilterRuleset {
|
||
serverId: string
|
||
rules: FilterRule[]
|
||
}
|
||
|
||
export const serverFilterRulesets: ServerFilterRuleset[] = [
|
||
// srv1 — mt-msk-core-01 (jump-host, MSK): gre1=SPB, gre2=FRA, gre3=AMS(deg), gre4=SGP(down)
|
||
{
|
||
serverId: "srv1",
|
||
rules: [
|
||
{ id: "r1", community: "65001:100", communityName: "youtube-bypass", gateway: "10.200.0.6", gatewayTunnelId: "gre2", description: "YouTube/Google Video → Frankfurt (IX)" },
|
||
{ id: "r2", community: "65001:200", communityName: "streaming-eu", gateway: "10.200.0.6", gatewayTunnelId: "gre2", description: "Netflix, Twitch EU → Frankfurt" },
|
||
{ id: "r3", community: "65001:300", communityName: "cdn-bypass", gateway: "10.200.0.2", gatewayTunnelId: "gre1", description: "Cloudflare / Akamai / Fastly → SPB" },
|
||
{ id: "r4", community: "65002:100", communityName: "cdn-secondary", gateway: "10.200.0.10", gatewayTunnelId: "gre3", description: "CDN резерв → Amsterdam (degraded)" },
|
||
{ id: "r5", community: "65001:400", communityName: "office-direct", gateway: "10.200.0.2", gatewayTunnelId: "gre1", description: "MS Office 365 / Teams → SPB direct" },
|
||
{ id: "r6", community: "65001:500", communityName: "gaming-ll", gateway: "10.200.0.2", gatewayTunnelId: "gre1", description: "Discord / Steam / Epic — низкая задержка → SPB" },
|
||
{ id: "r10", community: "65535:666", communityName: "BLACKHOLE (RFC 7999)", action: "blackhole", gateway: "", gatewayTunnelId: "", description: "RTBH — null-route входящих маршрутов" },
|
||
{ id: "r11", community: "65001:666", communityName: "blackhole-local", action: "blackhole", gateway: "", gatewayTunnelId: "", description: "Локальная блокировка — сброс трафика" },
|
||
],
|
||
},
|
||
// srv7 — mt-msk-lab-01 (jump-host, MSK lab): gre5=core
|
||
{
|
||
serverId: "srv7",
|
||
rules: [
|
||
{ id: "r7", community: "65001:100", communityName: "youtube-bypass", gateway: "10.201.0.2", gatewayTunnelId: "gre5", description: "Lab: YouTube → core" },
|
||
{ id: "r8", community: "65007:999", communityName: "school-block", gateway: "10.201.0.2", gatewayTunnelId: "gre5", description: "Lab: школьная блокировка" },
|
||
],
|
||
},
|
||
// srv6 — mt-ams-test-01 (jump-host, AMS test): gre6=AMS edge
|
||
{
|
||
serverId: "srv6",
|
||
rules: [
|
||
{ id: "r9", community: "65001:300", communityName: "cdn-bypass", gateway: "10.201.0.6", gatewayTunnelId: "gre6", description: "AMS test: CDN → AMS edge" },
|
||
],
|
||
},
|
||
// Exit nodes — нет правил по умолчанию
|
||
{ serverId: "srv2", rules: [] },
|
||
{ serverId: "srv3", rules: [] },
|
||
{ serverId: "srv4", rules: [] },
|
||
{ serverId: "srv5", rules: [] },
|
||
]
|
||
|
||
// ─── VXLAN mock data ─────────────────────────────────────────────────────────
|
||
|
||
export const vxlanTunnels: VxlanTunnel[] = [
|
||
{
|
||
id: "vx1", name: "vxlan-overlay-msk", vni: 10010, port: 0, dstPort: 8472,
|
||
serverId: "srv1", vtepIp: "10.0.0.1", remoteVteps: ["10.0.1.1","10.0.2.1"],
|
||
l2mtu: 1500, arpProxy: true, macLearning: true,
|
||
comment: "MSK overlay — сегмент bypass", enabled: true, status: "up",
|
||
},
|
||
{
|
||
id: "vx2", name: "vxlan-overlay-spb", vni: 10010, port: 0, dstPort: 8472,
|
||
serverId: "srv2", vtepIp: "10.0.1.1", remoteVteps: ["10.0.0.1","10.0.2.1"],
|
||
l2mtu: 1500, arpProxy: true, macLearning: true,
|
||
comment: "SPB overlay — сегмент bypass", enabled: true, status: "up",
|
||
},
|
||
{
|
||
id: "vx3", name: "vxlan-overlay-fra", vni: 10010, port: 0, dstPort: 8472,
|
||
serverId: "srv3", vtepIp: "10.0.2.1", remoteVteps: ["10.0.0.1","10.0.1.1"],
|
||
l2mtu: 1500, arpProxy: true, macLearning: false,
|
||
comment: "FRA overlay — сегмент bypass", enabled: true, status: "up",
|
||
},
|
||
{
|
||
id: "vx4", name: "vxlan-mgmt-lab", vni: 20001, port: 0, dstPort: 4789,
|
||
serverId: "srv7", vtepIp: "10.0.0.7", remoteVteps: ["10.0.0.1"],
|
||
l2mtu: 1500, arpProxy: false, macLearning: true,
|
||
comment: "Lab management VXLAN", enabled: true, status: "up",
|
||
},
|
||
{
|
||
id: "vx5", name: "vxlan-overlay-ams", vni: 10010, port: 0, dstPort: 8472,
|
||
serverId: "srv4", vtepIp: "10.0.3.1", remoteVteps: ["10.0.0.1"],
|
||
l2mtu: 1500, arpProxy: true, macLearning: true,
|
||
comment: "AMS overlay (degraded)", enabled: true, status: "down",
|
||
},
|
||
]
|
||
|
||
// ─── Container mock data ─────────────────────────────────────────────────────
|
||
|
||
export const routerContainers: RouterContainer[] = [
|
||
{
|
||
id: "c1", name: "adguard-msk", serverId: "srv1",
|
||
image: "adguard/adguardhome", tag: "latest",
|
||
status: "running",
|
||
envs: [{ key: "AGH_CONFIG", value: "/opt/adguardhome/conf/AdGuardHome.yaml" }],
|
||
mounts: [{ dst: "/opt/adguardhome/conf", src: "/disk1/adguard" }, { dst: "/opt/adguardhome/work", src: "/disk1/adguard-work" }],
|
||
interfaces: ["veth-adguard"],
|
||
startOnBoot: true, comment: "AdGuard Home — DNS фильтрация",
|
||
uptime: "12д 4ч", cpu: 3, memMb: 64,
|
||
},
|
||
{
|
||
id: "c2", name: "prometheus-msk", serverId: "srv1",
|
||
image: "prom/prometheus", tag: "v2.52.0",
|
||
status: "running",
|
||
envs: [],
|
||
mounts: [{ dst: "/prometheus", src: "/disk1/prom-data" }],
|
||
interfaces: ["veth-prom"],
|
||
cmd: "--config.file=/etc/prometheus/prometheus.yml --storage.tsdb.retention.time=30d",
|
||
startOnBoot: true, comment: "Prometheus метрики",
|
||
uptime: "5д 11ч", cpu: 8, memMb: 256,
|
||
},
|
||
{
|
||
id: "c3", name: "grafana-msk", serverId: "srv1",
|
||
image: "grafana/grafana", tag: "10.4.2",
|
||
status: "running",
|
||
envs: [{ key: "GF_SECURITY_ADMIN_PASSWORD", value: "*** (hidden)" }],
|
||
mounts: [{ dst: "/var/lib/grafana", src: "/disk1/grafana" }],
|
||
interfaces: ["veth-grafana"],
|
||
startOnBoot: true, comment: "Grafana — дашборды мониторинга",
|
||
uptime: "5д 11ч", cpu: 5, memMb: 128,
|
||
},
|
||
{
|
||
id: "c4", name: "wg-portal-spb", serverId: "srv2",
|
||
image: "wgportal/wg-portal", tag: "v1.3.1",
|
||
status: "running",
|
||
envs: [{ key: "WG_PORTAL_ADMIN_USER", value: "admin" }],
|
||
mounts: [{ dst: "/app/data", src: "/disk1/wgportal" }],
|
||
interfaces: ["veth-wgportal"],
|
||
startOnBoot: true, comment: "WireGuard Portal — управление клиентами",
|
||
uptime: "3д 7ч", cpu: 1, memMb: 48,
|
||
},
|
||
{
|
||
id: "c5", name: "unbound-fra", serverId: "srv3",
|
||
image: "mvance/unbound", tag: "1.19.3",
|
||
status: "stopped",
|
||
envs: [],
|
||
mounts: [],
|
||
interfaces: ["veth-unbound"],
|
||
startOnBoot: false, comment: "Unbound DNS резолвер (в резерве)",
|
||
cpu: 0, memMb: 0,
|
||
},
|
||
]
|
||
|
||
// ─── Certificate mock data ────────────────────────────────────────────────────
|
||
|
||
export const routerCertificates: RouterCertificate[] = [
|
||
{
|
||
id: "cert1", name: "mt-msk-core-01-server", serverId: "srv1",
|
||
commonName: "mt-msk-core-01.routerlists.io",
|
||
sans: ["mt-msk-core-01.routerlists.io","10.0.0.1"],
|
||
issuedBy: "RouterLists Internal CA", validFrom: "2024-01-15",
|
||
validUntil: "2026-01-15", daysLeft: 261,
|
||
keySize: 4096, usage: ["server"], trusted: true, status: "valid",
|
||
},
|
||
{
|
||
id: "cert2", name: "routerlists-internal-ca", serverId: "srv1",
|
||
commonName: "RouterLists Internal CA",
|
||
sans: [],
|
||
issuedBy: "RouterLists Internal CA (self-signed)", validFrom: "2023-06-01",
|
||
validUntil: "2033-06-01", daysLeft: 2589,
|
||
keySize: 4096, usage: ["ca","crl-sign"], trusted: true, status: "valid",
|
||
},
|
||
{
|
||
id: "cert3", name: "mt-spb-edge-01-server", serverId: "srv2",
|
||
commonName: "mt-spb-edge-01.routerlists.io",
|
||
sans: ["mt-spb-edge-01.routerlists.io","10.0.1.1"],
|
||
issuedBy: "RouterLists Internal CA", validFrom: "2024-01-15",
|
||
validUntil: "2026-01-15", daysLeft: 261,
|
||
keySize: 4096, usage: ["server"], trusted: true, status: "valid",
|
||
},
|
||
{
|
||
id: "cert4", name: "mt-fra-edge-01-server", serverId: "srv3",
|
||
commonName: "mt-fra-edge-01.routerlists.io",
|
||
sans: ["mt-fra-edge-01.routerlists.io","10.0.2.1"],
|
||
issuedBy: "Let's Encrypt", validFrom: "2026-01-10",
|
||
validUntil: "2026-04-10", daysLeft: -19,
|
||
keySize: 2048, usage: ["server"], trusted: true, status: "expired",
|
||
},
|
||
{
|
||
id: "cert5", name: "wg-client-admin", serverId: "srv1",
|
||
commonName: "admin.routerlists.io",
|
||
sans: ["admin.routerlists.io"],
|
||
issuedBy: "RouterLists Internal CA", validFrom: "2025-06-01",
|
||
validUntil: "2026-06-01", daysLeft: 33,
|
||
keySize: 2048, usage: ["client"], trusted: true, status: "valid",
|
||
},
|
||
{
|
||
id: "cert6", name: "mt-ams-edge-01-server", serverId: "srv4",
|
||
commonName: "mt-ams-edge-01.routerlists.io",
|
||
sans: ["mt-ams-edge-01.routerlists.io"],
|
||
issuedBy: "RouterLists Internal CA", validFrom: "2024-04-01",
|
||
validUntil: "2026-05-15", daysLeft: 16,
|
||
keySize: 2048, usage: ["server"], trusted: false, status: "valid",
|
||
},
|
||
{
|
||
id: "cert7", name: "mt-msk-lab-01-server", serverId: "srv7",
|
||
commonName: "mt-msk-lab-01.routerlists.io",
|
||
sans: ["mt-msk-lab-01.routerlists.io","10.0.0.7"],
|
||
issuedBy: "RouterLists Internal CA", validFrom: "2025-09-01",
|
||
validUntil: "2026-09-01", daysLeft: 125,
|
||
keySize: 4096, usage: ["server"], trusted: true, status: "valid",
|
||
},
|
||
]
|