banshee/services-collection/services/borg/ssh/
archives
For each borg repository a server backs up to, whether it reads and the age of its newest archive, by SSH, without taking a lock.
by banshee1 installation2 versions
v2Latest
Published on October 28, 2026. One naming convention across collections; documentation completed.
borg archives, by SSH
Returns, for each borg repository a server backs up to, whether borg reads it, and the age of its newest archive, read by borg on that server over SSH. A backup that failed leaves no archive: the age grows, and says it. Three watches are offered, each one set on the probe. No secret leaves the server.
Versions
BorgBackup 1.1 to 1.4 (borg list --json). Borg 1.4 tells a wrong passphrase (52) and a missing repository (13) by their exit codes, the older ones by their message. Generic: no folder of version. Borg 2, whose borg list lists the content of an archive, is not served.
How it works
Each repository is given by its location and by the file of its passphrase on the server. The collector runs date +%z once, for the offset of the server's clock, then, for each line of borg:repositories:
BORG_PASSCOMMAND='cat /etc/borg/nas.passphrase' borg list --json --bypass-lock --last 1 'ssh://backup@nas.example/srv/borg/www' the location going as an argument, quoted apart. borg runs the passphrase command itself, without a shell, and reads the passphrase from its output: the passphrase never leaves the server, and is never written on a command line. borg answers:
{"archives": [{"name": "www-2026-10-26", "id": "…", "start": "2026-10-26T01:00:03.000000"}], "repository": {"location": "…"}, "encryption": {"mode": "repokey"}} - A repository is named by its location:
ssh://backup@nas.example/srv/borg/www. Write no password in it. statusisok;emptyfor a repository without any archive;wrong-passphrase;not-foundfor a repository that does not exist;unreadablefor any other failure (the passphrase file unreadable, the repository unreachable, borg missing). Run the same command by hand, as the SSH account, to read why. borg's exit 1, a warning, still reads the list.ageis the time since the start of the newest archive, in hours. borg writes its times in the local time of the server, without their offset: the server's offset now (date +%z) is put on them.--bypass-lockmakes borg read without writing a lock in the repository, and without waiting for a backup or aprunethat holds one. Nothing is written in the repository; borg keeps, in the account's home, what it knows of each repository (~/.config/borg/security) and its cache.
Prerequisites
- An SSH account for monitoring, without write rights in the repositories (
monitoringbelow), on the server that runs the backups, withborgin its path. - For each repository, a file that holds its passphrase alone, owned by that account, mode 0400:
install -m 0400 -o monitoring /dev/null /etc/borg/nas.passphrase
editor /etc/borg/nas.passphrase The passphrase of a borg repository opens all its data.
- For a repository reached over SSH, an SSH key of the account and its
~/.ssh/config. On a borg server, give that key a line of its own inauthorized_keys, limited to the repository and to adding:command="borg serve --append-only --restrict-to-path /srv/borg/www". Borg 1.x has no read-only mode: an append-only key cannot delete, but it can still add. - No
sudo. - The fingerprint of the server's host key, set in
protocol:ssh:fingerprint(not needed when the Security settings trust the first SSH fingerprint presented).
Variables
| Name | Label | Says | Default |
|---|---|---|---|
borg:repositories | Repositories | one line per repository: its location, a space, the path of its passphrase file | — |
Outputs
| Name | Label | Unit | Per instance |
|---|---|---|---|
status | Repository read | — | yes, per repository |
age | Age of the newest archive | h | yes, per repository |
Watches
| Name | Title | Kind | Defaults | Checked by default |
|---|---|---|---|---|
unreadable | Repository unreadable or empty | expected value, on status | critical when anything but ok | yes |
old | Newest archive too old | above a threshold, on age | warning above 30 h, critical above 54 h: a daily backup missed once, then twice | yes |
missing | Repository missing | expected instances, on status | no name given: it raises nothing until names are set on the probe | no |
Limits
- A repository that borg has never seen from this account, unencrypted, or seen at another location, makes borg ask a question nobody answers, and reads
unreadable: runborg listonce by hand, as the account, to answer it. - A passphrase file may only be an absolute path of letters, digits and
. _ / -; a location may not hold a space. - An archive made before a change of summer time reads an hour off, the offset of the server being that of now.
- The age is that of the newest archive of the whole repository: a repository shared by several hosts stays young while one of them no longer backs up.
- Whether an archive is complete, and whether the repository is sound (
borg check), is not read here. - Not checked against a borg: the options, environment and JSON are those of the borg documentation ("General", "borg list", "All about JSON").