Running the services under dedicated accounts
A default installation runs both the Web/REST service and every worker service as LocalSystem on Windows and as root on Linux. Many hardening policies want them on dedicated accounts instead, and the product supports that, with one thing worth knowing: the two services talk to each other over a control channel the operating system itself guards, and that guard must admit both of them.
The control channel
Every worker exposes a small control channel that the Web/REST service uses to read live sessions, feed the dashboard, lift Shield bans, drain the node, terminate transfers and trigger reloads. It is a named pipe on Windows and a unix domain socket on Linux, never a TCP port, so nothing else on the machine, and no browser, can reach it. Every request on it also carries a secret minted when the worker starts.
Because the operating system enforces who may open the pipe or the socket, the services do not have to trust each other or guess which account the other one uses. They only have to be admitted, which the sections below explain.
Windows
The pipe admits SYSTEM, the local Administrators group, the account the worker itself runs as, and the two services by their service identity. Every Windows service has a security identifier derived from its name, shown as NT SERVICE\ss-webrest and NT SERVICE\ss-wrk-<site>, and Windows places it in the service's token whatever account the service logs on as, provided the service was installed with a service SID type. The installer sets that on every new install and on every upgrade, so on a current installation nothing needs to be done: change the Log On As account of either service in services.msc, restart it, and the control channel keeps working.
To check an installation:
sc qsidtype ss-webrest
sc qsidtype ss-wrk-<site>Both must report SERVICE_SID_TYPE: UNRESTRICTED. If one reports NONE, the service was installed by a version that predates this mechanism and has not been reinstalled since. Run the install command once, from an elevated prompt, and restart the service:
ss-webrest svc install
ss-wrk svc install --virtualsite <site>Both commands are safe to repeat: on Windows, on an already installed service they change nothing except the SID type. On Linux the same commands rewrite a unit file the product wrote so it matches the current template, and leave a unit file that was edited by hand exactly as it is (see Unit files below).
Any log on type works: LocalSystem, LocalService, NetworkService, a local or domain user, a group managed service account, or the virtual account NT SERVICE\<name>. The account still needs what any service account needs, the right to log on as a service and read and write access to C:\ProgramData\Syncplify\Server; that part is unchanged.
Linux
The socket lives under /opt/Syncplify/Server/data/run, mode 0600 in a 0700 directory, which admits the worker's own account and nobody else. When the two services run as different accounts they are joined through a group named syncplify. The product does not create it; its presence is how you tell the worker that sharing is deliberate.
Create the group and add both service accounts to it:
groupadd syncplify usermod -aG syncplify <webrest account> usermod -aG syncplify <worker account>Give each unit its account. Run
systemctl edit ss-webrestandsystemctl edit ss-wrk-<site>, then put this in each override:[Service] User=<account> SupplementaryGroups=syncplifyMake sure both accounts can use
/opt/Syncplify/Server/dataand/opt/Syncplify/Server/log, then restart the worker first and the Web/REST service after it.
On start the worker hands the socket directory and the socket to the group, 0750 and 0660, and logs that it did. If the group exists but the worker's account is not a member, the kernel refuses the hand over, the socket stays private, and the worker logs a warning saying so. Without the group, nothing changes.
What you see when it is not set up
Nothing fails at startup, because each service starts fine on its own. What fails is the connection between them, and the product says so in three places:
- The Web/REST service logs a warning naming the account it runs as and the pipe or socket that refused it, once every ten minutes for as long as the refusal lasts.
- A notification titled Worker control channel refused appears in the Admin UI, once per start of the Web/REST service, with the same details and the fix.
- The dashboard shows the reason next to its live indicator instead of just going grey.
A worker whose own account is refused by its pipe, which is a Windows worker on a dedicated account without a service SID, logs an error and raises a notification titled Worker control channel failed, and keeps serving clients meanwhile.
Unit files
The three units the product installs on Linux (ss-syngod, ss-webrest and one ss-wrk-<site> per virtual site) are kept up to date rather than written once. On every update, and every time the Web/REST service starts, a unit file the product wrote is compared with the current template and rewritten when it is out of date; a running service is never restarted for it and picks the new unit up at its next start.
A unit file that carries anything the product never writes (a User= line, an environment variable, a changed limit, a different command line) is a unit file an operator edited by hand. It is never rewritten. The product logs a warning, raises a notification titled Service unit not updated in the SuperAdmin UI, and the installer says so, and the file stays exactly as it is. The supported way to change a unit is a drop in:
systemctl edit ss-wrk-<site>A drop in survives updates, so the change made there is kept and the unit itself still receives every fix and hardening directive a new release ships.
Managing unit files needs root: the Web/REST service writes them under /etc/systemd/system and drives systemctl when a virtual site is created, started or stopped. A Web/REST service that runs under a dedicated account, as described above, leaves the unit files to the operator and says so in its log once at startup; creating or removing a virtual site from that account then needs a polkit rule or a manual ss-wrk svc install as root.
Sandboxing
From version 8.3.1 the units ship with systemd hardening directives that change nothing the services do.
The SyngoDB and Web/REST units carry NoNewPrivileges, PrivateTmp, PrivateDevices, ProtectKernelTunables, ProtectKernelModules, ProtectKernelLogs, ProtectControlGroups, ProtectHostname, ProtectClock, RestrictRealtime, RestrictSUIDSGID, RestrictNamespaces, LockPersonality and SystemCallArchitectures=native. Neither service runs any program but systemctl, and neither needs any of the rights these remove.
The worker unit carries only ProtectKernelTunables, ProtectKernelModules, ProtectKernelLogs, ProtectControlGroups, LockPersonality and RestrictRealtime. The worker serves whatever path the operator chose and runs whatever event handler script they wrote, and every script inherits the worker's sandbox, so nothing that alters the view of the file system, the ability to gain privileges, the set of capabilities or the allowed system calls is applied to it by default. The six directives it does carry cost a script only the ability to write kernel tunables, load modules, read the kernel log and ask for real time scheduling. One consequence worth knowing: the worker runs in a private mount namespace, so a mount performed by an event handler script is visible to the worker and its scripts but not to the rest of the host, while a mount the host makes later still appears inside the worker.
Operators who want more can add it in a drop in, knowing that it constrains their scripts too. An example for a site whose virtual file systems all live under /srv/files:
[Service]
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/srv/files /opt/Syncplify/Server/data /opt/Syncplify/Server/log
NoNewPrivileges=yes
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_FSETID
SystemCallFilter=@system-serviceNoNewPrivileges stops sudo inside event handler scripts; ProtectSystem=strict makes every path outside ReadWritePaths read only, virtual file systems included; the bounding set removes CAP_SYS_ADMIN, which a script needs for mounts and containers. Test on a site that matters before applying it to one that matters more.
The escape hatch
If, in some environment the above does not cover, the local transport cannot be made to work, the worker can be told to use an authenticated loopback TCP listener instead:
ss-wrk serve --virtualsite <site> --ipc-transport tcpor the equivalent environment variable SS_IPCTRANSPORT=tcp. On Linux put Environment=SS_IPCTRANSPORT=tcp in the unit override. On Windows add SS_IPCTRANSPORT=tcp to the Environment value (type REG_MULTI_SZ) under HKLM\SYSTEM\CurrentControlSet\Services\ss-wrk-<site> and restart the service. The Web/REST service needs no setting: it learns the transport from the worker.
This is a last resort, not a configuration option. Every request on the loopback listener still requires the worker's secret, so it is degraded rather than exposed, but it gives up the guard the operating system provides, and the worker logs a warning at every start for as long as it is in force. Use it to keep a system running while the real cause is found, then remove it.
