# Changelog All notable changes to Roster are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow [Semantic Versioning](https://semver.org/). German version: [CHANGELOG.de.md](https://github.com/boonkerz/roster/blob/master/CHANGELOG.de.md). ## [Unreleased] ## [0.28.0] - 2026-11-11 ### Added - Native viewer and tray app show their version: the viewer in the window title ("· Viewer 0.28.0"), the tray in the footer; both say "Update … available" when the server is newer (the tray in red). `--version` prints it. ### Fixed - **Settings → Downloads served outdated viewer and tray packages** (from September/October): a server built with `make server` didn't rebuild them. `make server` now embeds viewer and tray (Linux x86-64/ARM64, Windows) in the server's own version – so file transfers over 32 MB and progress now also reach the native viewer. ## [0.27.0] - 2026-11-11 ### Changed - File transfer (file browser, drag & drop onto the remote desktop, native viewer's file manager): **up to 4 GB instead of 32 MB**. Files are streamed – the server keeps them as a temporary file next to its database instead of in RAM (checks free disk space first) and deletes them right after pick-up; the agent writes into a temporary file and renames it only when complete, so an aborted transfer never leaves a half file; transfers run in the background so the agent keeps checking in. The web UI shows upload percentage and the device-side progress; waiting no longer gives up after one minute while the agent reports progress. Large uploads to agents older than 0.27.0 are refused with a clear message (they could only take 32 MB). ## [0.26.0] - 2026-11-10 ### Added - Remote desktop on Linux: **clipboard sync** in both directions – X11 via the CLIPBOARD selection, Wayland via the data-control protocol (labwc/Raspberry Pi OS, Sway, Wayfire, niri, Hyprland). ## [0.25.0] - 2026-11-10 ### Added - Remote desktop on **Linux**: real screen, mouse and keyboard instead of the colour-gradient test image – Wayland with wlroots (labwc on Raspberry Pi OS, Wayfire, Sway, niri, Hyprland) via `wlr-screencopy` and virtual pointer/keyboard, and X11 via the X server with XTEST. The agent finds the logged-in user's session on its own; nothing to install. GNOME/KDE on Wayland and other systems show a clear notice instead of the test image; without a session the viewer waits for a login. ## [0.24.1] - 2026-11-09 ### Fixed - Flows: deleting runs/flows and starting test runs/rollouts no longer rely on the browser's confirm dialog – browsers silently answer "Cancel" once "prevent additional dialogs" was ticked, so the delete button seemed to do nothing (unless DevTools were open). The button now asks itself ("Sure? Click again"). ### Added - Flow editor: save feedback – "✓ Saved at …" after saving and "● Unsaved changes" while editing. ## [0.24.0] - 2026-11-09 ### Fixed - Flows: the *Roll back* block with "restart services" now brings up the **whole Compose project** – previously only the services found by *Find files* (e.g. php-fpm) went back, while web/cron kept running on the new image. ### Added - Flows: five new blocks – **Filesystem** (`mkdir`/`chmod`/`chown`/`file`, idempotent, rollback removes newly created directories/files and restores permissions/owner), **Command in container** (`docker exec` in a Compose service, e.g. cache clear/migrations), **Back up database** (MySQL/MariaDB, MongoDB, PostgreSQL dump with credentials from the container environment, gzip, keeps the newest N, kept on rollback), **Clean up Docker** (dangling or unused images, preview lists them) and **Notify** (sent by the server via the alert channels, also during maintenance windows). Every block gets an optional **"Only run if …"** condition (empty value = skip, `!` = only if empty). *Check* can test whether a **path exists**. The preview remembers paths a previous line would create. Template *Compose: raise version if older* extended: optional DB backup, volume directory with bind volume, post-update command, cleanup, success/failure messages. ## [0.23.3] - 2026-11-09 ### Fixed - Flows, *Find files* (Compose image): the image **name is enough** (`php-fpm-prod` finds `registry…/docker/php-fpm-prod`), `*` works as a wildcard. Previously only the full repository matched. Version comparison ignores **variant suffixes** like `_tp` (`2.4.0_tp` counts as 2.4.0 – previously not comparable, so such hosts were skipped as "not affected"). New placeholder `{{value.suffix}}`; the template *Compose: raise version if older* keeps the suffix (`2.4.0_tp` → `2.5.0_tp`). ## [0.23.2] - 2026-11-09 ### Changed - Flows, *Edit YAML*: a short-form value (`{driver: local, driver_opts: {…}}`, `[a, b]`) is written as an indented block when the key is created – a named volume with driver options now fits on one `ensure` line. `{}`/`[]` stay as they are. ## [0.23.1] - 2026-11-09 ### Added - Flows: **try out YAML edits** – *Try it out …* on the *Edit YAML* block opens a three-column window (input YAML + parameter values | operations, applied to the block | live preview as diff or result, with a message per operation). The server computes it with the same code as the agent (`POST /flows/yaml-preview`); nothing is saved or executed. YAML logic and diff moved to shared packages (`internal/shared/yamledit`, `textdiff`). ## [0.23.0] - 2026-11-09 ### Added - Flows: new blocks **Read value** (YAML/JSON path or `.env` key, extract image tag/repository → `{{steps.ID.value}}`) and **Edit YAML** (`set`/`append`/`ensure`/`delete` with brace expansion `{web,php-fpm,cron}` and `{{value.repo}}`; edits are applied at the exact position, so comments, quotes and indentation stay; result re-parsed before writing, backup/diff/preview, idempotent). *Check* compares **versions** (`version_lt` … `version_eq`) and can **end the flow without error** when not met ("otherwise do nothing"). Template **Compose: raise version if older** (read php-fpm tag, < 2.5.0 → raise web/php-fpm/cron, add mount + volume, pull, up, check, roll back on failure). JSON Schema extended (format version stays 1). ## [0.22.0] - 2026-11-09 ### Added - Flows: **exchange format `roster-flow` (version 1)** – export a flow as `.roster-flow.json` (list and editor) and import it on another server (upload or paste, *Check* validates without changes; same-name flows stay untouched, the import becomes "Name (Import)"). Library scripts are embedded on export. Published **JSON Schema** `https://roster-rmm.dev/schemas/roster-flow-1.schema.json` for editor validation/completion. API `GET /flows/{id}/export`, `POST /flows/import` (`?dry_run=1`). ## [0.21.6] - 2026-11-07 ### Added - Container security: number of **fixable** findings per image (Docker tab and *Security → Containers*), filter "fixable only", header badge "with fixable critical/high", sort order fixable critical/high first. Debian's own urgency (unimportant/low/medium/high) replaces the generic CVSS level where set. ### Fixed - Container security: "Fixed in" is taken only from the image's own release (e.g. Debian 13). Previously it could show a version from another release (Debian 14 `8.21.0~rc2-1` for curl in trixie), suggesting a new image would fix it. Unfixed findings now show "no fix yet". Container scans no longer reuse fix data from host scans. Migration 0079 re-matches all images once. ## [0.21.5] - 2026-11-07 ### Fixed - Container security: image scans and their vulnerabilities are removed on every check-in as soon as no container (running or stopped) uses the image anymore – e.g. the old `jrcs/letsencrypt-nginx-proxy-companion` after switching, which still exists locally until `docker image prune`. Previously they stayed under *Security → Containers* until the image itself was deleted; hosts without any containers/images now drop all scans and database inventories too. ## [0.21.4] - 2026-11-07 ### Fixed - Flows: opening a stored run from the run history now shows that run's parameters and preview server instead of the flow's defaults. ## [0.21.3] - 2026-11-07 ### Changed - Flows: *Find files* never matches the flow's own backups (`*.roster-bak-*`, `*.roster-tmp`) – previously a pattern like `dir/*` picked them up on a second run. *Replace text* without any match now **ends the flow without error** (status "not affected": device already switched), so pull/up/restart are skipped; option "Continue even if nothing was replaced" keeps the old behaviour. ## [0.21.2] - 2026-11-07 ### Added - Flows: **copy** a flow (list and editor, "Name (copy)"; in the editor the current, unsaved state is copied) and **delete single runs** from the run history. Route `POST /flows/{id}/copy`, `DELETE /flow-runs/{id}`. ## [0.21.1] - 2026-11-07 ### Fixed - Flows: the *Docker Compose* block now also works after *Find files* in path mode – compose files among the matches (docker-compose*.yml, compose*.yaml) become the project (name from the labels of running containers in that directory, otherwise the directory name). Previously the preview failed with "no Compose project known". ## [0.21.0] - 2026-11-07 ### Added - **Flows (flow designer).** New page *Flows*: blocks (find files, replace text, Docker Compose, command/script, query API, check, roll back, wait) connected on a canvas (React Flow) via ok/error outputs, with parameters and placeholders (`{{param.X}}`, `{{steps.ID.value|out|json.path}}`, device fields). The agent runs the graph natively (command `run_flow`) – dry-run preview with unified diffs on one server, test run on that server, then rollout to company/site/tag/all or the affected devices. Per-file backups, automatic rollback when an error output is not connected, run history. Templates: *Replace image in Compose* (also from *Security → Containers*: "Replace image …"), *Replace value in file and restart services*, *Query API and write value*. Migration 0078. ## [0.20.2] - 2026-11-06 ### Added - **OPNsense: agent survives firmware upgrades.** On startup the agent registers itself as OPNsense plugin `os-roster-agent`: local package built with the firewall's own `pkg` (ABI `FreeBSD:*:amd64`, fallback host ABI), local repository `/var/lib/roster/pkg` (+ `/usr/local/etc/pkg/repos/roster.conf`), entry in `config.xml` via `register.php`, service enabled via `/etc/rc.conf.d/rosteragent`. Re-run after every agent self-update. If files are missing after an upgrade, reinstall under System → Firmware → Plugins. Installer also writes `/etc/rc.conf.d/rosteragent`. ## [0.20.1] - 2026-11-06 ### Added - **Security → Containers:** fleet overview of all container images (grouped across devices, critical/high and SSH/FTP/Telnet filters, expandable devices and findings) and the database inventory of all database containers, with a link to database deviations. Route `GET /security/containers`. ## [0.20.0] - 2026-11-06 ### Added - **Container security.** The agent reads os-release and the package list of every image of a running container once a day via `docker exec` (apk/dpkg/rpm); the server matches them against OSV.dev with the versioned ecosystem (Alpine 3.x, Debian 12, Ubuntu 24.04, Rocky/Alma). Results per image in the Docker tab (base OS, packages, critical/high counts, detected services such as sshd/ftpd, "not checkable" for distroless images), full list in the Vulnerabilities tab and the fleet vulnerability view ("Container images"). Button "Rescan images", command `scan_images`. Migration 0077. - **Database deviation (`db_change`).** In MongoDB, MySQL/MariaDB and PostgreSQL containers the agent lists databases and collection/table counts per check-in (credentials from the container environment, never transmitted). The server compares with the previous check-in and raises the incident "Database deviation": new database = warning; deleted or emptied database, ransom-style names (README/WARNING/RECOVER/…) or "data gone + note database" = critical. MITRE T1485/T1486, Active Response trigger (run script). Docker tab shows the inventory per container. - **Docker checks:** modes "Databases in container" (expected list, optional container filter) and "No image older than N days" (uses the new image creation timestamp). ### Fixed - CVE scan: "Fixed in" now takes the version of the queried ecosystem/release (Ubuntu/Debian records list one entry per release; previously the first entry, often of an older release, was shown). ## [0.19.1] - 2026-11-05 ### Added - Ubuntu **phased updates**: the agent asks `apt-get -s dist-upgrade` which upgrades apt defers due to phasing and marks them in the update list (badge "deferred (phasing)"). The install actions on the device, in the bulk action and on the Patches page get the option **Install phased updates now** (`APT::Get::Always-Include-Phased-Updates=true`). Without it, apt skips those packages – which looked like "dist-upgrade did not install everything". Migration 0076. ## [0.19.0] - 2026-11-03 ### Added - File integrity **who-data**: with the policy switch "Identify who changed files" the agent maintains auditd watch rules on Linux (`-w -p wa -k roster_fim`, read via `ausearch --checkpoint`) and on Windows sets success SACLs on the monitored paths and reads events 4663/4660. Changes then carry user and process in the event list (column "Who") and in notifications. Migration 0075 also adds the policy switches for system-state monitoring and the rootkit check. ### Added - Compliance catalog grown from 48 to 106 rules towards CIS Level 1: Linux (SSH idle/grace/empty passwords/rhosts/sessions/log level, pam_pwquality and pam_faillock, password ageing and umask, cron permissions and cron.allow, log file permissions, sticky bit, /tmp and /dev/shm mount options, home directory permissions, sysctl rp_filter/log_martians/redirects/source route/ICMP broadcasts/kptr_restrict, persistent journald, unused filesystem modules) and Windows Server (password history/age, lockout duration, anonymous enumeration, SMB signing, NTLMv2 only, RDP idle timeout, screen lock, firewall logging, Remote Registry, Print Spooler, WinRM basic/unencrypted, NetBIOS, Defender cloud/PUA, UAC secure desktop, SEHOP, DEP, PowerShell script block logging, audit policies for logon/account management/process creation/policy change, event log sizes, cached logons, autologon) – PowerShell-3-safe (`net accounts`, WMI, `auditpol` by GUID, `bcdedit`). Every rule carries **framework references** (CIS, PCI DSS, ISO 27001) shown as badges with a framework filter on the device, fleet and policy views, plus English descriptions and remediations. ### Added - **Rootkit and malware check** (policy switch): once a day the Linux agent looks for hidden processes (answer to `kill(pid,0)` but missing in `/proc`), a non-empty `/etc/ld.so.preload`, hidden kernel modules, interfaces in promiscuous mode, executables/setuid files/ELF binaries in `/tmp`, `/var/tmp`, `/dev/shm`, regular files in `/dev` and known rootkit paths (Reptile, Diamorphine, Jynx, BEURK). Findings become the critical incident **Rootkit indicator**. Files created or modified according to file integrity monitoring are scanned with ClamAV (`clamdscan`/`clamscan`, Linux) or Defender (`MpCmdRun`, Windows) if present → critical incident **Malware**. Button "Rootkit check now" on the device's file-integrity tab. ### Added - **System-state monitoring** (policy switch): every hour the agent compares listening ports, kernel modules, cron entries, UID-0 and administrator accounts, enabled systemd units/timers (Linux), auto-start services and scheduled tasks (Windows, via `net localgroup`/WMI/`schtasks`, Server-2012-safe) and launchd jobs (macOS) with its baseline. Each change becomes the incident **System change** (critical for a new UID-0 or administrator account), listed as "+ new, - gone". ### Added - File integrity monitoring covers the **Windows registry**: rule paths like `HKLM\SOFTWARE\…`, `HKU\*\…` (all loaded user profiles; `HKCU` maps to that) or `HKCR\…`. Keys count like directories, values like files (hash over type and data), new or removed sub-keys are reported (e.g. a new service). The policy gets a button with 18 registry defaults: Run/RunOnce (machine, WOW6432Node, per user), Winlogon, Image File Execution Options, AppInit_DLLs, Services, LSA, Session Manager, Browser Helper Objects, scheduled-task cache, UAC policies, Terminal Server, Defender exclusions. ### Added - Log sources: new formats **HAProxy** (HTTP log), **Traefik** (JSON or common log), **MySQL/MariaDB** error log (access denied, host not allowed) and **firewall drops** (iptables/nft/ufw kernel log, Windows `pfirewall.log`), plus `apache_access` as an alias of the combined log. New source types **systemd journal** (target `kernel` or a SYSLOG_IDENTIFIER – nft/iptables logs on hosts without rsyslog) and **Docker events** (`exec` in a container, start/stop/die). Templates for all of them in the policy. - New incidents **Port scan** (≥ N distinct target ports from one IP within the brute-force window, default 10, Settings → Security monitoring; auto-blocked like brute force) and **Command in container** (`docker exec`). ### Added - Windows login monitoring now also reads the **System** log (7045 service installed) and **PowerShell/Operational** (4104 script block) besides Security, with a cursor per log, and evaluates 4698/4702 (scheduled task created/changed), 1102 (audit log cleared) and 4688 (process creation – only suspicious patterns: certutil/bitsadmin downloads, encoded or hidden PowerShell, mimikatz/procdump/psexec, vssadmin delete shadows, wevtutil cl, schtasks /create, net user, Office spawning shells, …). New incident kinds **Persistence** (warning), **Audit log cleared** (critical) and **Suspicious process** (warning). Prerequisites: audit policy "Process Creation" with command line, "Other Object Access", Script Block Logging (missing logs are skipped). ### Added - **Threat intelligence**: the server fetches five public block lists daily (Spamhaus DROP, blocklist.de, Feodo Tracker, CINS Army, Tor exit nodes; cached in the database, feeds selectable). Source IPs of incidents, login events and blocks are flagged with the list name, and both lists can be filtered to listed IPs. A listed IP raises the incident **Known attack source** on its first failed login, suspicious request or firewall drop and is blocked fleet-wide right away – regardless of thresholds and of the general fleet-block switch (Settings → Security monitoring; never-block list and private addresses stay exempt). New tab Security → **Threat intelligence** with feed status, refresh and IP lookup; migration 0074. ### Added - Security → Incidents: every incident carries its **MITRE ATT&CK** techniques (e.g. T1110 Brute Force, T1070.001 Clear Windows Event Logs) as links into the ATT&CK matrix, and the incident list can be filtered by technique. The catalog of incident kinds (`GET /security/kinds`) is now the single source for server, policies and UI. - Settings → Security monitoring: **severity per incident kind** can override the default (Info suppresses the notification, the automatic response still runs). ## [0.18.19] - 2026-11-03 ### Changed - Agent: results of `block_ip`/`unblock_ip` are reported with the next regular check-in only (no extra check-in at all). The one-per-minute coalescing from 0.18.18 still fired once a minute per device because every device receives a block command about every 30 s under fleet blocking. ## [0.18.18] - 2026-11-03 ### Changed - Agent: results of `block_ip`/`unblock_ip` commands are reported in a coalesced check-in at most once per minute instead of immediately after each command. With fleet blocking every device received a block command every minute or so and checked in every 30 s (six times the regular rate). Interactive commands still report immediately. ## [0.18.17] - 2026-11-03 ### Fixed - Device list (polled every 15 s by dashboard and device page) was expensive per device: the "latest result per task" subquery ran quadratically over the device's task results, and the open-incident count read rows instead of an index. Migration 0073 adds `task_results(device_id, task_id, ran_at)` and `security_incidents(device_id, status)`. ### Added - Regression test for the Windows agent: fails when the embedded EXE would no longer start on Windows Server 2012 (PE minimum version above 6.1 or static imports of Windows-10-only APIs). ## [0.18.16] - 2026-11-03 ### Fixed - Dashboard took seconds to open and pushed the CPU up: the security summary and the country widgets joined the big event/block tables with the device table, and once SQLite had planner statistics it walked them per device (11 s for the blocked-IP count, 1.5–2.3 s per login query). These queries now read only covering time indexes without a join (new index `auth_events(ts, kind, source_ip, device_id)`, migration 0072) and filter by device in Go. - SQLite used a single connection, so every UI request waited behind every check-in write and vice versa. The server now uses a small pool (WAL readers run in parallel; transactions start with `BEGIN IMMEDIATE`, busy timeout 15 s, `synchronous=NORMAL`). - Finished `block_ip` commands are deleted after two days regardless of the result retention – with fleet blocking they were 155 MB of bulk rows. ### Added - Requests slower than 5 s are logged with path, status and duration (long-polls excluded). - `ROSTER_PPROF_ADDR` (e.g. `127.0.0.1:6060`) enables Go's pprof endpoints for diagnosis. ## [0.18.15] - 2026-11-03 ### Fixed - Fleet blocking woke every device immediately for each copied block, so with thousands of incidents a day the whole fleet checked in every ~20 s (12× the regular rate, ~1,500 check-ins per 10 minutes) and each check-in scanned the device's thousands of block rows for expired commands. Copies now arrive with the next regular check-in, and the expiry check walks the device's few pending commands instead (plus index `ip_blocks(status, device_id)`, migration 0071). ## [0.18.14] - 2026-11-03 ### Fixed - Dashboard slow: every widget recomputed all current metrics on each poll (all devices, check states, countries of blocked IPs and attack sources – two passes over the block table with 380,000 rows). The metrics are now cached for 30 s per visibility scope, the blocked-IP count uses the time index instead of scanning the whole table (2.6 s → 0.3 s), and SQLite's planner statistics are refreshed (`PRAGMA optimize`) with each cleanup run. ## [0.18.13] - 2026-11-03 ### Fixed - Server CPU at 100 % of a core and check-ins still timing out: every command result looked up its incident with a full scan of `security_incidents` (several times a second with fleet blocking), and the dashboard scanned the whole `ip_blocks` table every 15 s for the blocked-IP counts. Migration 0070 adds indexes on `security_incidents(response_command_id)` and `ip_blocks(created_at, ip, device_id)`; the security summary is cached for 60 s. ## [0.18.12] - 2026-11-03 ### Fixed - Agent: a hanging ad-hoc command no longer freezes the check-in loop (the device then showed as offline although the remote viewer still worked). Synchronous commands are limited to 10 minutes, and **Scan updates** runs in the background with a 30-minute cap – the Windows Update search on an old Windows Server 2012 without current servicing-stack updates can take hours. - Server: block commands a device could only pick up after the block had already expired (device offline at the time) are discarded at check-in instead of being executed one by one. ### Added - Windows agent service writes its log to `C:\ProgramData\Roster\agent.log` (rotated at 5 MB), since the Service Control Manager discards stderr. ## [0.18.11] - 2026-11-02 ### Fixed - Active Response no longer stalls agent check-ins: with fleet blocking on, every brute-force incident queued the block on ~65 devices one transaction at a time, inside the check-in request, with two unindexed look-ups per device. At several thousand incidents a day check-ins ran into the 30 s timeout (`context deadline exceeded` while saving check results, policies and commands). Responses now run in a serial background worker, the fleet block is a single transaction, and `ip_blocks` gets an index on the address (migration 0069). ### Changed - Retention of the bulk security tables: raw login/log events are kept 30 days (was 90), finished IP blocks 14 days (was 90). Incidents still stay one year. With web scanners the raw events exceed 100,000 rows a day, and fleet blocking stores one block row per device and address. ## [0.18.10] - 2026-11-02 ### Fixed - Windows agent on **Server 2012/2012 R2, Windows 7/8.1**: the EXE was rejected as "not a valid Win32 application" because the Go linker stamps Windows 10 as the minimum OS version into the PE header. The build now lowers it to 6.1 (`tools/pepatch`, also for tray, viewer and the Windows server binary); the runtime itself only needs Windows 7 APIs. Verified under Wine reporting Windows 6.2.9200. - Windows install snippet: forces TLS 1.2 and uses `-UseBasicParsing`, so it works with PowerShell 3/4 on older servers (no Internet Explorer engine, TLS 1.0 default). ## [0.18.9] - 2026-11-02 ### Added - Log sources: **SQL injection** in path or query counts as a suspicious request – `union select`, `' or 1=1`, `sleep(`, `benchmark(`, `waitfor delay`, `information_schema`, `load_file(`, `into outfile`, `extractvalue(`, `admin'--` and more; the URL-decoded form is checked too (`%27%20or%201%3d1`, `union/**/select`). POST bodies are not in access logs and stay invisible; that needs a WAF (ModSecurity denials are recognised in the web error log) or an application log as a custom-pattern log source. ### Changed - Housekeeping: finished IP blocks (released, expired, failed) are deleted after 90 days; the table grew without bound before (fleet blocking creates one row per device and incident). ## [0.18.8] - 2026-11-01 ### Added - Security → Incidents: **filter by country** of the source IP (select with flag, “Unknown” for addresses without a mapping); clicking a country in the *Attack sources by country* tile sets the filter. API: `GET /security/incidents?country=DE` (`?` = unknown). ## [0.18.7] - 2026-11-01 ### Changed - Device → Security: separate **Incidents** tab (security incidents, active IP blocks, open-incident counter); **Logins** now shows only the monitoring card and login events – split like the fleet page. - Device → Logins: column is now “Events since agent start” (with explanation), as the counter only counts new lines while “Test” reads retroactively. ## [0.18.6] - 2026-11-01 ### Changed - Dashboard: country metrics show up to 40 countries as bars, sorted descending (instead of 12 + “Other”); the remainder is labelled “Other (n countries)”. ## [0.18.5] - 2026-11-01 ### Fixed - **Automatic blocking no longer blocks private/internal addresses** (10/8, 172.16/12, 192.168/16, 100.64/10, fd00::/7, link-local). Background: a log source behind a reverse proxy only saw the proxy's Docker-internal address; the “attack pattern” incident blocked it fleet-wide in DOCKER-USER and cut the proxy off from the backends. The incident is still recorded, the response reads *skipped: private address*. Settings → Security monitoring has an opt-in; manual blocks remain possible. ### Added - Security → Blocks: **search** (IP/network, device, reason, creator) and **status filter** (active/queued, expired, released, failed) – server-side, up to 1,000 rows; the **everywhere** button releases an IP on all devices with one click (`POST /security/unblock-ip`). ## [0.18.4] - 2026-11-01 ### Fixed - Log sources: lines from **nginx-proxy** (forego prefix with colour codes) were not unwrapped cleanly, so the bare-IP detection did not apply. ANSI codes are now stripped. New attack patterns: command/code injection in path or query (`cmd=`, `=curl`, `${jndi`, `