@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phd: unit startup and hardening improvements

Summary:
These changes help ensure that phd starts more reliably and should phd itself,
or one of its dependencies (such as `git`, or `hg`) become somehow compromised,
the blast radius is minimized.

- Improve the startup characteristics
- use `syslog.socket` as `syslog.target` isn't guaranteed by systemd.
- use `network-online.target` rather than `network.target` under the common
assumption that mysql is on another host.
- defensively order after `local-fs.target`.
- Improve service hardening
- `ProtectHome=tmpfs`: ensure that arbitrary home directories are invisible.
- `ProtectHostname=yes`: prevent changing the system hostname.
- `ProtectKernelLogs=yes`: prevent access to kernel (dmesg) logs.
- `ProtectKernelModules=yes`: prevent access/modification to loaded modules.
- `ProtectKernelTunables=yes`: prevent modification sysctls and some `/proc` parameters.
- `ProtectSystem=full`: make `/boot`, `/efi`, `/usr`, and `/etc` read-only.
- `ProtectProc=invisible`: hide other than itself and those it spawned from itself.
- `ProtectControlGroups=strict`: hide other cgroups, and prevent modifications.
- `PrivateDevices=yes`: only expose essential devices e.g. `/dev/null`.
- `PrivateIPC=yes`: restrict mostly legacy IPC mechanisms (i.e., SysV IPC).
- `PrivateTmp=yes`: give phd private temporary directories `/tmp`, `/var/tmp`.
This helps make temporary files safer and improves service behavior since systemd
will clean up these directories after every service stop.
- `PrivateUsers=yes`: make only `root`, `nobody`, and the configured `daemon-user` visible.
The `nobody` is mapped to the entire rest of the uid space, precluding even knowledge of
other user account or groups.

Test Plan:
I deployed these units on my production install of Phorge and everything kept
working. I used the following systemd drop-in specify my install's configuration:

```lang=ini,name=/etc/systemd/system/phorge-phd.service.d/override.conf
[Service]
User=phd
Group=phd
# repository storage root
ReadWritePaths=/data
# phd log directory
ReadWritePaths=/var/log/phorge
```

Reviewers: avivey, O1 Blessed Committers

Reviewed By: avivey, O1 Blessed Committers

Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno

Differential Revision: https://we.phorge.it/D26216

amy bones 88c580da d345aa44

+40 -6
+20 -3
resources/phd/phorge-phd.service
··· 1 1 [Unit] 2 2 Description=Phorge Daemons 3 3 Documentation=https://we.phorge.it/book/phorge/article/managing_daemons/ 4 - After=syslog.target network.target 4 + # Want this so that there is a greater chance phd will start up successfully 5 + # when mysql is on a remote host. 6 + Wants=network-online.target 7 + After=local-fs.target network-online.target syslog.socket 5 8 6 9 [Service] 7 10 Type=forking 8 11 EnvironmentFile=/etc/phorge/environment 9 - User=phd 10 - Group=phd 12 + User=daemon-user 13 + Group=daemon-user 11 14 ExecStart="${PHORGE_ROOT}/bin/phd" start 15 + ExecReload="${PHORGE_ROOT}/bin/phd" reload 12 16 ExecStop="${PHORGE_ROOT}/bin/phd" stop 13 17 14 18 Restart=on-failure 19 + 20 + ProtectHome=tmpfs 21 + ProtectHostname=yes 22 + ProtectKernelLogs=yes 23 + ProtectKernelModules=yes 24 + ProtectKernelTunables=yes 25 + ProtectSystem=full 26 + ProtectProc=invisible 27 + ProtectControlGroups=strict 28 + PrivateDevices=yes 29 + PrivateIPC=yes 30 + PrivateTmp=yes 31 + PrivateUsers=yes 15 32 16 33 [Install] 17 34 WantedBy=multi-user.target
+20 -3
resources/phd/phorge-phd@.service
··· 1 1 [Unit] 2 2 Description=Phorge Daemons 3 3 Documentation=https://we.phorge.it/book/phorge/article/managing_daemons/ 4 - After=syslog.target network.target 4 + # Want this so that there is a greater chance phd will start up successfully 5 + # when mysql is on a remote host. 6 + Wants=network-online.target 7 + After=local-fs.target network-online.target syslog.socket 5 8 6 9 [Service] 7 10 Type=forking 8 11 Environment=PHABRICATOR_ENV=%I 9 12 EnvironmentFile=/etc/phorge/environment 10 13 EnvironmentFile=-/etc/phorge/%I.env 11 - User=phd 12 - Group=phd 14 + User=daemon-user 15 + Group=daemon-user 13 16 ExecStart="${PHORGE_ROOT}/bin/phd" start 17 + ExecReload="${PHORGE_ROOT}/bin/phd" reload 14 18 ExecStop="${PHORGE_ROOT}/bin/phd" stop 15 19 16 20 Restart=on-failure 21 + 22 + ProtectHome=tmpfs 23 + ProtectHostname=yes 24 + ProtectKernelLogs=yes 25 + ProtectKernelModules=yes 26 + ProtectKernelTunables=yes 27 + ProtectSystem=full 28 + ProtectProc=invisible 29 + ProtectControlGroups=strict 30 + PrivateDevices=yes 31 + PrivateIPC=yes 32 + PrivateTmp=yes 33 + PrivateUsers=yes 17 34 18 35 [Install] 19 36 WantedBy=multi-user.target