Linux
DIY Linux Router - Part 8 - Backup
This is the eighth part of a multi-part series describing how to build your own Linux router.
- Part 1: Initial Setup
- Part 2: Network and Internet
- Part 3: Users, Security, and Firewall
- Part 4: Podman and Unbound
- Part 5: Wi-Fi
- Part 6: Nextcloud and Jellyfin
- Part 7: File Sharing
- Impermanence Storage
In the previous parts, we installed the operating system, configured the gateway's internet functionality using PPPoE, set up a DNS server with Unbound, and deployed services like Jellyfin, Nextcloud, and a file server. Now, let’s establish a reliable backup routine.
Backup
Table of Contents
Introduction
It’s quite impressive how much can be achieved with this otherwise retired Mac Mini. However, all your efforts could be in vain if something happens to your data. Important services like File Server, Nextcloud, and Jellyfin could mean losing cherished memories like travel photos, newborn pictures, or critical documents. Having a solid backup routine is essential to ensure your data is safe.
Let’s clarify an important distinction: Backup is not the same as RAID. While RAID-1, for instance, provides real-time disk mirroring to prevent data loss from a single disk failure, it doesn’t address broader issues like:
- Data corruption
- Catastrophic operating system failure
- Electrical failure damaging all storage devices
- Malware or viruses
- Security breaches leading to data loss
RAID alone won’t protect against these threats. External backup routines are critical to ensure data preservation in these scenarios. A good backup solution should follow these principles:
- Regularly scheduled backups.
- Data stored in at least three different locations.
- Backup devices that can be easily detached.
- Avoid keeping backup devices always connected or mounted.
Automatic Backups
Modern filesystems like ZFS and BTRFS make snapshots and backups easy. These tools enable you to:
- Take snapshots of the filesystem.
- Send those snapshots to another block device, a dataset (ZFS), or a volume (BTRFS).
- Store incremental backups in compressed files for later restoration.
This process can be manual, but automation is more practical. I’ve developed a Python script to streamline this, performing tasks such as:
- Taking snapshots of all volumes/datasets.
- Mounting the target block device, like an external HDD or NFS server.
- Sending incremental backups compressed as
gz
.
Since incremental backups can generate many files, I also wrote a restore.py
script to restore all snapshots to a target disk.
In my setup, I utilize an older LaCie NAS, which, despite being slow by today’s standards, is an excellent backup target.
Note: Backups stored on network devices can be a security risk. Ensure your backups are secure to prevent unauthorized access.
Backup Routine Plan
- Backups will run every Sunday, Tuesday, and Friday at 1:00 AM.
- The backup target is an NFS share.
- The target will only be mounted during the backup process, after which the NAS will be powered down.
Set Up Infrastructure
Configure Backup Target
I use an old LaCie-d2 NAS running Debian 12. Although it’s a 15-year-old device, it handles NFS shares reliably. The NAS is connected to the LAN network and receives its IP address via DHCP. I’ve assigned it a static lease in the Mac Mini’s DHCP server configuration.
/etc/nixos/modules/networking.nix
systemd.network = {
...
networks = {
...
"10-${lan}" = {
...
dhcpServerConfig = {
## Placeholder configuration
};
dhcpServerStaticLeases = [{
dhcpServerStaticLeaseConfig = {
Address = "10.1.78.3"; ## NAS's static IP
MACAddress = "54:42:3b:27:31:41"; ## NAS's MAC Address
};
}];
}
...
};
}
To find your NAS’s MAC address, run the command below after pinging the device:
arp -a [current IP]
Backup Routine
The Backup Daily script is publicly available on cjuniorfox’s GitHub. Retrieve the raw link and calculate its sha256
hash:
1. Extract the `sha256` Value
nix-prefetch-url https://raw.githubusercontent.com/cjuniorfox/backup-daily/main/opt/backup-daily/backup.py
Output:
path is '/nix/store/v7g4qc9dn86is33rcsgkk5z2h6sz1vq0-backup.py'
12w37f5q5hm94g4hcd7acp7d734csjzazqgj78vgqm5s5x1wd414
Copy the hash value 12w37f5q5hm94g4hcd7acp7d734csjzazqgj78vgqm5s5x1wd414
.
2. Create the `backup-daily.nix` File
Create a service to download and run the backup script.
/etc/nixos/modules/backup-daily.nix
{ config, pkgs, ... }:
let
backupScriptSource = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/cjuniorfox/backup-daily/main/opt/backup-daily/backup.py";
sha256 = "12w37f5q5hm94g4hcd7acp7d734csjzazqgj78vgqm5s5x1wd414";
};
backupDaily = pkgs.writeTextFile {
name = "backup-daily.py";
text = builtins.readFile backupScriptSource;
};
in {
systemd.services.backup-daily = {
description = "Backup ZFS Filesystem";
serviceConfig = {
Type = "oneshot";
Environment = "PATH=${pkgs.coreutils}/bin:${pkgs.util-linux}/bin:${pkgs.zfs}/bin:${pkgs.bash}/bin:${pkgs.pv}/bin:${pkgs.pigz}/bin";
ExecStart = "${pkgs.python3}/bin/python3 ${backupDaily} --fs-type=zfs --block-device 10.1.18.3:/srv/Files --mountpoint /tmp/_backup";
};
};
systemd.timers.backup-daily = {
description = "Run Backup ZFS Filesystem";
timerConfig = {
OnCalendar = "Mon,Wed,Sat 01:00:00";
Persistent = true;
};
wantedBy = [ "timers.target" ];
};
}
Parameter Overview
fs-type=zfs
: Filesystem type for the data to be backed up.--block-device
: Target device or share.--mountpoint
: Directory to mount the backup target.
Additional options include:
--options
: Mount options for backup targets like SMB credentials.--print-fs-list
: Lists volumes/datasets to be backed up without performing the backup.
Conclusion
This backup routine addresses two key needs:
- Automated backups.
- Snapshots for quick recovery.
By maintaining this routine, you greatly reduce the risk of data loss. For further protection, consider adding cloud backups or additional targets. Thank you for reading, and I hope this article helps you secure your data!
keywords: macmini • router • linux • nixos • file • backup • python • raid • sharing • file-sharing