import type { Metadata } from "next" import { getTranslations, getMessages, setRequestLocale } from "next-intl/server" import { Link } from "@/i18n/navigation" import Image from "next/image" import { ArrowRight, Ban, ShieldCheck, ScanLine } from "lucide-react" import { DocHeader } from "@/components/ui/doc-header" import { Callout } from "@/components/ui/callout" export async function generateMetadata({ params, }: { params: Promise<{ locale: string }> }): Promise { const { locale } = await params const t = await getTranslations({ locale, namespace: "docs.security.meta" }) return { title: t("title"), description: t("description"), keywords: [ "proxmox fail2ban", "proxmox lynis", "proxmox security", "proxmox hardening", "proxmox intrusion prevention", "proxmox security audit", "proxmox ssh fail2ban", "proxmox web ui fail2ban", ], alternates: { canonical: "https://proxmenux.com/docs/security" }, openGraph: { title: t("ogTitle"), description: t("ogDescription"), type: "article", url: "https://proxmenux.com/docs/security", }, twitter: { card: "summary", title: t("twitterTitle"), description: t("twitterDescription"), }, } } type StringItem = string interface OptionProps { title: string description: string Icon: React.ComponentType<{ className?: string; "aria-hidden"?: boolean }> href: string } function OptionCard({ title, description, Icon, href }: OptionProps) { return (
{title}
{description}
) } export default async function SecurityOverviewPage({ params, }: { params: Promise<{ locale: string }> }) { const { locale } = await params setRequestLocale(locale) const t = await getTranslations({ locale, namespace: "docs.security" }) const messages = (await getMessages({ locale })) as unknown as { docs: { security: { cards: { fail2ban: { bullets: StringItem[] } lynis: { bullets: StringItem[] } } } } } const fail2banBullets = messages.docs.security.cards.fail2ban.bullets const lynisBullets = messages.docs.security.cards.lynis.bullets const code = (chunks: React.ReactNode) => {chunks} const strong = (chunks: React.ReactNode) => {chunks} const em = (chunks: React.ReactNode) => {chunks} return (
{t.rich("intro.body", { strong, em })}

{t("opening.heading")}

{t.rich("opening.body", { strong })}

{t("opening.imageAlt")}

{t("pick.heading")}

{t("pick.body")}

{t("cards.fail2ban.title")}

{t("cards.fail2ban.body")}

    {fail2banBullets.map((_, idx) => (
  • {t(`cards.fail2ban.bullets.${idx}`)}
  • ))}

{t("cards.lynis.title")}

{t("cards.lynis.body")}

    {lynisBullets.map((_, idx) => (
  • {t(`cards.lynis.bullets.${idx}`)}
  • ))}
{t.rich("workflowTip.body", { code })}

{t("fail2banSection.heading")}

{t("fail2banSection.body")}

{t("lynisSection.heading")}

{t.rich("lynisSection.body", { code })}

{t("componentStatus.heading")}

{t.rich("componentStatus.body", { code })}

) }