Australian cloud for business software — built and run in Sydney since 2003

NetLeverage
NetLeverage

Immutable Backup Repositories on Linux: Hardened Design, Attributes, Credentials and Limits

Technical article
Backup & Recovery

About this article: AI-assisted writing, reviewed against the cited sources. This is source research, not a lab validation of the procedures. Check the stated versions and your own recovery requirements before making changes.

An immutable repository is only as strong as the account or system that can lift the lock. On Linux, the i attribute stops root from changing a file, but root can usually clear the attribute first. Real protection comes from making sure no credential reachable from production can get to the process, the host or the storage that holds that power.

Identifiers are examples. Validate retention changes on a disposable repository before deployment.

Interpretations are editorial; no lab testing was performed.

Why it matters

The current Australian Information Security Manual, dated September 2026, addresses this directly. ISM-2151 and ISM-2152 first appear with that update, and ISM-1708 was last updated in December 2023:

  • ISM-1708: backup administrator accounts are prevented from modifying and deleting backups during their retention period. It is tagged Essential Eight Maturity Level 3.
  • ISM-2151: backups are stored using a technically enforced immutability mechanism that prevents their modification or deletion for the duration of their retention period.
  • ISM-2152: backup infrastructure, including backup servers, repositories and management consoles, is segregated from production and uses a separate authentication mechanism for administrative access.

Shared administrative credentials can expose backups and production to one compromise.

How it works

What the kernel enforces

Two inode flags matter, both set with chattr and read with lsattr:

lsattr /srv/backup/2026-11-10.full

This query inspects flags only. Choosing when to lock or unlock a real backup is a retention operation that belongs to the validated repository implementation.

The important part is who can change the flag. Setting or clearing either one needs CAP_LINUX_IMMUTABLE. A normal root shell has that capability, so chattr -i followed by rm works. The flag blocks accidents and processes without the capability. It does not, on its own, stop an attacker who has full root.

The flag also lives inside the filesystem. Anyone who can write to the block device, reformat the volume, delete the virtual disk or destroy the storage array goes around it completely.

Removing the capability from a service

A service that receives backups does not need to change these flags. systemd can remove the capability from its bounding set:

The design should specify an unprivileged receiver identity, no privilege escalation, removal of the immutable-flag capability and protection against changing the clock. A systemd policy can express those restrictions, but the exact unit must be checked against its required storage, network and service-manager access before deployment.

A drop-in takes effect only after systemctl daemon-reload and a restart of the service.

The bounding set limits the capabilities a process can gain at execve, so an exploited receiver cannot regain this one through a set-user-ID program. ProtectClock=yes denies writes to the system and hardware clocks from that unit.

This limits that service only, and it needs the User= line. A receiver still running as root could write a unit or cron entry, or ask PID 1 to start something with full capabilities, and that new process sits outside the limit. A root login arriving through another route has its own capabilities too.

Who sets and clears the flag

This is the central design question of a self-built repository, and the flag alone does not answer it. systemd can drop a capability for the whole host, since CapabilityBoundingSet= in system.conf applies to PID 1 and its children, and capabilities dropped there are lost for good. But setting a flag needs the same capability as clearing it, so a host-wide drop leaves nothing able to lock new files or release expired ones.

A workable design needs a deliberate answer to three questions:

  • Which process sets the flag? A small local service, separate from the receiver and not listening on the network, that alone holds CAP_LINUX_IMMUTABLE.
  • Which process clears it at expiry? The same service, working from an expiry date it holds itself and a client cannot edit.
  • How is that service protected? Anyone who gains root on the host can reach the capability, so the protection is closing the routes to root: no shared logins, console access controlled and logged off the host.

Kernel lockdown is a useful companion, but it solves a different problem. It restricts access to the running kernel image, including /dev/mem, and unsigned modules. Nothing in that page says it restricts chattr.

Two-process design

Veeam's hardened repository shows the pattern clearly, and the same separation applies to a design of your own. Two services divide the work:

  • The transport service talks to the backup server on port 6162 and runs as a non-root user.
  • The immutability service runs with root permissions, as a child process of the Veeam Data Mover Service. It checks attributes every 20 minutes and sets or removes the immutable flag.

Only child processes of the Data Mover or Transport service can run under root on the repository. So the separation is one of privilege within a single vendor service tree, not two unrelated programs. That compromising the network-facing service is not meant to deliver the lock service is our inference from the design. Veeam states the design prevents deletion even if the transport service is exploited or the NTP server compromised, which is the vendor's claim, not something tested here. A design of your own can borrow the pattern, with the same qualification.

Single-use credentials, used once to deploy the data mover and never stored, mean a compromised backup server does not hold a login to the repository. Veeam's appliance form uses certificate-based authentication and SSH cannot be used.

Practical design

Storage

Veeam's requirements are a reasonable reference even if you build something else. It asks for block storage with a filesystem that supports immutable files and extended attributes, and rules out NFS and SMB. It recommends XFS for its block cloning. Check your filesystem before relying on the flags, because not all are supported by all filesystems.

The two deployment types differ. A manually configured Linux server may use local or remotely attached block storage, and Veeam's note says to use a physical machine with local storage to reduce the attack surface. The reason follows from the limit above. On a virtual machine, whoever administers the hypervisor can delete the disk without touching Linux. The Veeam Infrastructure Appliance attaches local, iSCSI or Fibre Channel storage, and it is strongly recommended to disable its Host Management console Web UI. Multi-factor authentication cannot be disabled on appliances without Security Officer accounts. Where those accounts are enabled, the default one must be initialised before the repository is added.

Access

ISM-2152 asks for segregation and separate administrative authentication across the backup servers, repositories and consoles, not only the repository. Our recommendations for a self-built Linux host:

Clock

Time-based immutability trusts the clock. If an attacker can move it forward, retention expires early.

Veeam compares system time, hardware time and elapsed intervals. If the detected shift exceeds 86,400 seconds (24 hours), retention operations are blocked. In a blocked state, the service neither sets nor removes the immutable attribute for existing and new files. Veeam says the hardware clock should be set to UTC, and that if it is disabled only one of the two comparisons runs. A shift under the threshold is not blocked (our reasoning from that figure).

For a self-built host, use several time sources. chrony's minsources defaults to 1, and raising it requires agreement between sources before the clock is updated. maxchange refuses large offsets and eventually makes chronyd give up and exit, leaving the clock unmanaged, so alert on that. The nts option authenticates the time sources. These settings guard against bad network time only. They do nothing against root on the host.

minsources 2
maxchange 1000 1 2

Those are illustrative values, and maxchange 1000 1 2 is the example from the manual.

A planned outage has a side effect. Shutting a Veeam repository down for more than 24 hours blocks retention operations, and an administrator must reset the protection. On a manually configured server that needs the account with root privileges, which conflicts with a host that has no login path unless a console route was planned.

Retention and capacity

Immutable data cannot be cleaned up early, so the wrong settings fill the disk with data you are unable to remove.

Several details from Veeam 13 matter when sizing:

  • The period is at least 7 days and at most 9999.
  • The count starts from the last restore point in the active chain, and is extended across that chain. With a 10-day period, a full created on 12 January followed by increments to 14 January stays locked until 24 January.
  • GFS lifetime is the largest driver. Veeam sets the immutability of a GFS full to the longer of the two periods. Its example has a 10-day repository period and a 3-year GFS lifetime, and "the backup file will be immutable for 3 years". Size for that, not for the repository's period.
  • Immutability overrides job retention, so a shorter job retention does not free space early.
  • Only forward incremental with active or synthetic full is allowed, since a locked file can be merged or deleted only after expiry. Reverse and forever forward incremental cannot be selected. For backup copy jobs, immutability needs the GFS retention policy.
  • Decreasing the period does not release existing files. In Veeam's example a change from 20 to 7 days leaves the active chain locked until its original date, and only later backups get the shorter period.

Long chains also keep their first full locked for much longer than the configured period (our arithmetic from the example above).

Set the period longer than your realistic time to detect a compromise. A lock that expires before anyone notices protects nothing.

Not everything can be locked

Veeam states that .VBM metadata files cannot be immutable, because they change on every job, and that imports should use VBK files. An immutability flag is also set only when the backup session completes, so a session that fails stays unlocked until a later run applies the flag. Per-machine formats flag the files created successfully, while a single-file backup with an incomplete restore point is not flagged. If the next run creates a new full, Veeam says those files are not locked automatically and points to the Set-VBRImmutabilityLockExpirationDate cmdlet.

Log backups behave differently again. Their period is not extended across the chain, so an active log chain can expire and leave a gap unless the period covers it.

Append-only software

Open-source tools use a different model: the server refuses deletes from the client.

rest-server for restic. --append-only allows new backups but stops deletion and modification of existing ones.

Borg. A forced command restricts a client key on the server. This authorized_keys line combines the append-only form with the restrict option from Borg's documentation:

command="borg serve --append-only ...",restrict ssh-rsa <client-key>

The restrict option needs OpenSSH 7.2 or later.

Both have serious conditions:

These protect against a compromised client. They do not protect against a compromised repository server, where the files are ordinary files.

Object storage

S3-compatible Object Lock enforces retention through the storage API, so it does not depend on a Linux host you administer.

On Amazon S3:

Mode Who can remove protection early
Governance Users with s3:BypassGovernanceRetention, sending the bypass header
Compliance No user, including the root user. The only early route is deleting the AWS account

Governance mode is a test setting for this purpose, because a stolen privileged credential can bypass it. The S3 console includes the bypass header by default, so a delete by a permitted user simply succeeds.

Details that surprise people:

  • Object Lock requires versioning, and once enabled on a bucket it cannot be disabled, nor versioning suspended.
  • A lock protects a version, and does not stop new versions or delete markers. An object can appear gone while the locked version remains, so restore tools must read versions.
  • Lifecycle rules still run, but expiry cannot delete a locked version.
  • Compliance mode is hard to undo. A retention set in error cannot be shortened, so AWS suggests testing in governance mode first.
  • A lock does not protect the keys. AWS says Object Lock "does not protect against losing access to the encryption keys or encryption keys being deleted", and that deleted KMS keys may leave objects unreadable. An attacker who destroys the key defeats compliance mode without touching it, so hold keys under the same separation as the lock.
  • A legal hold gives the same protection with no expiry, and anyone with s3:PutObjectLegalHold can remove it. Variable retention sets the date when you release an event hold, and AWS suggests it for "a configurable recovery window against ransomware".

MinIO AIStor documents the same two modes. On any self-hosted store, compliance mode is still subject to whoever controls the disks underneath.

What to choose and why

The following are our recommendations:

Situation Sensible first choice
Veeam on-premises Hardened repository on a physical host, separate credentials
Open-source tools, trusted server Append-only server plus administration from a separate host
Need protection from your own administrators Object Lock in compliance mode, with a different account owner
Strongest position One local immutable copy for speed, and one held under separate administration

How each option maps to the ISM, as our assessment rather than ASD's ruling. An assessor decides in the end.

Option ISM-1708 and ISM-2151 ISM-2152
chattr with root administrators Not met by itself. An administrator can clear the flag Depends on the host's design
Veeam hardened repository Intended to meet both, if backup administrators hold no root on it Needs the server and console segregated too
Append-only server, administered separately Doubtful. It restricts clients, and the server's files stay ordinary files Depends on the host's design
Object Lock, governance Not met if backup administrators hold the bypass permission Separate account needed
Object Lock, compliance Can support both for retained versions; complete coverage, keys and restore access still need assessment Separate administration needed

Separation of administration matters more than the mechanism. If one person or one identity provider can reach both the production platform and the storage layer below the repository, a single compromise reaches both.

Risks and limits

These are our assessments, drawn from the limits above.

  • Immutable does not mean clean. A lock preserves whatever was written, including encrypted files or backdoored systems. Test restores and keep enough history to go back before the intrusion.
  • Immutable does not mean readable. Locks do not detect corruption. Verify integrity on a schedule.
  • The lock window is a countdown. Backups stopped for longer than the period become deletable, so alert on missed runs.
  • Capacity is a denial-of-service path. Filling the repository with junk that cannot be removed can stop new backups. Alert on unusual growth.
  • Do not set long compliance retention to "be safe". You will pay for storage you cannot remove.
  • Not covered: tape and offline media, encryption key management in detail, and vendor-specific object storage integrations.

Sources

Opened 2026-11-10.