Duplicati as a service - more complicate than it need be

Interesting! So you are saying it is possible to create a file that is not readable from the snapshot?

Did you use an admin account to create the snapshot, and then another account to read it?
When I tested it, I used the same account to create the snapshot and read it, and it would always get full access. I did not try to specifically deny anyone access, but just accessed things from the standard users (which are not shared).

I don’t understand the question. My Duplicati.GUI.TrayIcon.exe backup made and tried to read.
This was all done as an Administrator account which is elevated at manual start and UAC like

I have not tested a lot of combinations, but the above gets me into Admnistrators group as.

image

I also think the VSS snapshots honor ACLs just like the live filesystem. Backup programs usually utilize SeBackupPrivilege to bypass ACL checking. If the user running Duplicati is a member of Administrators or Backup Operators, it has the ability to get this privilege token. (This is in a default Windows configuration. Technically any user can be granted the ability to get this privilege token if you edit the Local Security Policy.)

Use SeBackupPrivilege on Windows #4471 is in the Duplicati pull request queue.

1 Like

Arh, that was the confusion. It looks like a user that can run VSS gets the SeBackupPrivilege by default (cannot find definitive docs stating it). But it makes sense to separate the two, and allow toggling VSS and SeBackupPrivilege individually.

I think this would make it possible to have a service with elevated privileges that can create/remove VSS snapshots, and then allow Duplicati to run with the current user privileges to perform the backup, optionally toggling SeBackupPrivilege to grant the user extra privileges.

Maybe you’re already doing this, but

The commands whoami /priv and whoami /groups are useful for examining.

A non-elevated user set up as an Administrator in settings does not get this.
They also do can’t run VSS, getting

Failed to create a snapshot: Attempted to perform an unauthorized operation.

The same user, elevated, seems like they do get SeBackupPrivilege to enable:

C:\>whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                            Description                                                        State
========================================= ================================================================== ========
SeIncreaseQuotaPrivilege                  Adjust memory quotas for a process                                 Disabled
SeSecurityPrivilege                       Manage auditing and security log                                   Disabled
SeTakeOwnershipPrivilege                  Take ownership of files or other objects                           Disabled
SeLoadDriverPrivilege                     Load and unload device drivers                                     Disabled
SeSystemProfilePrivilege                  Profile system performance                                         Disabled
SeSystemtimePrivilege                     Change the system time                                             Disabled
SeProfileSingleProcessPrivilege           Profile single process                                             Disabled
SeIncreaseBasePriorityPrivilege           Increase scheduling priority                                       Disabled
SeCreatePagefilePrivilege                 Create a pagefile                                                  Disabled
SeBackupPrivilege                         Back up files and directories                                      Disabled
SeRestorePrivilege                        Restore files and directories                                      Disabled
SeShutdownPrivilege                       Shut down the system                                               Disabled
SeDebugPrivilege                          Debug programs                                                     Disabled
SeSystemEnvironmentPrivilege              Modify firmware environment values                                 Disabled
SeChangeNotifyPrivilege                   Bypass traverse checking                                           Enabled
SeRemoteShutdownPrivilege                 Force shutdown from a remote system                                Disabled
SeUndockPrivilege                         Remove computer from docking station                               Disabled
SeManageVolumePrivilege                   Perform volume maintenance tasks                                   Disabled
SeImpersonatePrivilege                    Impersonate a client after authentication                          Enabled
SeCreateGlobalPrivilege                   Create global objects                                              Enabled
SeIncreaseWorkingSetPrivilege             Increase a process working set                                     Disabled
SeTimeZonePrivilege                       Change the time zone                                               Disabled
SeCreateSymbolicLinkPrivilege             Create symbolic links                                              Disabled
SeDelegateSessionUserImpersonatePrivilege Obtain an impersonation token for another user in the same session Disabled

C:\>

Ok, that fits my investigations. On a default system, a user that has VSS create privileges also has SeBackupPrivilege (maybe it can be adjusted with policies).

Technically they only have the privilege when the token is enabled (it’s disabled by default). A program has to use the AdjustTokenPrivileges API to enable the privilege.

The State column on the right of my whoami /priv shows the Disabled (most) or Enabled (few) state.
Sorry for the wide line. You need to use the scrollbar to see.

Duplicati includes functionality to execute arbitrary scripts before/after backup job execution. The web GUI reduces overall system security by requiring a single password; it would be preferable to authenticate using a Windows credential.
Unfortunately, the Duplicati-as-a-Windows-Service deployment model is not mature yet.

Welcome to the forum @sergethedev17

First note that Duplicati is cross-platform, so GUI authentication also needs to be.

Having said that, are you enough of a Windows expert to expand on your thought?
Things are partly not mature due to lack of Windows devs, and devs in general…

Even if it’s possible to authenticate with OS credential, can one change process?
I’m used to the idea of Windows Services launching as some preconfigured user.
I don’t know if it can change users as easily as UNIX can, .e.g. setuid and friends.

Hi @ts678 , good to be here :slight_smile: .
Yes, I understand the cross-platform requirement; it is a great feature and makes this product appealing to a much broader audience. I don’t want to suggest any changes that diminish cross-platform functionality.

Web GUI logon
OS-backed authentication can improve security significantly: the OS supports comprehenstive password and account-lockout policies; authentication attempts are logged centrally; users don’t need to memorise yet another password. Many users do not regard this functionality as essential (and many users probably don’t have a password on the web GUI altogether!). In Windows we can use OS API calls to validate user credentials. In Linux, similarly, we can validate against the Linux PAM authentication modules.
For avoidance of doubt, the web GUI authentication should be used only to control access to the web GUI. We do not suggest to use these credentials to execute any backup jobs (Duplicati already has functionality to access network resources using credentials stored in the job configuration).

Windows Service user accounts

Let’s return to the Windows Service. On Windows, services typically run under one of the following accounts:

  • LocalSystem - highly privileged account that can manage the computer; it has a swath of privileges, including SeBackupPrivilege, SeRestorePrivilege (both disabled initially). On the network, the computer authenticates as itself (relevant for Windows AD).
  • LocalService - basically a ‘user-level’ account for services. Conceptually, it is similar to a Linux account with /sbin/nologin shell (ie users cannot login). On the network, the computer acts as an anonymous user (relevant for Windows AD).
  • NetworkService - same as LocalService, but on the network the computer authenticates as itself.

(See Service User Accounts)
The above accounts are machine-local. Windows AD also offers managed service accounts (MSA) that are intended for use by services (no interactive logon) and are installed on a Windows machine. Applications/services would use MSA accounts in the same way as regular accounts.

Of course, users can also configure a Windows Service to use a regular account of their choosing.

How do we use the above security model to assign different permissions to Service A and Service B? We use virtual accounts. A virtual account is essentially a sub-account of NetworkService, and can be created on-the-fly. In the Services snap-in:

  1. Open properties for any service, go to the Logon tab.
  2. Select This account radio button and enter NT Service\MyNewAccountName, leave the password field blank, and press OK.

We can then edit resource ACLs to give our service the necessary permissions.

Screenshots in PR#4471 show the application running as NT Service\Duplicati and that we added NT Service\Duplicati to the Backup Operators security group to give it the relevant privileges.

Robust software applications often use the virtual NetworkService accounts. For example, by default the Microsoft SQL Server service runs as NT Service\MSSQLSERVER, and the installer restricts access to important directories to this user (eg C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA).

On Windows, Duplicati stores configuration in the %LOCALAPPDATA% directory. When Duplicati runs a logged on user, this is typically C:\Users\USERNAME\AppData\Local\Duplicati. If we run the Duplicati service as NT Service\Duplicati, then %LOCALAPPDATA% will resolve to C:\Windows\ServiceProfiles\duplicati\AppData\Local\Duplicati.

What improvements are desired for running Duplicati as a service?

Functional

  1. Duplicati service should (try to) access local files using SeBackupPrivilege/SeRestorePrivilege with the correct file IO semantics (eg Alphaleonis.Win32.Filesystem.File.OpenBackupRead).

Installer

  1. It would be nice to have a simple forms-based UI to manage service install/uninstall (eg add forms to Duplicati.WindowsService.exe).
  2. By default, the service installation process should configure the Windows Service to logon as NT Service\Duplicati.
  3. By default, the service installaiton process should add the service user account to the Backup Operators security group.

User interface (web GUI)

  1. GUI should show more prominently the user context under which the application is running (currently visible on System info tab, 17 lines into System properties). On Windows, we should show the full account name in Domain\User format (currently, when service runs as NT Service\Duplicati, the System properties reads: UserName : duplicati).
  2. GUI should show the location of the data folder being used (can be specified using the --server-datafolder parameter). This is currently not visible at all.

The OP (@jcs1167957 ) also mentioned functionality to detect when USB drives are plugged in and execute relevant jobs. This would be a great feature, but is not related to the Windows service requirement. I suggest a separate discussion about this.

With automatic detection of a USB drive, I also wanted this, having come off CrashPlan which has that feature. For my Windows 10 PC, I wrote a PowerShell script and went through the rigamarole of getting the service registered, and triggering the Duplicati backup upon detection of the correct USB drive with ‘beginning / ending’ alerts. Also, while there may be a way to obfuscate the Duplicati backup creds, I did not do that so my creds were in plain text in the script, which is obviously poor form.

It works okay once everything is setup, but having the app support this natively would obviously be cleaner.

Indeed, I considered posting the process here in the forums but decided that the DIY approach is not straightforward enough that it wouldn’t potentially cause malformed backups or expose a user PC to malicious PowerShell scripts due to the need to change Windows 10 security policies…plus, the plain text!

In the end, because my use case is single PC under my control, I just went back to manually triggering the backup when I plug the USB drive in, and while it is not as seamless as Crashplan, it obviously works. But I would need to carefully consider configuring in the automatic USB drive PowerShell if I was setting this up for another PC with less knowledgeable users, like your club members may be.

I agree. The service discussion is likely to get messy enough by itself without unrelated posts threaded in.
It also might stay a little theoretical until necessary volunteers and equipment gather, but planning is good.

It looks like I can move the USB parts into a new or existing topic. Any suggestions before I attempt that?
Device mount detection (USB or otherwise) was my previous idea, but those who want this, look around.
Getting beyond a DIY approach is probably a feature request, so search for one, maybe with DIY for now.

Hi sergethedev17,
thanks for providing such detailed instructions. So I built it according to your instruction in a virtual machine, reflecting a typical setup I face.
First of all, it works. However, on a simulated workstation with one administrator account and two standard user accounts it seems that all 3 user accounts share one Duplicati account without a chance to have 3 separate user accounts in Duplicati. Is this the intended setup?

I did try that early on, as it clearly seems to be the intended way to access files. However, when I tested it, I did not get the raw file data, but rather a packed copy of the file with metadata. This can/could be restored with the corresponding restore method, but I did not like the nonstandard format and worry that it will make it hard/impossible to restore on a new/different machine, so I decided not to use it.

Yes, that is a good suggestion and should be easy to do. Non-Windows systems should use the whoami output and display that context, possibly with the hostname output as well.

Also a good suggestion, and should be simple to add.

Maybe it adds a bit complexity to implement, but combining this with detecting the LOCAL SYSTEM profile folder (%WINDIR%\System32\config\systemprofile\AppData) and - if detected - moving the Duplicati data folder to %PROGRAMDATA% would avoid running into a known problem (all Duplicati configurations wiped after installing a Windows 10 feature update).

1 Like

Thank you for the major input. It will take awhile to digest. Sorry about the delay, as I’ve been chipping.

I started looking at the PAM usage with sshd on Linux to see what processes it started during the login.
What you suggest is somewhat familiar to me for Internet services that start as root then change user.
Unless someone is really ambitious, I guess Duplicati wouldn’t do user-of-your-choice, just single user.
Duplicati About → System info has a Username field, so it seems aware of the user that it’s running as.

I’ve wished that Duplicati could get away from LocalSystem, as it’s a lot of power, especially with a web server connected. In addition, SYSTEM has trouble using SMB shares. I’m not sure if NetworkService or LocalService is better. It sounds like LocalService might have even more trouble with remote connection.

Sounds like you’re advocating a specially made account that is none of those (below in Installer section), along with a way to get access. Arch Linux packaging does half of that, running Duplicati as a new user dedicated to duplicati, and leaving it as an exercise to the user to set things up so it can actually work…

The ideal way of doing things would remove (or at least not worsen) headaches with SMB access, while allowing local access necessary for backup and restore. As a side note, a restore will try to read current source files in the hope that it can obtain a block locally instead of from remote. The option to stop this is

no-local-blocks

--no-local-blocks = false
Duplicati will attempt to use data from source files to minimize the amount of downloaded data. Use this option to skip this optimization and only use remote data.

Another chronic pain point of running as LocalSystem is that Windows version upgrades wipe Duplicati configuration into Windows.old, and destroy it in 10 days. I did some initial testing using NetworkService and LocalService, e.g. C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Duplicati) survived.

Hence the feature request to move the datafolder to %ProgramData% if the user context is SYSTEM.

1 Like

Hi,

we’ve had a similar discussion which service account is best under Windows at Syncthing. I’ve made a MSI package that takes care of relocating Syncthings configuration directory to C:/Server/Syncthing/AppData . This way, we ensure the config is preserved during System upgrades. The MSI can be edited (with Orca) to set the desired service account. We default to LocalService (to avoid the overpowered LocalSystem). LocalService can do network connections and built-in webserver without problems.

For users it’s a bit tricky as directories not owned by LocalService nor containing NTFS permissions for “all users” cannot be accessed by LocalService by default. I’ve shipped a small batch which can be easily used by the user to grant a drive or directory tree permissions for LocalService. all in all that solution works well.

Batch: syncthing-msi/syncthing_grant_folder_access.cmd at master · Catfriend1/syncthing-msi · GitHub

Kind regards,
Catfriend1

1 Like