Duplicati as a service - more complicate than it need be

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