VPS monitoring with an agent: what you get

On a server where you have root you install the full agent: a shell script that reports, signed, every 5 minutes, what happens inside. From outside we check the public address. Real problems become an incident and alert you; the rest stays on the host page.

  • agent, installed as root
  • signed report every 5 min

What you get

What you install

The agent, with one command run as root. On systemd it runs from a low-priority timer; without systemd, from cron. No dependencies beyond standard tools: sh, curl, openssl and sha256sum; python3 is recommended.

What it sees inside

SSH logins, new keys and accounts, sudo, suspicious processes, connections to mining pools, new executables in /tmp, the site files (fingerprints and backdoor patterns), web traffic, mail (where there is one), firewall, ports, cron, disk, failed services, updates and the sshd configuration.

What it sees from outside

If the host address is an IP: blocklists and 16 sensitive ports. If it is a domain: availability, DNS, certificate, blocklists and domain expiry. Either way, every hosted site that answers gets an HTTP probe, and all their certificates are watched.

What alerts you

Suspicious SSH logins, new keys or accounts, mining processes and connections, new executables, malware in a site, web campaigns, a full disk, a listed IP, exposed database ports, a site down, a certificate close to expiry, a silent agent.

What it can fix

Four, only with your approval: block an address in the firewall (expires after 24 hours), stop a process, move a file from /tmp to quarantine, restart the web server after testing its configuration. Switched on in two places: at install time and in the dashboard.

What it cannot see

Security headers, page content, email posture and the site’s exposed files are not checked from outside on a VPS: for those, add the same domain as an external site too. And nothing inside the applications: the agent sees the server, not the database or the application code.

What you see in the dashboard

The host page has the Overview, Availability, System, Security, Files, Inventory, Checks, Activity and Agent tabs: charts, logins, processes, network, the site files, the inventory, the outside checks and the agent’s state.

How it counts against your plan

One host from your plan. The hosted sites found on the server get a probe without using extra hosts.

The full list, row by row

Each row says how often it looks, what it compares and what it does: alerts you, shows only on the host page, or is a remediation you approve.

from the report

  • CPU, as load per core (every 5 min) [on the host page]: Load normalized per core, not true utilization: that is what a shell script can compute cheaply. It can exceed 100% when a run queue forms. It shows in the host page charts; it sends no alert.
  • Memory and the / disk (every 5 min) [on the host page]: In the dashboard the number turns amber from 85% memory and 80% disk, so you get days to clean up. Full memory sends no alert on its own; processes killed for lack of memory and a disk at 97% do (the rows below).
  • Load average and uptime (every 5 min) [on the host page]: A reboot you did not know about shows up as uptime reset between two reports, even when nothing else changed.

what the agent watches

  • SSH logins, accepted and failed (every 5 min) [alerts you]: Source, user and method. Three things open an incident: a login with a key we do not know (critical), a successful login after at least 10 failures from the same address within two hours (critical), and a password login from a new address (warning). The usual wave of failures stays on the host page.
  • SSH keys, accounts and sudo (every 5 min) [alerts you]: A new key in authorized_keys, an SSH certificate authority, a new account with a shell, a new member of sudo, wheel or docker, a new sudoers line, or an account created or changed (useradd, usermod, passwd): a critical incident at once, with no threshold.
  • Suspicious processes, by behavior (every 5 min) [alerts you]: Not signatures but a score: a binary started from /tmp or deleted from disk after starting, an interpreter running a script from /tmp, CPU above 80% for at least 10 minutes, an unusual user. From a score of 7 it is a critical incident. That is how the miner posing as a system process was caught.
  • Connections to mining ports (every 5 min) [alerts you]: Established connections to the ports mining pools use (3333, 4444, 14444 and ten more), excluding private addresses and connections that came in on a port the server itself listens on. A critical incident. A miner moved to port 443 does not show here; the process rule catches it by its CPU use.
  • New executables in volatile directories (every 5 min) [alerts you]: /tmp, /var/tmp and /dev/shm: ELF files or scripts with the execute bit, new since the last report, with a sha256 fingerprint. A critical incident: that is where almost every payload lands first.
  • Backdoor patterns and fingerprints in the webroot (every 5 min) [alerts you]: Webshells, obfuscated eval, uploaders and risky lines in .htaccess or .user.ini, in the site roots named in the nginx and Apache configuration. Only new or changed files are read (their first and last 64 KB), and a certain pattern opens a critical incident. Every file has a fingerprint: a new, changed or deleted one shows on the host page, without an alert.
  • Web traffic of the hosted sites (every 5 min) [alerts you]: The server’s nginx and Apache logs, summarized per source: how many different paths it tries in an hour, how many errors it gets, whether it announces a scanning tool, requests shaped like a backdoor. A sustained campaign opens an incident; an ordinary bot stays a note on the host page.
  • The server’s mail, where there is one (every 5 min) [alerts you]: Only where postfix, exim or dovecot runs. An account sending more than 1,000 messages an hour or a queue above 2,000 messages opens a critical incident; repeated password attempts and smaller volumes stay on the host page. Usernames typed in failed logins never leave the server.
  • Firewall blocks and fail2ban (every 5 min) [on the host page]: We count from the rule counters, not from the log: firewalld ships with logging off, so on most RHEL servers the log is empty while the counters climb. The log only says who was blocked.
  • Firewall rules, as a baseline (every 5 min) [on the host page]: We read the rules straight from nftables, firewalld, ufw or iptables and diff them against the previous ones. A deleted rule is the half that matters: that is how a door opens. If we find no firewall with rules at all, we say so: a server without one produces no blocks.
  • New listening ports (every 5 min) [on the host page]: A diff against the approved state, by address and port. A port that appears without you installing anything is the question of the day. The ports actually exposed to the internet are checked from outside by the IP probe (below).
  • Cron jobs and systemd timers (every 5 min) [on the host page]: /etc/crontab, cron.d, user crontabs and systemd timers, with the whole command. Persistence is set up through cron more often than through anything else.

system health

  • Disk and inodes, on every filesystem (every 5 min) [alerts you]: Not only /: a full /var stops the database and the logs while / still looks fine. A warning on the host page from 90%, a critical incident from 97%.
  • Failed systemd units (every 5 min) [on the host page]: Every service systemd has marked as failed, by name. A certbot that died at three in the morning shows up here before the certificate expires.
  • Processes killed by the kernel for lack of memory (every 5 min) [on the host page]: What the OOM killer stopped since the last report. A database killed overnight leaves only this trace.
  • Pending updates and required reboot (every 6 h) [on the host page]: How many updates are available and how many are security fixes, simulated from the package lists already on the server: the agent installs nothing. Security updates and a reboot pending for over 7 days become a warning.
  • SSH password logins (every 6 h) [on the host page]: From the effective sshd configuration, not the file. Root with a password is a warning; passwords for other accounts are noted.
  • System posture, in a single check (every 5 min) [on the host page]: Security updates, a pending reboot, root with a password, a missing or non-filtering firewall: gathered into one check that shows on the host page and in the security score. It is hygiene, so it sends no alert.
  • The server’s PHP, against PHP2Shell (every 5 min) [alerts you]: Every installed PHP version and the package it comes from: whether the one your sites use is affected by PHP2Shell (CVE-2026-109618, CVE-2026-109619), whether your distribution shipped the fix under the old number, and whether PHP was restarted after the update. The inventory is refreshed every 6 hours; an affected version in use opens an incident.
  • Operating system out of support (every 5 min) [on the host page]: A release out of support no longer receives security updates, however often you upgrade. We warn 90 days ahead.

from outside, if the address is an IP

  • Blocklists for the IP (every 6 h) [alerts you]: The server’s address, on Spamhaus ZEN, SpamCop and Barracuda. A listed IP is a critical incident: the server’s mail stops arriving. A list that does not answer means “unknown”, not “clean”.
  • Ports exposed to the internet (every 12 h) [alerts you]: We try 16 ports from outside, on the server’s IP. A database (MySQL, PostgreSQL, Redis, MongoDB, Elasticsearch, Memcached), the Docker API, VNC or Telnet reachable from the internet is a critical incident; RDP, FTP and Kibana are a warning.

from outside, if the address is a domain

  • HTTP availability (every 1 min) [alerts you]: The site at the host address, seen as a visitor sees it: code, response time, redirects. A failure is confirmed by a second probe 15 seconds later, before alerting.
  • DNS records (every hour) [alerts you]: A, NS and MX against the baseline, from public resolvers. A change of A or NS is a critical incident.
  • TLS certificate and blocklists (every 6 h) [alerts you]: The certificate actually served (chain, name, days left: 21 and 7) and whether the domain’s IP is on the lists that affect mail.
  • Domain registration expiry (every 12 h) [alerts you]: Through RDAP, with whois as a fallback. Warning at 30 days, critical at 7. For .ro the registry publishes no date, so we watch the domain status.

the sites hosted on the server

  • The hosted sites, each with its own probe (every 1 min) [alerts you]: The domains in the nginx and Apache configuration that the agent reports are tried once; the ones that answer get an HTTP probe, without using a host from your plan. A failure is confirmed by a second probe 15 seconds later, before alerting.
  • The certificates of every hosted site (every 10 min) [alerts you]: The certificate each probed site serves: a warning 21 days before expiry or when browsers reject it, critical from 7 days. One incident per server, listing the sites.

remediation, only with your approval

  • Block an address in the firewall (on request) [with your approval]: IPv4 only, on nftables, firewalld or ufw. The rule expires after 24 hours: on nftables inside the kernel itself, on firewalld and ufw at the agent’s next run, so even if the dashboard stops answering. The agent refuses private addresses, the server’s own address, the gateway, the DNS resolvers and the dashboard’s addresses: blocking any of them would sever the very channel that could undo it.
  • Stop a process (on request) [with your approval]: Before sending the signal the agent re-checks that the pid still belongs to the same program: name, executable and the start time recorded by the kernel. A pid recycled between proposal and approval is refused, not killed. systemd, sshd, journald and the rest of what keeps the server administrable are never touched.
  • Move a file to quarantine (on request) [with your approval]: It is moved, never deleted or rewritten: the file stays as evidence and goes back with one click. Only from /tmp, /var/tmp and /dev/shm, never through a symlink, and only if the fingerprint still matches the one at the moment of the decision.
  • Restart the web server (on request) [with your approval]: nginx, Apache, LiteSpeed or PHP-FPM, only the units the agent reports. The configuration is tested first (nginx -t, apachectl -t, php-fpm -t): if the test fails, nothing is restarted and you see why. Then a reload or restart, a check that the service is still running two seconds later, the last lines of its log and a fresh probe of the site from outside. At most three restarts an hour for the same service. It can be turned off on the server with VPSDASH_ACTIONS_SERVICES=0.

from our side

  • Silent agent: a critical incident (always on) [alerts you]: If three reports in a row do not arrive, we treat the absence as a signal, not as quiet. Either the server is off or the agent was stopped, and the second is what a successful compromise looks like.
  • A collector that can no longer read (every 5 min) [alerts you]: A moved log, a lost permission, a missing tool: the affected collector is named, with the reason. A silent collector must never look like a clean server.
  • A wrongly signed command: a critical incident (always on) [alerts you]: Every command is signed with your server’s secret, over a random number the agent generated seconds earlier, so a recorded reply cannot be replayed later. If the signature does not verify, the agent refuses and reports it: someone is trying to command the server.

remediation ships disabled and takes two separate switches to turn on: one when you install the agent on your server, one in the dashboard. Without both, even a correctly signed command is refused

How to start

  1. In the dashboard pick “Add a host”, type “VPS with agent”, with the server address (IP or domain).
  2. Copy the install command generated there and run it on the server, as root. The key and the secret travel in environment variables, not in the URL.
  3. The installer sends the first report and tells you whether the dashboard received it. From then on the agent reports by itself, every 5 minutes.
  4. Optional: remediation. You switch it on at install time and in the dashboard; without both, no command runs.

Questions about this host type

Does the agent need root?

On a VPS, yes: the full agent reads the authentication log, the firewall rules and every user’s processes. Run without root, the installer switches by itself to shared hosting mode, which only sees the site files, the account cron and the access logs.

How much does it use on the server?

It runs every 5 minutes, at low CPU and disk priority, with a time limit on every command. File fingerprints have a budget of 20 seconds and at most 2,000 files per run, and on an untouched site a run re-reads nothing.

What data leaves the server?

Numbers, names, fingerprints and summaries. On a critical incident, short evidence is added: the process command line, the last 60 lines of the authentication log when an account or key changes, the first 256 bytes of a new executable. Whole files, .env, databases and private keys never leave.

Can the agent change anything on the server?

By default, no: it only reads. The four remediations are switched on in two places and run only after you approve them. Updating the agent from the dashboard is a separate option, ticked by default at enrollment (you can untick it), and it checks the file’s fingerprint before running it.

The other host types

Shared hosting · External site · cPanel/WHM reseller