Restore a hacked or broken server from backup

Updated November 2026

If an attacker had root, or you cannot be sure they did not, do not clean the old server. Build a fresh one from the vendor's installer, patch it, restore only your data from a backup made before the break-in, change every password and key, check it, and only then put it back online.

Do this first.

  1. Cut the hacked server off the network (provider firewall or console), but do not wipe it yet. Take a disk snapshot if your provider offers one: it is your evidence.
  2. From a clean computer, change the passwords for your hosting account, DNS registrar and backup storage.
  3. Work out roughly when the intrusion started, so you pick a backup from before it.
  4. Never restore onto the hacked system itself.

Restore or repair?

Choose the right recovery path
SituationWhat to do
Root or admin account compromised, unknown processes, rootkit suspectedRebuild and restore data (this page)
Only a website or CMS account was abusedOften a site-level clean-up: see Website hacked
Update broke the systemRoll back an update first
Disk failed or system will not boot, no attackReinstall and restore; you may restore /etc more freely
A few files deletedRecover deleted files

CISA's ransomware guide recommends rebuilding systems from pre-configured standard images where possible, restoring data from offline, encrypted backups, and taking care "not to re-infect clean systems during recovery".

1 Isolate 2 Clean backup 3 Fresh OS 4 Patch, harden 5 Restore data 6 Rotate secrets 7 Verify 8 Back online
Rebuild first, then bring back only data, then change every secret before going live.

1. Isolate and keep evidence

Block all traffic except your own IP address at the provider's firewall, or disconnect the network from the console. Keep the old disk or a snapshot of it for at least a few weeks: you may need it to learn how the attacker got in, for insurance, or for a breach report (see Personal data breach). Incident response covers evidence in more detail.

2. Pick a clean backup

Look for the first sign of the attack in logs, file dates and alerts, then choose a backup from before it. List and compare snapshots:

# restic
restic snapshots
restic diff 4e5f9b1a 9c2d7e03          # what changed between two snapshots
restic check --read-data               # read and verify all stored data

# Borg
borg list
borg check --verify-data

Backups can contain the attacker's files too, such as a web shell in an upload folder. You will scan the restored data in step 5. If the backup storage was writable from the hacked server and not append-only, treat it with extra suspicion and check it fully.

3. Install a fresh operating system

Create a new server, or reinstall from your provider's official image or the vendor's installer (check the image checksum if you download it). Use a current supported release, not the old one if it was near end of life (Is my OS supported?). Do not reuse the old disk. Keep the firewall closed to everyone except you until step 8.

4. Patch and harden before anything else

# Debian / Ubuntu
sudo apt update && sudo apt full-upgrade

# RHEL, Rocky, AlmaLinux, Fedora
sudo dnf upgrade --refresh

# Reboots the server: needed if a new kernel was installed
sudo reboot

Then set up SSH with new keys, disable password logins and add only the users you need: see SSH hardening, Server hardening and Automatic updates. Install your software (web server, PHP, database) from the distribution's repositories, using your saved package list as a guide, not a script to run blindly.

5. Restore data, not programs

Restore into a staging folder first, then copy across only what you need.

# As root. restic keeps full paths under --target
restic restore 4e5f9b1a --target /root/restore \
  --include /var/www --include /var/backups/db --include /etc

# Borg: extract writes into the current folder; paths have no leading slash
mkdir -p /root/restore && cd /root/restore
borg extract ::web1-2026-10-28T02:15:01 var/www var/backups/db etc
What to bring back after a compromise
RestoreReinstall freshDo not copy back
Site content, uploads, documents, database dumpsPackages, CMS core, plugins and themes from official sources/etc/passwd, /etc/shadow, /etc/sudoers, authorized_keys
Individual config files you have read and comparedPrograms in /usr, /bin, /optCrontabs, systemd units, /etc/ld.so.preload, shell startup files, unless reviewed line by line

Look for planted files before copying. PHP files in upload folders, recently changed files and unknown scripts are the usual signs:

find /root/restore/var/www -path '*uploads*' -name '*.php'
find /root/restore/var/www -type f -newermt '2026-10-20' | head -50
diff -ru /root/restore/etc/nginx /etc/nginx | less

Copy with a dry run first. -a keeps permissions and times; rsync's manual notes it does not include ACLs (-A), extended attributes (-X) or hard links (-H), so add those if you use them. A trailing slash on the source copies the folder's contents rather than the folder itself.

rsync -aHAX --dry-run -v /root/restore/var/www/ /var/www/
rsync -aHAX /root/restore/var/www/ /var/www/

Restore databases from the dumps (as root):

# MariaDB / MySQL
mariadb < /root/restore/var/backups/db/mariadb-all.sql

# PostgreSQL: roles first, then the database (--create makes it)
runuser -u postgres -- psql -X -d postgres < /root/restore/var/backups/db/pg-globals.sql
runuser -u postgres -- pg_restore --create -d postgres < /root/restore/var/backups/db/mydb.dump

An --all-databases dump also restores the old database users and their passwords, which you change in step 6. If the new server runs a newer MariaDB version than the old one, run sudo mariadb-upgrade afterwards. More help: Database won't start.

6. Rotate every secret

Assume the attacker copied everything that was on the old server. CISA's guide says to issue password resets for all affected systems once the rebuild is done.

The full list is in Leaked credentials.

7. Verify

sudo ss -tulpn                         # only the ports you expect
awk -F: '$3 == 0' /etc/passwd          # only root should have UID 0
sudo ls /etc/cron.* /var/spool/cron    # no unknown jobs
systemctl list-units --type=service --state=running

Run a malware scan over web folders (Malware scan) and check for persistence tricks (Find backdoors). Test the site or application from your own browser using a hosts-file entry before changing DNS.

8. Bring it back online

  1. Take a first backup of the new server, so you have a known-good starting point.
  2. Open the firewall, then switch DNS or move the IP address.
  3. Watch logs closely for two weeks: failed logins, new admin users, outbound connections (Logging and monitoring).
  4. Fix the hole the attacker used. Without that, the new server can be hacked the same way.

How to confirm it is fixed

When to call a professional

Bring in an incident response firm if personal or payment data may have been taken, if several servers or your cloud account were reached, or if you cannot find how the attacker got in. Your hosting provider can often provide snapshots, console access and a new server quickly.

Sources