Repository navigation
Releases: aulafy/vigia
Releases · aulafy/vigia
Release list
Vigía v0.15.0
Added
-
One-command VPS kit (
deploy/vps/):setup.sh <domain>on a fresh Ubuntu/Debian server does the following:- installs Docker and a firewall (SSH, 80, 443);
- writes
/opt/vigiawith Vigía behind Caddy (Let's Encrypt certificate, HSTS,X-Forwarded-Foroverwritten, soTRUST_PROXY=trueis safe); - generates every secret into
.env(never overwritten on re-runs); - installs a daily backup of
data/and.env, kept 14 days; - checks the DNS, waits for HTTPS, and prints the dashboard password and ntfy topic once.
Tested end to end with a local certificate. CI dry-runs it and validates the compose file.
-
deployment.md leads with the VPS kit, and the README quick start and the technical guide include it.
Docker image: docker pull ghcr.io/aulafy/vigia:0.15.0
Vigía v0.14.2
Fixed
- The installers no longer warn about plain HTTP when Vigía is on the same machine (
localhost,127.x,::1): the key never leaves it. On a private network, the warning now says the key crosses your local network unencrypted.
Docker image: docker pull ghcr.io/aulafy/vigia:0.14.2
Vigía v0.14.1
Fixed
- Running the test suite could delete pushed inventories from your real
data/pushed.json. The test for "refuses to listen beyond localhost without a password" started a server that loaded and scheduled everything before refusing. Its first cleanup ran against the test inventory and wrote the real file, because the test did not redirect that one. A refused start now exits before any data file is read or written, and tests and the demo keep every file in a scratch folder (VIGIA_DATA). A push from each agent restores what was lost. - The demo wrote monthly reports into the real
data/reports/.
Added
VIGIA_DATA: folder for every data file (defaultdata/).
Docker image: docker pull ghcr.io/aulafy/vigia:0.14.1
Vigía v0.14.0
Added
- Exposure to the Internet. For every computer, Vigía now checks whether the ports it listens on answer from the Internet at its public address. Risky services (RDP, SMB, databases, VNC, Telnet, FTP…) are P2, or P1 on high criticality. The Docker API is P1 and other ports P3. Acknowledging accepts a port for that computer. When a port stops answering, the alert closes with a message.
- Which address: the one the inventory came from, if it is public. Otherwise it is the one the agent looked up (
--publicipinvigia-collect.sh, now part of--all, and the same in the Windows agent;VIGIA_IP_URL,offto skip). Behind a reverse proxy,TRUST_PROXY=trueusesX-Forwarded-For. Only global addresses are accepted, never private, loopback, link-local, CGNAT, documentation or multicast ranges. - How it probes: a plain TCP handshake, only on the TCP ports that computer reports listening on beyond loopback (at most 50). Each address and port is tried at most every
EXPOSURE_HOURS(6), 10 at a time. Computers behind Vigía's own public address are skipped, because from inside the same network the router's answer means nothing (hairpin NAT). The dashboard says so.PUBLIC_IP_URLandEXPOSURE_CHECK=falsecontrol this. - Dashboard and portal: public address and "open to the Internet" on each computer.
- docs/technical-guide.md: a technical guide for IT staff covering architecture, every check and its priority, data sources, agents, protocols and signatures, alert lifecycle, API, deployment, hardening, operations and limits.
Security (from an independent review before release)
- Addresses are parsed and stored in one canonical form (IPv4-mapped IPv6 included), and hostnames are refused.
- With
TRUST_PROXY, only the lastX-Forwarded-Forentry counts, and only when the connection comes from a private address. - Probing is bounded: 500 probes per round, 20,000 stored results. A computer reporting more than 3 addresses in a day is not checked. An address reported only by the agent waits until Vigía knows its own.
- A probe Vigía could not attempt (no route) is "unknown": it neither raises nor closes an alert. When a computer turns out to share Vigía's network, its exposure alerts close.
- When several computers behind one address listen on the same port, the alert names the others.
Fixed
- A lifecycle test depended on the time of day (it mixed the wall clock with the simulated one).
Docker image: docker pull ghcr.io/aulafy/vigia:0.14.0
Vigía v0.13.0
Added
- Client portal: a read-only page per client behind a signed link from Clients → a client → Client portal and notices. It shows a plain-words status ("Everything is working" or "2 open issues, your IT team is on it") and their open issues (Urgent, Important, Notice), saying whether you are on it. It also lists their websites, computers, firewalls and backups, and their monthly reports. It shows nothing about other clients or Vigía's own alerts. There are no scripts and nothing is indexed, it refreshes every 5 minutes, and it works on phones and in dark mode. Links do not expire: New link retires the previous one and Turn off retires it. Ten wrong links from one address are blocked for 10 minutes.
- E-mails to the client: addresses per client, urgent only or urgent and important. Clients hear about new, worse and resolved issues and what is still open after maintenance. They never get the 10-minute repeats, the digest or Vigía's own alerts, and get no acknowledge links (the portal link instead). Notices are batched for a minute per client, so a burst is one e-mail. Send test checks the addresses, and a failed delivery is a P2 for you. A new
onEventhook in the alert lifecycle (alerts.mjs) decides what a client hears. - Monthly report: a Computers and servers table (system, antivirus, last update, last report, open alerts).
data/clients.json(VIGIA_CLIENTS) holds per-client e-mails and portal link versions. API:PUT /api/clients/<client>,POST /api/clients/<client>/portal,POST /api/clients/<client>/test,GET /portal/<token>,GET /portal/<token>/report.npm run demohas a portal link on for Clínica Dental Sol.
Security (from an independent review before release)
- Client names never reach
Object.prototype: settings are kept in prototype-less objects, and__proto__,constructorandprototypeare refused as client names. - The portal's monthly report leaves out Vigía's internal alerts, like the portal page.
- Only wrong portal links are rate-limited, so a stranger cannot lock clients out of a valid link behind a shared proxy address.
- A client that leaves the inventory loses its link and recipients, so a new client with the same name does not inherit them.
- Client e-mails: at most one every 5 minutes per client, problems that come and go within a batch are dropped, 20 items at most. Resolutions reach the client even when they are quiet for you. The sender is always
MAIL_FROM/SMTP_USER, never derived from the client's domain. - Client settings are written to disk before they change in memory; a write error answers 500 instead of stopping Vigía.
Docker image: docker pull ghcr.io/aulafy/vigia:0.13.0
Vigía v0.12.0
Added
- Computers and servers with one install line. Clients → Add computers creates a line for Linux/macOS (
curl … | sudo sh) and one for Windows (PowerShell). Run on a computer, it registers it under that client, installs a daily job (systemd timer, cron, launchd or a scheduled task) and sends a signed inventory. That inventory covers the operating system, antivirus, installed software, ports the computer listens on and its last update. The line holds an expiring token signed withCHECKIN_SECRET(ENROLL_DAYS, default 7). Every computer gets its own key, and running the line again on the same computer updates it instead of adding a duplicate. Nothing is scanned: each computer reports on itself. - New findings for computers: Windows without an active antivirus (P2); antivirus signatures older than 7 days (P3); no Windows updates for 45 days (P3) or 90 (P2); risky services listening on the network (RDP, SMB outside Windows, FTP, Telnet, VNC, databases; P3, the Docker API P2); a new listening service since the first inventory (P3, acknowledge to accept it); macOS behind the latest release of its version (P3). Windows and Windows Server end of life comes from endoflife.date's own cycles (
11-24h2-w,10-22h2,2012-r2…). - Installed programs matched against CISA KEV: WinRAR, 7-Zip, AnyDesk, TeamViewer, ScreenConnect, SimpleHelp, Veeam, PaperCut, MOVEit, GoAnywhere, CrushFTP, FortiClient, GlobalProtect, Acrobat, Java, Exchange and more. Browsers, Office and Zoom update themselves, so their matches are P3.
- Windows agent
deploy/vigia-agent.ps1(PowerShell 5.1+). It reads Defender and Windows Security products, programs from the registry,Get-NetTCPConnectionandGet-HotFix. It installs the "Vigia inventory" task as SYSTEM, its key is readable only by SYSTEM and Administrators, andVIGIA_DRYRUN=1/VIGIA_UNINSTALL=1are supported. vigia-collect.shgains--listening,--av,--softwareand--all, plus macOS support (sw_vers,lsof, applications, XProtect). It reads its address and key from/etc/vigia/agent.env.deploy/vigia-install.shis the one-line installer, with--uninstall.- Email channel: a built-in SMTP client (
smtp.mjs, still zero dependencies) with implicit TLS (465) or STARTTLS (587), AUTH PLAIN/LOGIN and verified certificates. A password is never sent without TLS, except tolocalhost. P1/P2 alerts, the digest and the canary go toMAIL_TOwith the acknowledge link and a dashboard link. Configured withSMTP_HOST,SMTP_PORT,SMTP_SECURE,SMTP_USER,SMTP_PASS,MAIL_FROMandMAIL_TO. - API:
POST /api/enroll-token(dashboard),POST /api/enroll(install-line token, rate-limited),GET /agent/install.sh|vigia-collect.sh|vigia-agent.ps1. - Dashboard: a Computers and servers section on each client (OS, antivirus, software count, last update, listening ports, alerts) and an Add computers screen with copy buttons. It warns when Vigía is on localhost or plain HTTP.
npm run demoadds two computers through the real install-line endpoints: a Windows PC with problems and a Mac.
Security (from an independent review before release)
- The address in the install line comes from
PUBLIC_URL, or from the request only when it is a plain URL, so a forgedHostheader cannot inject commands. - Installers refuse plain HTTP outside private networks (
VIGIA_INSECURE=1to override). On Windows,C:\ProgramData\Vigiais owned by Administrators and stripped of inherited permissions, and a folder that is a link is refused before anything runs as SYSTEM. - Email is never sent in plain text to a remote server (
SMTP_ALLOW_PLAIN=trueto allow it for a relay without a password), and addresses are validated before they reach an SMTP command or header. - Bad install-line tokens have their own rate limit, separate from dashboard logins.
- A push without antivirus, update or port data no longer closes those alerts.
- The dashboard editor reads
inventory.jsonafter the request body arrives, so a computer registered meanwhile is never overwritten. - Agent scripts drop control characters from names before building JSON.
Docker image: docker pull ghcr.io/aulafy/vigia:0.12.0
Vigía v0.11.0
Added
- Local AI (optional, Ollama): two buttons on every alert. Explain covers what is happening, the real risk, numbered steps and how to check the fix. Draft for the client writes a short, jargon-free message to copy into an e-mail or WhatsApp. Both are marked as an AI draft. Nothing is sent, and the AI never changes priorities or acknowledges anything.
- Grounded prompts (
ai.mjs): the model gets only what Vigía knows about that alert (registrar, DNS and SPF/DMARC records, component version, device, backup run, site status, EPSS…). Every unknown fact is listed as unknown, so the model does not fill gaps: without the registrar it had suggested "GoDaddy or Cloudflare" for a NameCheap domain; with it, it said NameCheap. Feed text is fenced as data. - One generation at a time, a cache per alert text, and a time limit. Settings shows whether the model is installed and reachable. The configuration is
OLLAMA_MODEL(enables it),OLLAMA_URLandOLLAMA_TIMEOUT_S. POST /api/ai/explainandPOST /api/ai/client.
Fixed
- Tests and
npm run demono longer read your own.env. They could send test alerts to your real channels (VIGIA_ENV_FILEselects the file).
Docker image: docker pull ghcr.io/aulafy/vigia:0.11.0
Vigía v0.10.0
Added
- Edit clients from the dashboard. Add, edit, pause and delete assets with their software, firewalls/VPNs and backup jobs, with no JSON involved. The form validates as you type, with the same rules the server enforces (
public/validate.js, shared), and proposes an ID from the client and name. Every save checks the revision the form started from, so a hand edit ofinventory.jsonin the meantime is never overwritten: you get a warning and your changes are kept. The previous file is kept indata/inventory-history/(last 20), writes are atomic, and an unreadableinventory.jsoncannot be edited from the dashboard until it is fixed. IDs cannot change, because alerts and history use them. - Maintenance windows for an asset, a whole client or everything, from the client page or Settings: 1/2/4/8 hours, until 08:00 tomorrow, or custom (up to 7 days). During a window, alerts for those assets are recorded but not sent, P1s do not repeat, and planned downtime does not count against availability. Whatever is still wrong when the window ends is sent then, marked "(after maintenance)", and what got fixed during the window is closed quietly. Windows appear on Today and in the client's monthly report.
- Docker image on GHCR for amd64 and arm64:
ghcr.io/aulafy/vigia, taggedlatest,0.10and0.10.0.docker-compose.ymlnow uses it. Releases: every version tag runs the tests, publishes the image and creates a GitHub release with the notes from this changelog. - API:
GET /api/inventory,POST /api/assets,PUT|DELETE /api/assets/<id>,POST /api/assets/<id>/pause,GET|POST /api/maintenance,DELETE /api/maintenance/<id>.
Changed
- Dashboard actions with
PUTandDELETErequire thex-vigia-uiheader too (CSRF). - The client page lists every asset, device-only ones included, with Edit and Pause buttons.
- Focus and cursor survive redraws in every text field, not only in search.
Docker image: docker pull ghcr.io/aulafy/vigia:0.10.0