Encryption protects the data contents, but the transport and backend still have gaps: leaked credentials, non-TLS paths, or ransomware deleting snapshots. This episode secures the transport (SFTP/HTTPS, S3 TLS, firewall) and applies immutability with bucket object lock and an `--append-only` repo for anti-ransomware defense.

Episode 13 secured the contents of the data. This episode secures the path and storage location. Strong encryption is useless if credentials are sent in plaintext, or if ransomware succeeds in deleting the entire snapshot history.
The three layers we build: encrypted transport, a restricting firewall, and immutable storage — untouchable even by an admin.
The SFTP backend runs over SSH — all traffic is encrypted from the start. Unlike older rsync versions that could run over a plaintext rsync:// without an SSH layer. The rule is simple: backup data must never cross the network without transport-layer encryption, whatever application-layer encryption from episode 13 already does.
https:// endpoint — for MinIO make sure TLS is enabled on the server side.--tls.A quick check whether the connection is encrypted:
restic -r s3:https://minio.example.com/bucket snapshots
restic -r rest:https://backup.example.com/repo snapshotsIf an http:// endpoint is used and restic does not complain, you are sending credentials and blobs over plaintext.
Warning
Beware man-in-the-middle: restic verifies TLS certificates by default. Don't set -o rest.tls.insecure=true or --insecure-tls except for a brief local test — and understand that it disables the protection.
Basic rules for backup backends:
443/8000 only to the legitimate host IPs.sshd_config with AllowUsers backup and a forced command so the user can only run restic.Match User restic-backup
ForceCommand restic -r sftp:/srv/backup --backend-sftp-restore-relevant
AllowAgentForwarding no
AllowTcpForwarding noForceCommand forces that user to run only the allowed command — minimizing the attack surface if credentials leak.
Ransomware encrypts files, then deletes or overwrites backups so victims cannot recover. Two immutability mechanisms:
When a client connects to a rest-server running with --append-only, it can only add — it cannot delete or overwrite. Even an infected host cannot poison the history:
ExecStart=/usr/local/bin/rest-server --path /srv/restic --append-onlyThe trade-off: restic forget and prune cannot be run from an append-only client. Run maintenance (forget/prune) from a separate machine with direct server access.
For S3-compatible storage that supports it (AWS S3, MinIO, B2), enable object lock / WORM at the bucket level. Every object has a Compliance or Governance retention — data cannot be deleted before the retention period expires:
mc mb minio/backup-bucket --with-lock
mc retention set compliance 180d minio/backup-bucketCompliance retention even refuses deletion by root — full anti-ransomware power.
Tip
The ideal combination: append-only to prevent modification, object lock to prevent deletion, and a second repo in a different physical location as the last resort. A backup that an attacker can delete is not a backup.
tls.insecure without a strong reason.ForceCommand narrows the surface.--append-only prevents clients from deleting/overwriting — separate maintenance.In the next episode, episode 15, we apply defense at multi-team scale: hardening & multi-tenant — one repository per tenant, one key per repo, credential isolation, least-privilege storage, and periodic access audits.