Full system restore (via SFTP/SSH) - permissions discrepancies on restored files

Hello all

I’ve searched the forum and various sites and don’t believe there’s an existing conversation on this, but apologies if I’ve missed it.

TL;DR

I’m having some issues on a restore whereby the permissions for group and everyone are not correct. I have a non-root user via systemd for the backup, with AmbientCapabilities; and the same non-root user for restore, having cap_dac_override+ep cap_chown+ep on the restic binary to elevate privileges again.

The permissions snippet is:

Current files

$ ls -l /etc/systemd/system/snap*
-rw-r--r-- 1 root root  311 Oct  7  2025  snap-bare-5.mount
-rw-r--r-- 1 root root  350 Apr 11 10:06 'snap-chromium\x2dffmpeg-109.mount'
-rw-r--r-- 1 root root  326 Mar 28 10:09  snap-core18-2999.mount
-rw-r--r-- 1 root root  326 Oct  7  2025  snap-core22-2133.mount
-rw-r--r-- 1 root root  326 Mar 28 12:40  snap-core22-2411.mount
-rw-r--r-- 1 root root  326 Mar 31 08:00  snap-core24-1587.mount

Restored files

$ ls -l /resticrestore/etc/systemd/system/snap*
-rw------- 1 root root  311 Apr 18 16:50  snap-bare-5.mount
-rw------- 1 root root  350 Apr 18 16:50 'snap-chromium\x2dffmpeg-109.mount'
-rw------- 1 root root  326 Apr 18 16:50  snap-core18-2999.mount
-rw------- 1 root root  326 Apr 18 16:50  snap-core22-2133.mount
-rw------- 1 root root  326 Apr 18 16:50  snap-core22-2411.mount
-rw------- 1 root root  326 Apr 18 16:50  snap-core24-1587.mount

Update: further testing

I have mounted the snapshot and browsed the files, I can see that the files have been written with the correct permissions, so it must be the restore process that is augmenting the permissions.

$ ls -l /mnt/test/snapshots/2026-04-18T16:30:03+01:00/etc/systemd/system/snap*
-rw-r--r-- 1 root root 311 Oct  7  2025  /mnt/test/snapshots/2026-04-18T16:30:03+01:00/etc/systemd/system/snap-bare-5.mount
-rw-r--r-- 1 root root 350 Apr 11 10:06 '/mnt/test/snapshots/2026-04-18T16:30:03+01:00/etc/systemd/system/snap-chromium\x2dffmpeg-109.mount'
-rw-r--r-- 1 root root 326 Mar 28 10:09  /mnt/test/snapshots/2026-04-18T16:30:03+01:00/etc/systemd/system/snap-core18-2999.mount
-rw-r--r-- 1 root root 326 Oct  7  2025  /mnt/test/snapshots/2026-04-18T16:30:03+01:00/etc/systemd/system/snap-core22-2133.mount
-rw-r--r-- 1 root root 326 Mar 28 12:40  /mnt/test/snapshots/2026-04-18T16:30:03+01:00/etc/systemd/system/snap-core22-2411.mount
-rw-r--r-- 1 root root 326 Mar 31 08:00  /mnt/test/snapshots/2026-04-18T16:30:03+01:00/etc/systemd/system/snap-core24-1587.mount

More detailed info on my setup and the process I followed are in the original post below, but the above is essentially where I’ve got to. I’ll leave it for posterity in case it helps anyone else (especially if I can find the solution!)


Original post

My system and setup

Kubuntu 25.10 (desktop ofc)
restic 0.18.0 compiled with go1.24.4 on linux/amd64

Backing up my via SFTP/SSH to a local server:

Ubuntu Server 22.04.4 LTS
restic 0.16.4 compiled with go1.22.2 on linux/amd64

Background

I have been using restic for years to backup my $HOME, but recently decided to switch to backing up wider dirs such as /etc /home /usr/local/bin etc. as this requires backing up (reading) several root-restricted files, I followed the instructions to use a non-root user to run the backup task.

I also used this guide on the Arch wiki as a strong guide for my systemd service. One change is that I found restic unable to use the cache as the guide sets ProtectHome=read-only, so I removed that line.

In a slight change to the above, rather than having a dedicated user I’ve been using my regular desktop user, but with of course the AmbientCapabilities etc., as this enables access to the service using my SSH key.

The issues

The backup runs without issues according to journalctl and systemctl status backup.service

However, I’m trying to test the backup and am running into some issues, mainly around the permissions to read or write certain files.

I have created a dedicated (but temporary) folder to restore into at /resticrestore. The permissions on this dir are standard: 755.

  1. The command I’m using to restore (only a test portion of the backup, in this case /etc) is as follows:
    restic -r sftp:user@ip.addr.:/path/to/backup restore latest:/etc --target /resticrestore --host myhost

This enables access to the server using my user’s SSH key, but then the attempt to restore files fails completely, either with ‘permission denied’ or ‘file not found’ (on the target destination). For example:
ignoring error for /ssh/ssh_config.d: lchown /resticrestore/ssh/ssh_config.d: no such file or directory
This seems odd: if it’s complaining that the target directory doesn’t exist, I would expect that it doesn’t, as I want to restore it.

Furthermore, I notice the comment at the end:
Summary: Restored 114 / 475 files/dirs (392.945 KiB / 392.945 KiB) in 0:00

Yet when I check the directory it appears to be empty:

$ ls -la /resticrestore
total 8
drwxr-xr-x  2 root root 4096 Apr 18 12:00 .
drwxr-xr-x 22 root root 4096 Apr 18 12:00 ..
  1. Thinking that the issue was around write permissions to the directory /resticrestore (as it is indeed 755 just like / would be if I ever have to restore that), I tried to augment the command by using sudo to restore the backup. This creates problems accessing the repo, as it’s protected by an SSH key that sudo (root) doesn’t have. I don’t generally want to create an SSH key for root, hopefully for obvious reasons, and have disabled the root login anyway.

  2. Using the advice from HSteeb in this post I tried running it as a short script, owned by my current user, and temporarily elevating privileges in a manner similar to how the backup is created. The script is as follows:

#!/bin/bash
# Minimal script to restore system from restic snapshot, or components. Edit as needed.

# Set privileges for the restoring user
sudo setcap "cap_dac_override+ep cap_chown+ep"

# Load the environment variables into a locked environment
source /etc/restic/restic_$(hostname).env

# Restore specific dirs ("--path") to a defined location ("--target") from a specific host ("--host")
restic restore latest:/etc --target /resticestore --host myhost

This seems like a catch-22: I can’t restore the backup (i.e. write the system files to /resticrestore) because I’m running as a standard user, and I can’t access the backup when I run it as root due to having configured local user SSH.

I’m certain that I’m approaching this the wrong way, but I can’t figure out how I should be. Certainly, the restore process is completely different to the backup process.

Can anybody advise on how best to approach a restore in this scenario?

Many thanks!

Edit:

I may have found the solution! My implementation of HSteeb’s advice on another post (linked above) to use the setcap command, was misused – I hadn’t included the location of the restic binary in the command!

I have now updated it to:
sudo setcap "cap_dac_override+ep cap_chown+ep" /usr/bin/restic and performed the restore to /resticrestore just perfectly, with all permissions intact.

The only thing I noticed, which I wasn’t expecting, was that using the command restore latest:/etc... sent contents of /etc to my target. When I then ran the same command with restore latest:/home/myuser/testdir..., the contents of that were also dumped into my target of /resticrestore.

I now just need to satisfy myself that if I intend to do a full restore in this fashion:
restic restore latest --target / --host myhost
It will restore /etc to my new /etc, /usr to /usr etc., which in theory it should. I’m testing that now and will report back for any future interested users.

Update:

I have now completed the restore and can confirm that the ownership was restored as per the original backup files. However, one or two permissions are slightly off. I’ve checked this by running another backup, to make sure the repo is right up to date, and then restoring just these files. Here are the differences (snippet):

$ ls -l /etc/systemd/system
total 8
...
-rw-r--r-- 1 root root  311 Oct  7  2025  snap-bare-5.mount
-rw-r--r-- 1 root root  350 Apr 11 10:06 'snap-chromium\x2dffmpeg-109.mount'
-rw-r--r-- 1 root root  326 Mar 28 10:09  snap-core18-2999.mount
-rw-r--r-- 1 root root  326 Oct  7  2025  snap-core22-2133.mount
-rw-r--r-- 1 root root  326 Mar 28 12:40  snap-core22-2411.mount
-rw-r--r-- 1 root root  326 Mar 31 08:00  snap-core24-1587.mount
...

$ ls -l /resticrestore/etc/systemd/system
total 8
...
-rw------- 1 root root  311 Apr 18 16:50  snap-bare-5.mount
-rw------- 1 root root  350 Apr 18 16:50 'snap-chromium\x2dffmpeg-109.mount'
-rw------- 1 root root  326 Apr 18 16:50  snap-core18-2999.mount
-rw------- 1 root root  326 Apr 18 16:50  snap-core22-2133.mount
-rw------- 1 root root  326 Apr 18 16:50  snap-core22-2411.mount
-rw------- 1 root root  326 Apr 18 16:50  snap-core24-1587.mount
...

The ownerships of both user and group match the current version, but the permissions differ. Can anyone suggest why this might be? Is it to do with the restic binary having cap_dac_override+ep cap_chown+ep setting which prevents incorrect group and everyone permissions setting?