"use client" import { useMemo, useState } from "react" import { PageHeader } from "@/components/page-header" import { servers } from "@/lib/data" import type { WireGuardInterface } from "@/lib/data" import { DataPageCard } from "@/components/data-page-card" import { DataPageToolbar } from "@/components/data-page-toolbar" import { WireguardDataGrid, type WgIfaceWithServer, } from "@/components/data-grids/wireguard-data-grid" import { Button } from "@/components/ui/button" import { Card, CardContent } from "@/components/ui/card" import { cn } from "@/lib/utils" import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetFooter, SheetClose, } from "@/components/ui/sheet" import { ShieldCheckIcon, PlusIcon, KeyRoundIcon, CodeXmlIcon, UsersIcon, ActivityIcon, CopyIcon, CheckIcon, } from "lucide-react" // ─── collect all WireGuard interfaces from all servers ──────────────────────── function collectInterfaces(): WgIfaceWithServer[] { const result: WgIfaceWithServer[] = [] for (const srv of servers) { for (const wg of srv.wireGuardIfaces ?? []) { result.push({ ...wg, serverId: srv.id, serverName: srv.name, serverCountry: srv.country, }) } } return result } // ─── helpers ────────────────────────────────────────────────────────────────── // ─── RSC generator ──────────────────────────────────────────────────────────── function generateWgRsc(iface: WgIfaceWithServer): string { const lines: string[] = [] lines.push(`# WireGuard — ${iface.name} · ${iface.serverName}`) lines.push(`# RouterOS 7.x`) lines.push(``) lines.push(`/interface wireguard add \\`) lines.push(` name=${iface.name} \\`) lines.push(` listen-port=${iface.listenPort} \\`) lines.push(` mtu=${iface.mtu} \\`) if (iface.comment) lines.push(` comment="${iface.comment}" \\`) if (!iface.enabled) lines.push(` disabled=yes \\`) lines.push(``) for (const p of iface.peers) { lines.push(`/interface wireguard peers add \\`) lines.push(` interface=${iface.name} \\`) lines.push(` public-key="${p.publicKey}" \\`) lines.push(` allowed-address=${p.allowedIps.join(",")} \\`) if (p.endpoint) lines.push(` endpoint-address=${p.endpoint.split(":")[0]} \\`) if (p.endpoint) lines.push(` endpoint-port=${p.endpoint.split(":")[1] ?? "13231"} \\`) if (p.persistent) lines.push(` persistent-keepalive=25 \\`) if (p.comment) lines.push(` comment="${p.comment}" \\`) lines.push(``) } return lines.join("\n") } // ─── Export Sheet ───────────────────────────────────────────────────────────── function ExportSheet({ open, iface, onClose }: { open: boolean; iface: WgIfaceWithServer | null; onClose: () => void }) { const [copied, setCopied] = useState(false) const code = useMemo(() => iface ? generateWgRsc(iface) : "", [iface]) function handleCopy() { navigator.clipboard.writeText(code).then(() => { setCopied(true); setTimeout(() => setCopied(false), 2000) }) } return ( { if (!v) onClose() }}>
Экспорт WireGuard RouterOS 7.x · /interface wireguard + peers
            {code.split("\n").map((line, i) => {
              const isComment = line.startsWith("#")
              const isCmd = line.trimStart().startsWith("/interface")
              const isParam = /^\s+[a-z]/.test(line)
              return (
                
                  {line}{"\n"}
                
              )
            })}
          
}>Закрыть
) } // ════════════════════════════════════════════════════════════════════════════ export default function WireGuardPage() { const allIfaces = useMemo(() => collectInterfaces(), []) const [search, setSearch] = useState("") const [exportIface, setExportIface] = useState(null) const filtered = useMemo(() => { if (!search) return allIfaces const q = search.toLowerCase() return allIfaces.filter((i) => i.name.includes(q) || i.serverName.toLowerCase().includes(q) || i.peers.some((p) => p.allowedIps.some((a) => a.includes(q)) || (p.endpoint ?? "").includes(q)) ) }, [allIfaces, search]) const totalPeers = allIfaces.reduce((s, i) => s + i.peers.length, 0) const onlinePeers = allIfaces.reduce((s, i) => s + i.peers.filter((p) => !!p.latestHandshake).length, 0) const upIfaces = allIfaces.filter((i) => i.status === "up").length return (
} />
{/* KPI */}
{[ { label: "Интерфейсов", value: allIfaces.length, icon: }, { label: "Активных (UP)", value: upIfaces, icon: }, { label: "Всего пиров", value: totalPeers, icon: }, { label: "Пиров онлайн", value: `${onlinePeers}/${totalPeers}`, icon: }, ].map((s) => (

{s.label}

{s.value}

{s.icon}
))}
{/* Info banner */}

WireGuard — рекомендуемый туннельный протокол в RouterOS 7.x

Доступен с RouterOS 7.1+. Более высокая производительность и безопасность по сравнению с GRE+IPsec. Ключи генерируются командой /interface/wireguard/print.

{/* Search + table */} {/* RouterOS reference */}

RouterOS 7 · /interface wireguard — быстрые команды

{[ { title: "Создать интерфейс", lines: [ "/interface wireguard add \\", " name=wg0 \\", " listen-port=13231 \\", " mtu=1420", ], }, { title: "Добавить пира", lines: [ "/interface wireguard peers add \\", " interface=wg0 \\", ' public-key="<ключ>" \\', " allowed-address=10.0.0.2/32 \\", " endpoint-address=1.2.3.4 \\", " persistent-keepalive=25", ], }, { title: "Назначить IP", lines: [ "/ip address add \\", " address=10.210.0.1/30 \\", " interface=wg0", "", "# Статус:", "/interface wireguard print", ], }, ].map((b) => (

{b.title}

                      {b.lines.join("\n")}
                    
))}
setExportIface(null)} />
) }