Installing the sensor on Linux
The GPG-signed deb and rpm packages, the exact install commands, the systemd unit and its paths, and what the sensor needs from the kernel to see anything useful.
The Linux sensor is a single static binary run by systemd as an unprivileged service. It reports process activity and file activity to Qorionix, and it is the same code as the Windows and macOS builds with a different set of collectors underneath. This article covers what it runs on, the exact commands, where the files go, how to confirm it works, and — the part most vendors skip — what it needs from the kernel and what you actually lose where that is missing.
What it runs on
One packaging definition produces both a .deb and an .rpm, for amd64 and arm64. Our architecture decision record lists the family coverage as Ubuntu, Debian, RHEL, Rocky, Alma and AmazonLinux. We do not publish tested minimum releases for each of those, and we would rather tell you that than print a version table nobody verified.
- systemd is required. The package ships a systemd unit and nothing else; there is no SysV or OpenRC init script.
- Debian and Ubuntu package dependencies:
libc6,adduser,libcap2-bin. - RHEL-family package dependencies:
glibc,shadow-utils,libcap. - Outbound HTTPS to your API base URL — the console origin you were given at enrolment, e.g.
https://app.qorionix.com. Nothing inbound; the sensor never listens on a port. - An enrolment token from the console, Settings -> Endpoints -> Enrolment tokens. See Enrolment tokens.
The install commands
The console generates these when you create an enrolment token, with the download URL, token and API URL already substituted. They begin with a fetch on purpose: a copy-pasteable command that names a file you were never told how to obtain is worse than no command at all. Every generated command downloads the package, its GPG signature and the public key, verifies the signature, and only then installs — all &&-chained, so a bad signature stops the command rather than being silently skipped.
curl -fsSL -o qorionix-sensor.deb <url> \
&& curl -fsSL -o qorionix-sensor.deb.asc <url>.asc \
&& curl -fsSL -o qorionix-linux-packages.asc https://stqorionixmvpqtjd4q.z16.web.core.windows.net/agents/qorionix-linux-packages.asc \
&& sha256sum -c <(echo '<published-sha256> qorionix-sensor.deb') \
&& gpg --import qorionix-linux-packages.asc \
&& gpg --verify qorionix-sensor.deb.asc qorionix-sensor.deb \
&& sudo QX_ENROLL_TOKEN=<token> QX_API_URL=<api> apt-get install -y ./qorionix-sensor.debcurl -fsSL -o qorionix-sensor.rpm <url> \
&& curl -fsSL -o qorionix-sensor.rpm.asc <url>.asc \
&& curl -fsSL -o qorionix-linux-packages.asc https://stqorionixmvpqtjd4q.z16.web.core.windows.net/agents/qorionix-linux-packages.asc \
&& sha256sum -c <(echo '<published-sha256> qorionix-sensor.rpm') \
&& gpg --import qorionix-linux-packages.asc \
&& gpg --verify qorionix-sensor.rpm.asc qorionix-sensor.rpm \
&& sudo QX_ENROLL_TOKEN=<token> QX_API_URL=<api> dnf install -y ./qorionix-sensor.rpmThe command the console generates for you has the exact URLs and checksum substituted — copy that one rather than retyping the shape above. The public key's fingerprint is 82B5493F28E56C9879AF345C69585537BBC6B9D9; if you are verifying by hand outside the generated command, confirm gpg --verify reports a good signature from that fingerprint before trusting the download.
Those two work from an interactive shell. They are not the form to use from configuration management, because apt and dnf do not reliably forward the invoking environment to package maintainer scripts. If Ansible, Puppet, Chef or an MDM is doing the install, drop the token into a file instead — a file arrives reliably where an environment variable may not.
curl -fsSL -o qorionix-sensor.deb <url> \
&& sudo mkdir -p /etc/qorionix && printf '%s' '<token>' | sudo tee /etc/qorionix/enrollment-token >/dev/null \
&& sudo chmod 600 /etc/qorionix/enrollment-token \
&& printf '%s' '<api>' | sudo tee /etc/qorionix/api-url >/dev/null \
&& sudo apt-get install -y ./qorionix-sensor.debThe token file is read and whitespace-stripped, so a trailing newline or a CRLF from a file pushed by an MDM is handled rather than turned into a mystifying rejection. The installer deletes /etc/qorionix/enrollment-token once enrolment reaches a terminal outcome, and keeps it where a corrected re-run would still need it.
Where everything lives
| Thing | Value |
|---|---|
| Service name | qorionix-sensor.service |
| Runs as | the qorionix-sensor user and group, not root |
| Binary | /usr/bin/qorionix-sensor |
| Config | /etc/qorionix/qorionix-sensor.yaml, owned root:qorionix-sensor, mode 0640 |
| Log file | /var/log/qorionix-sensor.log, plus journald |
| Local state | /var/lib/qorionix-sensor/cache.db |
| Quarantine vault | /var/lib/zentryq/quarantine |
| Unit file | /lib/systemd/system/qorionix-sensor.service |
The config path is compiled into the binary rather than supplied by the unit, so the unit, the package scripts and the enroll subcommand cannot disagree about where it is. Only five keys in that file are read: api_url, enrollment_token, sensor_id, organization_id and tls_insecure_skip_verify. The channels, poll_interval_seconds, cache_path and log_path entries you will see in the shipped default are written but not parsed — they are not tuning knobs, and we would rather say so than let you spend an afternoon changing a value nothing reads.
The unit is deliberately hardened. It runs with NoNewPrivileges, ProtectSystem=strict, ProtectHome, PrivateTmp and MemoryDenyWriteExecute, and can only write to /var/lib/qorionix-sensor and its log file. Restart policy is Restart=always with RestartSec=5, and the start-limit budget is widened to ten restarts in five minutes — systemd's default of five in ten seconds is the wrong budget for a security agent, because it gives up permanently at exactly the moment you most want it trying again.
What the sensor needs from the kernel
The service does not run as root. Instead the unit pins exactly four capabilities, in both the ambient set and the bounding set, so the process holds these and nothing more:
| Capability | Why it is needed |
|---|---|
CAP_SYS_PTRACE | Read details of processes owned by other users from /proc. |
CAP_DAC_READ_SEARCH | Read files and directory entries the service account would otherwise be refused. |
CAP_AUDIT_READ | Read the kernel audit stream. |
CAP_NET_ADMIN | Apply and remove the host firewall ruleset used by network isolation. |
Beyond those, three collectors run concurrently and they are not equally important:
- The procfs process differ — the source of record
- It reads the process table from
/procevery two seconds and diffs it. It always works, it carries the parent linkage and the full command line, and it depends on nothing being installed. This is what behavioural detection actually runs on. - The file watcher
- A bounded scan of a few directory trees every five seconds, recording path, size and entropy. Its job is the burst shape that mass file encryption produces. Default roots are
/home,/srvand/var/www; setQX_WATCH_PATHS(ZQ_WATCH_PATHSis still read as a fallback this release) to change them. - The auditd tail — useful, optional
- It follows
/var/log/audit/audit.logfor syscall-level context that procfs cannot give. If that file is absent — a container, an unprivileged laptop, most non-RHEL default installs — this collector degrades to a 30-second heartbeat and the other two carry on regardless.
Two things are not available on Linux, and both bound what can ever be detected. There is no eBPF collector in the shipped package — the build tag exists, the compiled program lives outside the distribution build, and it is excluded from the artefacts you download, so treat eBPF as not shipped. And the sensor is a userland poller rather than a kernel callback: a process that starts and exits inside one two-second interval is missed. That trade buys an agent with no kernel module, no compiler, no headers and no dependency on your distribution's kernel version, which on a mixed fleet is worth a great deal. It is still a real gap and it is listed as one.
Confirming it is running
sudo systemctl status qorionix-sensor
sudo journalctl -u qorionix-sensor -n 50An active unit is necessary and not sufficient. The check that counts is the machine appearing under Endpoints in the console with a recent last-seen time, usually within a minute. A sensor that installed cleanly but never enrolled looks perfectly healthy from the host and does not exist as far as the platform is concerned.
In the journal, the messages worth recognising are these. Repeats of the same message are throttled to one line every five minutes, with a (<n> similar messages suppressed) suffix, so a machine that has been offline overnight does not fill your log.
sensor: cannot reach <endpoint> (<err>) — <n> events dropped
sensor: telemetry rejected with HTTP <code> — <n> events dropped
sensor: telemetry delivery recovered
sensor: enrolled as <sensor-id> after <n> attempt(s)
sensor: no credential configured — this endpoint will not report. Re-run the installer with an enrolment token from Settings -> Endpoints -> Enrolment tokens.To re-enrol a machine without reinstalling the package, run the enroll subcommand and restart the unit. --token, --config and --api are all required — pass the console origin you were given at enrolment as --api. --timeout defaults to 20s.
sudo qorionix-sensor enroll --token <TOKEN> --api <URL> --config /etc/qorionix/qorionix-sensor.yaml && sudo systemctl restart qorionix-sensorUpgrading and removing
Upgrade by installing the newer package over the old one — sudo apt-get install -y ./qorionix-sensor.deb or sudo dnf install -y ./qorionix-sensor.rpm. The config file is marked as a configuration file that must not be replaced, so the machine's credential survives the upgrade and no re-enrolment is needed; the package's post-install step restarts the unit. There is no automatic update mechanism at all, which is a limitation rather than a preference — Keeping the sensor up to date explains how to run this across a fleet.
To remove it, remove the package: sudo apt-get remove qorionix-sensor or sudo dnf remove qorionix-sensor. As on every platform, removing the software does not remove the endpoint from your console — it reads as stale fifteen minutes after its last telemetry and stays there. Revoke the sensor in the console if the machine is gone for good; a revoked sensor is refused with sensor auth: sensor revoked even if someone restores the disk image later.
What to do next
- Enrolment tokens — token scoping, lifetimes and every failure message, verbatim.
- What the sensor collects — the per-platform list, including what is deliberately not gathered.
- The endpoint list and endpoint health — what
stalemeans and the ordinary reasons for it.