# Borg Backup Server Setup for Richmond-Server This document outlines the research and recommended approach for setting up a secure Borg backup server on the NixOS host `richmond-server`. ## 1. Research Findings The core security principle for a Borg server is to use SSH with a dedicated, unprivileged user account whose command execution is strictly limited to `borg serve`. I investigated two main ways to achieve this on your server. ### Method 1: Manual NixOS Configuration (Recommended) This method involves declaratively configuring the necessary components directly within your `configuration.nix`. It leverages standard NixOS options for user management and OpenSSH, allowing for precise control and integration with the rest of your system. * **How it works**: You define a new system user (e.g., `borg-x1carbon`) and configure its SSH `authorized_keys` entry. For security, the SSH access for this user is restricted by prepending `command="borg serve --restrict-to-path /path/to/repo"` to the public key entry. This ensures that when a client connects as this user via SSH, it can *only* execute the `borg serve` command and *only* within the specified repository path. #### Pros - **Highly Secure**: Directly implements Borg's recommended security model (restricted SSH command). - **Idiomatic & Declarative**: Managed entirely within your NixOS configuration using standard options. - **Flexible**: Allows fine-grained control over user permissions and repository paths. - **Integrated**: Works seamlessly with other NixOS components like `users.users` and `services.openssh`. #### Cons - Requires manual definition of each user and their SSH keys. --- ### Method 2: Podman Container This approach involves running a community-provided Docker image (like `borgmatic/borgserver` or `nold360/borgserver`) as a Podman container on `richmond-server`. * **How it works**: You would define a `virtualisation.oci-containers.containers.` block. This would involve: 1. Pulling a suitable Borg server image from Docker Hub. 2. Mapping a host directory (e.g., `/var/lib/borg-backups`) into the container as a volume to persist the backup data. 3. Mapping a host directory containing the `authorized_keys` file into the container's SSH directory. 4. Publishing the container's SSH port (e.g., 2222) to a port on the host. #### Pros - **Encapsulated**: The Borg environment and its dependencies are isolated from the host system. - **Consistent Workflow**: Aligns with the existing use of Podman containers on `richmond-server`. #### Cons - **Increased Complexity**: Managing persistent storage and SSH keys via volumes is more complex and prone to misconfiguration. - **Manual Security**: You are responsible for ensuring the container image is secure and that the SSH key restrictions are correctly implemented inside the container. - **Less Integrated**: Does not tie into the host's user or firewall management as cleanly as the native NixOS configuration. --- ## 2. Recommendation **The Manual NixOS Configuration is the best method.** It is more secure, simpler to manage, and more robust than a container-based solution for this specific use case on a NixOS system. It perfectly embodies the declarative and security-focused principles of both NixOS and Borg. ## 3. Example Configuration for `richmond-server` Here is a proposed configuration snippet that you would add to `hosts/richmond-server/configuration.nix`. This example sets up a repository for a hypothetical client named `x1carbon-laptop`. ```nix { config, pkgs, lib, ... }: { # ... existing configuration ... # Borg Backup Server Configuration # Create a dedicated system user for Borg backups users.users.borg-x1carbon = { isSystemUser = true; group = "borg-x1carbon"; home = "/var/lib/borgbackup/x1carbon-main-backup"; # Home directory for this repo createHome = true; }; users.groups.borg-x1carbon = {}; # Configure OpenSSH to allow access for the borg user with restricted commands services.openssh.enable = true; # Ensure OpenSSH is enabled services.openssh.authorizedKeys.keys = { "borg-x1carbon" = [ # IMPORTANT: Replace this with the actual public SSH key from your x1carbon laptop. # The 'command' option restricts this key to only execute Borg serve commands. "command=\"/run/current-system/sw/bin/borg serve --restrict-to-path /var/lib/borgbackup/x1carbon-main-backup\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICyour_clients_public_key_here user@x1carbon" ]; }; # Ensure the base directory for backups exists and has correct permissions systemd.tmpfiles.rules = [ "d /var/lib/borgbackup 0700 root root -" ]; # Borg uses SSH, so ensure the SSH port is open in your firewall. # This is likely already enabled on your server. networking.firewall.allowedTCPPorts = [ 22 ]; # ... rest of your configuration ... } ``` ## 4. Helpful Links - [**BorgBackup Official Documentation - Usage with SSH**](https://borgbackup.readthedocs.io/en/stable/usage/ssh.html) - [**NixOS Wiki on BorgBackup**](https://nixos.wiki/wiki/BorgBackup) - [**NixOS `users.users` Options**](https://search.nixos.org/options?channel=unstable&show=users.users&from=0&size=50&sort=relevance&type=packages&query=users.users) - [**NixOS `services.openssh` Options**](https://search.nixos.org/options?channel=unstable&show=services.openssh&from=0&size=50&sort=relevance&type=packages&query=services.openssh)