Back to articles
Technology Insight

Building an Immutable Backup System Against Ransomware for VPS Using BorgBackup and Cloudflare R2 Append-Only

May 30, 2026

The Escalating Threat of Ransomware on Modern Infrastructure

In the contemporary digital landscape, ransomware has evolved from a disruptive nuisance into a sophisticated, multi-million-dollar cybercrime industry. Modern malicious actors no longer settle for merely encrypting live production databases on your Virtual Private Servers (VPS). They actively hunt down connected storage mounts, API keys, and automated backup repositories. If your backup system relies on traditional protocols like standard FTP, SSH/SFTP, or basic object storage credentials with full write/delete permissions, a compromised VPS means your safety nets are instantly erased.

To survive a targeted attack, enterprise IT infrastructure must shift toward a Zero-Trust Architecture. The ultimate line of defense in this paradigm is Immutability. An immutable backup is a data record that, once written, cannot be modified, overwritten, or deleted by any user or application for a predetermined retention period—not even by the root administrator account that created it. This blog post provides an engineering blueprint to construct a highly resilient, cost-effective immutable backup pipeline for your VPS by combining two industry-leading technologies: BorgBackup and Cloudflare R2 Object Storage configured with Append-Only restrictions.

Understanding the Core Components

Before diving into the technical implementation, it is vital to understand why the symbiosis of BorgBackup and Cloudflare R2 provides such an impenetrable shield against data extortion.

1. BorgBackup: Deduplication and Client-Side Security

BorgBackup (commonly known as Borg) is a premier, open-source deduplicating backup solution. Unlike primitive backup tools, Borg operates on a content-defined chunking algorithm. It splits files into variable-length chunks, ensuring that only modified blocks are transmitted and stored. This introduces several critical benefits:

  • Space Efficiency: Daily backups require minimal incremental storage, drastically reducing data transfer costs.
  • Authenticated Encryption: All data is encrypted on the client side (your VPS) using 256-bit AES encryption before it leaves the server. The storage provider never sees your plaintext data.
  • Speed: Local chunk caching ensures that subsequent backup routines execute in a matter of minutes or seconds.

2. Cloudflare R2 & The Power of Append-Only Buckets

Cloudflare R2 is an S3-compatible object storage service distinguished by its complete elimination of egress bandwidth fees. While standard object storage is vulnerable if an attacker steals the access keys, R2 supports granular AWS Identity and Access Management (IAM) style policies. By generating an API token restricted strictly to PutObject and GetObject actions—explicitly omitting DeleteObject and PutObjectRetention—we create an Append-Only gateway. Even if a malicious actor gains root access to your VPS and extracts the R2 API keys, they lack the cryptographic authorization to delete historical archives or modify existing backup blocks.

Architecting the Immutable Backup Pipeline

To successfully integrate these tools, the backup pipeline must be structured to isolate state and limit privilege. Below is the step-by-step engineering implementation matrix.

Step 1: Preparing Cloudflare R2 Storage

First, log into your Cloudflare Dashboard, navigate to the R2 section, and create a new bucket dedicated strictly to your VPS backups (e.g., vps-immutable-backup-repo). Once the bucket is provisioned, you must generate restricted API credentials:

  1. Navigate to Manage R2 API Tokens and click Create API Token.
  2. Select Custom Read/Write Permission.
  3. Under the permissions matrix, explicitly assign Read and Write capabilities to the specific bucket, but ensure that Edit/Delete controls are strictly disabled. Alternatively, apply a scoped JSON policy that restricts actions exclusively to s3:PutObject, s3:GetObject, and s3:ListBucket.
  4. Save the generated Access Key ID, Secret Access Key, and the S3 Endpoint URL safely. Remember, these keys will have zero authority to purge data.

Step 2: Installing and Initializing BorgBackup on the VPS

Log into your VPS via SSH and install BorgBackup along with the necessary standard utility packages. On Debian/Ubuntu-based distributions, execute the following commands:

sudo apt update && sudo apt install borgbackup rclone -y

Because Borg natively saves backups to local or SSH-based directories, we utilize rclone as a highly efficient, transparent bridge to mount or sync Borg repositories directly to Cloudflare R2. Configure rclone by executing rclone config, mapping a new remote named cloudflare_r2 using the S3-compatible storage type, and inserting your R2 credentials.

Next, initialize your local encrypted Borg repository. Choose a secure, high-entropy passphrase to protect the encryption keys:

borg init --encryption=repokey-blake2 /var/backup/borg-repo

Critical Security Note: Always export your Borg repository keys and passphrases to an external, offline location (such as a hardware security module or physical safe). If your VPS is completely destroyed, the backup data on R2 cannot be recovered without this repository key.

Automating the Execution and Synchronization

To achieve automation, we write a robust shell script that orchestrates the Borg creation process and synchronizes the state to Cloudflare R2. This script should be placed within a root-restricted directory, such as /usr/local/bin/backup.sh.


#!/bin/bash
# Automated Immutable Backup Script
set -e

export BORG_PASSPHRASE="your_secure_borg_passphrase_here"
REPO_DIR="/var/backup/borg-repo"

echo "Starting BorgBackup archive creation..."
borg create --stats --progress $REPO_DIR::"vps-archive-{now:%Y-%m-%d-%H%M%S}" /var/www /etc /var/log

echo "Synchronizing new chunks to Cloudflare R2 Append-Only Storage..."
rclone sync $REPO_DIR cloudflare_r2:vps-immutable-backup-repo --immutable

echo "Backup routine successfully executed."

Notice the inclusion of the --immutable flag in the rclone command line. This directive instructs rclone to strictly upload new data blocks and completely refrain from attempting any remote file deletions or modifications, complementing the bucket-level security policies established in Cloudflare R2.

The Append-Only Conundrum: Handling Retention Safely

A completely unalterable system introduces a distinct operational challenge: Storage Growth. Over time, outdated backups will accumulate, inflating storage costs. Standard Borg commands like borg prune work by actively deleting old chunks from the repository. In a true append-only architecture, running borg prune directly from the VPS will fail because the Cloudflare R2 API token lacks the deletion permission.

To solve this elegantly without breaking your ransomware defenses, implement a Split-Credential Lifecycle Management Strategy:

  • The VPS (Untrusted Zone): Holds only the Append-Only keys. It can create data but can never destroy it. If compromised, the attacker cannot delete history.
  • The Lifecycle Layer (Trusted Administrative Zone): Utilize Cloudflare R2’s native Object Lifecycle Management policies configured directly within the Cloudflare dashboard. By defining a rule such as "Automatically expire and delete objects with prefixes older than 90 days", Cloudflare handles the retirement of stale blocks internally. The deletion authority never exists on your vulnerable production VPS.

Disaster Recovery Protocol

An immutable backup architecture is only as good as its recovery performance. In the event of a catastrophic ransomware attack where your VPS is compromised or completely wiped, execute the following emergency restoration matrix:

  1. Provision a Clean Environment: Instantly deploy a completely fresh VPS instance with an untainted OS installation.
  2. Isolate and Auditing: Ensure old security groups are audited so the vector used by the attacker is entirely closed.
  3. Pull the Immutable Archives: Configure rclone on the new server using a Read-Only or Full-Access credential to pull down the uncorrupted Borg repository from Cloudflare R2 to a local staging path.
  4. Decrypt and Extract: Input your off-site repository key and passphrase to mount the Borg archive, then extract your production web roots, databases, and system configurations:
borg extract /var/backup/borg-repo::vps-archive-[TIMESTAMP]

Conclusion

Defeating ransomware requires moving past outdated security paradigms. Relying on simple automated snapshotting tools that live within the same ecosystem or interface as your production servers leaves your enterprise vulnerable. By decentralizing your data defense mechanism—coupling BorgBackup's client-side cryptographic deduplication with Cloudflare R2's infrastructure-enforced Append-Only tokens—you effectively neutralize a ransomware operator's primary leverage: the destruction of your backups. Implement this architecture today to ensure your corporate data assets remain resilient, compliant, and rapidly retrievable under any circumstances.

Building an Immutable Backup System Against Ransomware for VPS Using BorgBackup and Cloudflare R2 Append-Only | DPTCloud