A backup protects against whatever it does not share a fate with. On the same disk it survives a deleted file and not a failed disk. On the same server it survives a failed disk and not a compromised account. The question is always: what does this copy share a fate with?
Three-two-one, in plain terms
- Three copies - the live one and two backups.
- Two kinds of storage - not two folders on one disk.
- One somewhere else - a different machine, ideally a different provider.
Somewhere else, in order of how much it protects
- Another disk on the same server - a failed disk, and nothing else.
- Another server at the same provider - a failed server. Not an account suspension, not a mistake made with provider-wide access.
- Another provider entirely - everything above, plus the day the account itself is the problem.
If a compromise of your server can also delete the backups, they are not a defence against a compromise. The backup destination should be write-only from the server: it can add, it cannot remove.
Write-only in practice
# object storage with an append-only policy, or\n# a pull model: the BACKUP server connects to the site and takes a copy,\n# so the site never holds credentials that can delete anything
The pull model is the strongest and the least used: nothing on the web server can reach the backups at all, so nothing that happens there can touch them.
Encrypt it, and keep the key elsewhere
gpg --symmetric --cipher-algo AES256 backup.tar.gz
A key stored only on the server that died is not a key. Write it down and keep it somewhere that has nothing to do with the server.
Test the offsite copy specifically. The local one usually works and the remote one is the one nobody has ever restored from.