Panellicense

Immutable JetBackup 5 backups with S3 Object Lock

Configure JetBackup 5 with AWS S3, Wasabi, or Backblaze B2 Object Lock so a compromised cPanel server cannot delete or overwrite its own offsite backups.

8 min readUpdated 2026-05-16jetbackup-5 · object-lock · immutable-backups · ransomware
schema: HowToschema: FAQPage

The 2026 ransomware playbook does not start with encrypting /home. It starts with stealing the JetBackup destination credentials out of /usr/local/jetapi/data/, deleting every offsite snapshot, and then encrypting the live data. By the time the operator notices, the backups are gone and the only restore source is whatever the attacker hasn't touched yet.

Object Lock is the answer. It tells the S3-compatible storage provider to physically refuse deletion or overwrite of an object until a retention timer expires — even from the root account, in Compliance mode. JetBackup 5 can write to a locked bucket, but the destination configuration and retention math are non-obvious. Get them wrong and the daily prune job fails forever; get them right and an attacker with full root on the cPanel box still cannot touch yesterday's backup.

How Object Lock interacts with JetBackup prune

JetBackup 5 manages its own retention. Every job run, after a successful upload, it lists the destination, identifies snapshots older than the retention window, and issues DeleteObject calls against them. That is the cycle that Object Lock blocks.

The conflict is fixable, not fundamental. Two rules:

  1. Lock period must exceed retention period plus slack. If JetBackup retains 30 days and locks for 30 days, the prune job races the lock expiry — half the time the object is still locked when JetBackup tries to delete it, the API returns AccessDenied, and the job logs a failure even though the backup itself succeeded.
  2. Storage cost is bounded by lock period, not retention. A locked object survives JetBackup's delete call and stays billable until the lock expires naturally. Plan storage capacity against the lock window, not the retention window.

The right pattern is retention < lock < retention + 7 days. JetBackup tries to delete on day 30, fails silently (or noisily, depending on settings), and the object self-deletes on day 37 when the lock expires. The S3 lifecycle isn't involved unless you add a lifecycle policy explicitly — see below.

Set up the bucket

The bucket-level config is the same shape across providers; the console paths differ.

AWS S3

In the S3 console, Create bucket. Object Lock must be enabled at creation time — there is no way to enable it on an existing bucket. Tick Enable Object Lock, acknowledge the warning, create.

Then Properties → Object Lock → Edit default retention:

  • Default retention: Enabled
  • Mode: Compliance
  • Default retention period: 37 days (matches a 30-day JetBackup retention with 7-day slack)

Bucket versioning is enabled automatically with Object Lock — that is required, leave it on. Add a lifecycle rule under Management → Lifecycle rules to permanently delete noncurrent versions after 1 day, otherwise versioning will accumulate every overwrite forever. Object Lock applies to current versions, so the lifecycle rule only cleans up superseded delete-markers and is safe.

Wasabi

Wasabi exposes Object Lock under Compliance Settings when creating a bucket. Same constraints — must be enabled at creation, cannot be added later. Set the Minimum Retention Time to 37 days; pick Conditional Hold (Wasabi's equivalent of Compliance mode).

Note Wasabi's 90-day minimum storage billing applies on top of Object Lock. A 37-day lock period still bills for 90 days minimum per object. If you are using Wasabi for immutable backups, set the lock period to 97 days and retention to 90 — you are paying for 90 days anyway, get the protection too.

Backblaze B2

B2 calls this File Lock. Create a Bucket → File Lock: Enable. Then Lifecycle Settings → Configure and set Default retention mode to Compliance with a 37-day duration.

B2 has no minimum storage period, so the bucket cost matches retention exactly. This is the cheapest immutable option for typical cPanel backup volumes.

IAM policy for the JetBackup sub-user

The destination credentials JetBackup uses must be able to PutObject and GetObject but must not be able to disable Object Lock or change the bucket's lock configuration. If the attacker grabs the JetBackup credentials, you want them to find a key that cannot weaken the bucket.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": [
        "arn:aws:s3:::acme-cpanel-immutable",
        "arn:aws:s3:::acme-cpanel-immutable/*"
      ]
    },
    {
      "Effect": "Deny",
      "Action": [
        "s3:PutObjectRetention",
        "s3:PutObjectLegalHold",
        "s3:BypassGovernanceRetention",
        "s3:PutBucketObjectLockConfiguration"
      ],
      "Resource": "*"
    }
  ]
}

The DeleteObject allow is intentional — JetBackup needs it to attempt prune even though Compliance mode will block actual deletion. Without it the daily job logs an authorisation failure on every retention pass.

Configure the JetBackup destination

In WHM open JetBackup 5 → Destinations → Create Destination → Amazon S3 (compatible). The fields match a normal S3 destination — see Configure JetBackup 5 destinations on cPanel for endpoint and region detail per provider. Two settings matter specifically for Object Lock:

  • Path-style addressing: enabled. Some providers' Object Lock endpoints reject virtual-hosted style.
  • Multipart threshold: 100 MB or higher. Each part of a multipart upload is locked individually; with a 5 MB threshold a 2 GB backup creates 400 locked parts, which inflates the bucket's ListObjectVersions response and slows down JetBackup's own prune scan.

Click Test Connection. JetBackup writes a test object, reads it back, and tries to delete it. With Compliance mode active the delete will fail — and that is the point. JetBackup 5.3+ treats this as success for the connection test, but if you see a red error containing AccessDenied: object is locked, the test is functionally passing. The destination is usable.

Attach to a backup job and verify

Attach the destination under Backup Jobs → [your job] → Destinations. Set the job's retention to 30 days (or your chosen window), keeping it strictly less than the bucket's lock period.

After the first job run, verify immutability with the AWS CLI:

aws --endpoint-url https://s3.us-east-1.amazonaws.com s3api list-object-versions \
  --bucket acme-cpanel-immutable --max-items 1

Pick an object key from the output and try to delete it as the root account:

aws s3api delete-object --bucket acme-cpanel-immutable --key <key>
# Expected: An error occurred (AccessDenied) when calling the DeleteObject operation:
# Object is locked due to compliance.

If that command succeeds, Object Lock is not active — recheck the bucket's default retention setting.

Can ransomware delete JetBackup backups protected by Object Lock?+
No. Compliance-mode Object Lock blocks DeleteObject and PutObject (overwrite) calls until the retention timer expires, even from the AWS root account. A fully compromised cPanel server with valid JetBackup credentials still cannot touch locked objects.
Why does JetBackup's daily prune job report errors after enabling Object Lock?+
JetBackup tries to delete objects past its retention window; Object Lock returns AccessDenied. Set the bucket lock period to at least 7 days longer than JetBackup retention so the object self-expires shortly after the failed delete. Logs will still show one AccessDenied per object per day until expiry — that is expected.
Does Object Lock work with all S3-compatible providers?+
AWS S3, Wasabi, Backblaze B2, and Cloudflare R2 support it. MinIO supports it from RELEASE.2020-08-13 onward. DigitalOcean Spaces and most older S3 clones do not. Test before committing — Storj DCS in particular advertises Object Lock but has known issues with multipart uploads from JetBackup.
How much does immutable backup storage cost?+
Storage cost equals the lock period, not the retention period. A 30-day retention with 37-day lock on Backblaze B2 at $6/TB/month and 500 GB of backup data costs roughly $3.70/month — the 23% bump over standard pricing buys ransomware protection.
Can I restore from a locked bucket?+
Yes. Object Lock blocks delete and overwrite, not read. GetObject and ListObjects work normally, so JetBackup restore operations are unaffected.
What happens if I need to delete a backup early for GDPR or legal reasons?+
In Compliance mode you cannot — that is the trade. Use Governance mode and an IAM role with s3:BypassGovernanceRetention scoped to a separate human-only account; for true compliance buckets, plan retention windows you can live with.

Next steps

Switch in an afternoon

Switch from your current reseller — free.

We migrate active cPanel, Plesk, LiteSpeed and CloudLinux licenses from any reseller. We prorate the first month so you never pay twice, and your customers see zero downtime during the swap.