mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-06-01 13:04:42 +00:00
5ca3463bf6
Full rewrite of the docs site under app/[locale]/ with next-intl in localePrefix:"always" mode. Every page now exists at both /en/<path> and /es/<path>; the root / shows a meta-refresh + JS redirect to /<defaultLocale>/ so GitHub Pages serves something on the apex URL. Highlights: - 107 doc pages migrated to file-per-page JSON namespaces under messages/en/ and messages/es/. Spanish content is fully translated (no copy-of-English placeholders). - New documentation for the Active Suppressions section in the Settings tab and the per-event Dismiss dropdown in the Health Monitor modal. - New screenshots: dismiss-duration-dropdown.png and an updated health-suppression-settings.png. - Pagefind integrated for client-side search; index is built on every CI deploy (not committed). - RSS feeds: per-locale at /<locale>/rss.xml plus root /rss.xml for backward compat. - Removed the dead app/[locale]/guides/[slug]/ route — every guide now has its own static page and no markdown source remains. - Fixed orphan link /guides/nvidia -> /guides/nvidia-manual in docs/hardware/nvidia-host. - Removed obsolete components (footer2, calendar, drawer). Verified locally with `npm ci && npm run build`: 2804 files in out/, 231 pages indexed by pagefind, root redirect intact, both locale roots and the new Active Suppressions docs render OK.
153 lines
12 KiB
JSON
153 lines
12 KiB
JSON
{
|
|
"meta": {
|
|
"title": "Fail2Ban | ProxMenux Documentation",
|
|
"description": "Install Fail2Ban with three jails tuned for Proxmox (SSH aggressive, Proxmox UI 8006, ProxMenux Monitor 8008). Includes the journald MaxLevelStore fix, custom log services for reliability, auto-detected nftables/iptables backend and SSH MaxAuthTries hardening.",
|
|
"ogTitle": "Fail2Ban | ProxMenux Documentation",
|
|
"ogDescription": "Brute-force protection for SSH and Proxmox web UIs, with Proxmox-specific journald and backend fixes."
|
|
},
|
|
"header": {
|
|
"title": "Fail2Ban",
|
|
"description": "Installs Fail2Ban with a Proxmox-specific configuration: three jails (SSH aggressive, Proxmox UI on port 8006, ProxMenux Monitor on port 8008 + reverse proxy), a journald log-level fix so SSH auth events are actually stored, two journal-to-file logger services that work around a known Fail2Ban systemd-backend issue, auto-detected firewall backend and SSH MaxAuthTries hardening.",
|
|
"section": "Security"
|
|
},
|
|
"intro": {
|
|
"title": "What this does",
|
|
"body": "Installs Fail2Ban from the Debian repos and writes a complete Proxmox-tuned configuration that protects three attack surfaces (SSH, Proxmox UI, ProxMenux Monitor) out of the box. Detects an existing install and offers a manage menu (reinstall / remove) instead of re-running the installer."
|
|
},
|
|
"firstLaunch": {
|
|
"heading": "First-launch dialog",
|
|
"body": "On a host without Fail2Ban, the script shows a confirmation dialog summarising everything it's about to install and configure. Cancel exits without changes; confirm starts the install flow.",
|
|
"imageAlt": "Fail2Ban install confirmation dialog listing the three jails, journald fix and SSH hardening"
|
|
},
|
|
"jails": {
|
|
"heading": "The three jails",
|
|
"headerJail": "Jail",
|
|
"headerProtects": "Protects",
|
|
"headerRetries": "Retries / Window",
|
|
"headerBan": "Ban time",
|
|
"rows": [
|
|
{
|
|
"jail": "[sshd]",
|
|
"protects": "SSH (aggressive mode — covers ddos, mode, normal)",
|
|
"retries": "2 / 60 min",
|
|
"ban": "9 hours"
|
|
},
|
|
{
|
|
"jail": "[proxmox]",
|
|
"protects": "Proxmox web UI (port 8006)",
|
|
"retries": "3 / 10 min",
|
|
"ban": "1 hour"
|
|
},
|
|
{
|
|
"jail": "[proxmenux]",
|
|
"protects": "ProxMenux Monitor (port 8008 + http/https reverse proxy)",
|
|
"retries": "3 / 10 min",
|
|
"ban": "1 hour"
|
|
}
|
|
],
|
|
"outro": "Global defaults from <code>jail.local</code>: <code>ignoreip = 127.0.0.1/8 ::1</code>, <code>ignoreself = true</code>,<code> bantime = 86400</code> (24h fallback for jails that don't override it), <code>maxretry = 2</code>, <code>findtime = 1800</code>."
|
|
},
|
|
"journald": {
|
|
"heading": "Why the journald fix matters",
|
|
"intro": "Proxmox ships <code>/etc/systemd/journald.conf</code> with <codeNw>MaxLevelStore=warning</codeNw>. journald drops every log message <em>below</em> warning before storing it. SSH and PAM emit auth failures at <em>info</em> / <em>notice</em> levels, so:",
|
|
"diagram": {
|
|
"sshLabel": "SSH / PAM",
|
|
"sshDetail": "auth failure\n(info / notice level)",
|
|
"journaldLabel": "journald",
|
|
"journaldDetail": "MaxLevelStore=warning\n→ event silently dropped",
|
|
"fail2banLabel": "Fail2Ban",
|
|
"fail2banDetail": "sees nothing\n→ never bans anything",
|
|
"arrowLabel": "default Proxmox"
|
|
},
|
|
"afterDiagram": "The installer detects this and writes a drop-in at <codeXs>/etc/systemd/journald.conf.d/proxmenux-loglevel.conf</codeXs> raising both <code>MaxLevelStore</code> and <code>MaxLevelSyslog</code> to <code>info</code>:",
|
|
"code": "[Journal]\nMaxLevelStore=info\nMaxLevelSyslog=info",
|
|
"outro": "Then restarts <code>systemd-journald</code>. The drop-in is removed on uninstall, restoring the original Proxmox default."
|
|
},
|
|
"loggers": {
|
|
"heading": "Why two custom logger services",
|
|
"intro1": "Fail2Ban can read directly from the systemd journal (<code>backend = systemd</code>), but on Proxmox this backend has known reliability issues with <code>pvedaemon</code> worker processes (auth events appear in the journal but Fail2Ban doesn't always pick them up) and intermittently with <code>sshd</code>.",
|
|
"intro2": "The workaround: ProxMenux creates two tiny systemd services that <code>journalctl -f</code> the relevant units and append every line to a file. Fail2Ban then reads those files with the rock-solid <code>backend = auto</code> (file mode):",
|
|
"headerService": "Service",
|
|
"headerSource": "Source unit",
|
|
"headerOutput": "Output file",
|
|
"rows": [
|
|
{
|
|
"service": "proxmox-auth-logger.service",
|
|
"source": "pvedaemon.service",
|
|
"output": "/var/log/proxmox-auth.log"
|
|
},
|
|
{
|
|
"service": "ssh-auth-logger.service",
|
|
"source": "ssh.service",
|
|
"output": "/var/log/ssh-auth.log"
|
|
}
|
|
],
|
|
"outro": "Both services are declared <code>PartOf=fail2ban.service</code> so they restart with Fail2Ban and stop with it. Mode 640 owned by <code>root:adm</code> on the log files. The third log used by the <code>[proxmenux]</code> jail (<code>/var/log/proxmenux-auth.log</code>) is written directly by the ProxMenux Monitor Flask app — no logger service needed for that one."
|
|
},
|
|
"backend": {
|
|
"heading": "Firewall backend auto-detection",
|
|
"intro": "The installer probes the host: if <code>nft list ruleset</code> works, it picks <code>nftables</code> as the ban action. Otherwise it falls back to <code>iptables-multiport</code> / <code>iptables-allports</code>. The choice is written into <code>jail.local</code>:",
|
|
"code": "# nftables host\nbanaction = nftables\nbanaction_allports = nftables[type=allports]\n\n# iptables host (fallback)\nbanaction = iptables-multiport\nbanaction_allports = iptables-allports"
|
|
},
|
|
"hardening": {
|
|
"heading": "SSH hardening: MaxAuthTries",
|
|
"intro": "Lynis control <strong>SSH-7408</strong> recommends <code>MaxAuthTries 3</code> in <code>sshd_config</code>. With Fail2Ban's <code>maxretry = 2</code> on the SSH jail, a malicious client never reaches three attempts anyway — but the explicit setting satisfies the audit and adds defence in depth (e.g. if Fail2Ban is stopped for maintenance).",
|
|
"installerIntro": "The installer:",
|
|
"items": [
|
|
"Reads the current <code>MaxAuthTries</code> value (or defaults to 6 if absent).",
|
|
"Saves it to <code>/usr/local/share/proxmenux/sshd_maxauthtries_backup</code>.",
|
|
"Edits <code>sshd_config</code> in-place — replaces existing line, uncomments commented line, or appends.",
|
|
"Reloads <code>sshd</code> (reload, not restart, to keep existing sessions alive)."
|
|
],
|
|
"outro": "On uninstall, the saved original value is restored and <code>sshd</code> is reloaded again."
|
|
},
|
|
"manage": {
|
|
"heading": "Manage an existing install",
|
|
"intro": "If Fail2Ban is already installed when you open the menu, the script detects it and shows a manage menu instead of re-running the installer:",
|
|
"headerAction": "Action",
|
|
"headerWhat": "What it does",
|
|
"rows": [
|
|
{
|
|
"action": "Reinstall",
|
|
"what": "Re-runs the full installer — rewrites all jails with the current ProxMenux defaults. Use this after a ProxMenux update bumps the recommended values."
|
|
},
|
|
{
|
|
"action": "Remove",
|
|
"what": "Stops fail2ban and the two logger services, purges the apt package, removes all jail / filter files, deletes the journald drop-in (restoring the Proxmox default), and restores the original SSH MaxAuthTries."
|
|
}
|
|
]
|
|
},
|
|
"verify": {
|
|
"heading": "Verify it's working",
|
|
"intro": "After installation, useful commands from the host:",
|
|
"code": "# Service status and version\nsystemctl status fail2ban\nfail2ban-client --version\n\n# All active jails\nfail2ban-client status\n\n# Detail on one jail\nfail2ban-client status sshd\nfail2ban-client status proxmox\nfail2ban-client status proxmenux\n\n# Currently banned IPs in a jail\nfail2ban-client status sshd | grep \"Banned IP\"\n\n# Manually unban an IP (use this if you ban yourself)\nfail2ban-client unban 192.0.2.10\n\n# Tail the auth logs Fail2Ban watches\ntail -f /var/log/ssh-auth.log\ntail -f /var/log/proxmox-auth.log\ntail -f /var/log/fail2ban.log"
|
|
},
|
|
"troubleshoot": {
|
|
"heading": "Troubleshooting",
|
|
"neverBansTitle": "Fail2Ban runs but never bans anything",
|
|
"neverBansBody": "Check the auth log files actually receive entries: <code>tail -f /var/log/ssh-auth.log</code> and try a wrong-password SSH attempt from a different machine. If the log stays empty, the logger service is not running: <code>systemctl status ssh-auth-logger.service</code>. If it's active but the log is empty, check that the journald drop-in took effect: <code>journalctl --dump-catalog | head</code> — events at <em>info</em> level should be visible.",
|
|
"monitorEmptyTitle": "ProxMenux Monitor jail has no entries even after failed logins",
|
|
"monitorEmptyBody": "The <code>[proxmenux]</code> jail reads <code>/var/log/proxmenux-auth.log</code>, which is written by the ProxMenux Monitor Flask app — not by a journald logger. If you don't run the Monitor, the file stays empty and the jail never fires. That's expected; the jail config is harmless. If you do run the Monitor and the log is empty, check the Flask logging config.",
|
|
"selfBanTitle": "I banned myself",
|
|
"selfBanIntro": "From a console / IPMI / iKVM (or another whitelisted IP):",
|
|
"selfBanCode": "fail2ban-client unban '<'YOUR_IP'>'\n\n# To prevent it next time, edit /etc/fail2ban/jail.local and add your IP:\nignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 203.0.113.42\n\n# Then reload\nfail2ban-client reload",
|
|
"aptFailTitle": "apt-get fails: ''Unable to locate package fail2ban''",
|
|
"aptFailBody": "The host is missing the Debian repos (common on barebones Proxmox installs). The installer detects this and writes <code>/etc/apt/sources.list.d/debian.sources</code> with the right codename (<code>bookworm</code> / <code>trixie</code>) before retrying. If it still fails, check <code>/etc/os-release</code> for <code>VERSION_CODENAME</code> and confirm the repo URL is reachable.",
|
|
"lockoutTitle": "SSH locks me out after install",
|
|
"lockoutBody": "The installer sets <code>MaxAuthTries=3</code>. If your password manager / agent retries multiple keys, you may exceed that on a single connection attempt. Limit the keys offered: <code>ssh -o IdentitiesOnly=yes -i ~/.ssh/specific_key user@host</code>. Or temporarily raise <code>MaxAuthTries</code> in <code>sshd_config</code> while you debug."
|
|
},
|
|
"files": {
|
|
"heading": "Files written",
|
|
"code": "/etc/fail2ban/jail.local # global defaults + [sshd]\n/etc/fail2ban/jail.d/proxmox.conf # [proxmox]\n/etc/fail2ban/jail.d/proxmenux.conf # [proxmenux]\n/etc/fail2ban/filter.d/proxmox.conf # auth-failure regex for pvedaemon\n/etc/fail2ban/filter.d/proxmenux.conf # auth-failure regex for Monitor\n/etc/systemd/system/proxmox-auth-logger.service # journal → file (pvedaemon)\n/etc/systemd/system/ssh-auth-logger.service # journal → file (sshd)\n/etc/systemd/journald.conf.d/proxmenux-loglevel.conf # MaxLevelStore=info\n/etc/ssh/sshd_config # MaxAuthTries=3 (in-place edit)\n/var/log/proxmox-auth.log # written by logger service\n/var/log/ssh-auth.log # written by logger service\n/var/log/proxmenux-auth.log # written by Monitor Flask app\n/usr/local/share/proxmenux/sshd_maxauthtries_backup # for restore on uninstall"
|
|
},
|
|
"related": {
|
|
"heading": "Related",
|
|
"monitorLabel": "ProxMenux Monitor → Security tab",
|
|
"monitorTail": " — same install reachable from the dashboard, plus live jail status, banned IPs and per-jail retry / ban-time tuning from the browser.",
|
|
"lynisLabel": "Lynis",
|
|
"lynisTail": " — run a security audit before/after to confirm the SSH-7408 control is satisfied.",
|
|
"securityLabel": "Security overview",
|
|
"securityTail": " — back to the section overview."
|
|
}
|
|
}
|