Skip to content

feat: systemd hardening - #120

Open
juju4 wants to merge 1 commit into
RIPE-NCC:masterfrom
juju4:devel-systemd
Open

feat: systemd hardening#120
juju4 wants to merge 1 commit into
RIPE-NCC:masterfrom
juju4:devel-systemd

Conversation

@juju4

@juju4 juju4 commented Jan 26, 2025

Copy link
Copy Markdown

Follow-up of #109
No functional impact as far as I can tell for now

@trixmoe

trixmoe commented May 28, 2025

Copy link
Copy Markdown
Member

I remember discussing this internally with @mmavropoulos and coming to the conclusion that a much more conservative approach would be better, which was then done as part of a23fa17.

@mmavropoulos Feel free to comment or close if you believe this has been completed.

--
Trix
RIPE NCC

@juju4

juju4 commented Jun 1, 2025

Copy link
Copy Markdown
Author

It's great that there are already some improvements in, but, like often in security, this is a journey, one step at a time.
systemd-analyze security ripe-atlas returns exposure level at 7.8. should target below 5, OK level imho.
I would especially recommend ProtectSystem, ReadWritePaths, Umask, CAP_SYS_ADMIN.
From https://github.com/RIPE-NCC/ripe-atlas-software-probe/blob/master/openwrt/files/capabilities.json, normally only need CapabilityBoundingSet=CAP_NET_RAW CAP_SETUID
Ideally some syscall filters but, in my testing, it was difficult even for groups which should not be like @clock @cpu-emulation @module @obsolete @raw-io @reboot @swap.
@privileges can't be filtered because of sudo/setuid usage. It would probably be better to split unit in two, one per identity (ripe-atlas and ripe-atlas-measurement) to make it manageable. This would also allow NoNewPrivileges option which is not possible for now.
Also unclear to me why ProtectKernelLogs, ProtectKernelModules, ProtectKernelTunables are blocking.

@mmavropoulos

mmavropoulos commented Jun 5, 2025

Copy link
Copy Markdown
Contributor

Dear @juju4

Thank you for your feedback. As you correctly stated, securing software is a journey, to be done incrementally.
This is also true for RIPE Atlas, especially if we take into account that the project was originally designed to run on isolated Linux systems that do not use systemd. This in turn meant that processes and users created and owned by the service were granted elevated privileges, which causes issues when trying to apply systemd-based sandboxing.

In answer to your question, the majority of problems stems from setuid usage: we no longer rely on the use of sudo for the processes, and the way chosen to achieve this result at the time was to grant some elevated privileges to the ripe-atlas and ripe-atlas-measurement users. This, however, means that we cannot effectively use settings that set or modify the process IDs, such as PrivateUsers, which is an implicit requirement for settings such as ProtectKernelLogs, ProtectKernelModules and ProtectKernelTunables (as stated in https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html).

Additionally, some sandboxing settings do not apply cleanly to all the systems we support, and at the time the resource constraints forbade us from working around this. A clear example can be found in ProtectKernelLogs, added in systemd version 244. One of our supported systems, Oracle Linux 8, uses version 239. As such, adding that setting to the
unit's file would force us to drop support for Oracle Linux 8, which is not a feasible target at present.

We remain committed to ensuring the security of the service. We will take your suggestions into consideration, in particular the concept of splitting the service unit for each user. We thank you again for your time and insight.


Marios Mavropoulos Papoudas
Software Engineer @ RIPE Atlas
RIPE NCC

@juju4

juju4 commented Jun 8, 2025

Copy link
Copy Markdown
Author

Thanks for the feedback
I did an ansible role https://github.com/juju4/ansible-ripe-atlas-swprobe/ and happy to add more testing that could help to identify issues. But limited by what I can do on a short duration and without registering the probe. If there are some testing commands available, please share.

Both packaging tools and ansible normally allows some custom configuration depending on os release.
Or just build script like
https://github.com/dariogriffo/lazygit-debian/blob/main/build.sh
https://dario.griffo.io/posts/ultimate-guide-debian-packaging/

@mmavropoulos

Copy link
Copy Markdown
Contributor

Dear @juju4,

Apologies for the late reply. While it is not possible at this time to share exact testing commands, a suggested process to follow in this particular case would be (assuming the starting point is a compiled probe source code with changes to the service's unit file) :

  • Step 1: Setting up the probe. To save time, I would recommend backing up the probe's public/private key pair prior to this step to avoid having to update them with every iteration.
  • Step 2: Ensuring the probe can register and connect to the infrastructure.
  • Step 3: Attempting to run a couple of measurements (one-off and periodic) and seeing results crop up.

The service's system logs, accessible via, for instance, journalctl -u ripe-atlas.service, contain useful information to identify potential errors in any step of the process.

Hope this helps. We remain at your disposal for any additional information.


Marios Mavropoulos Papoudas
Software Engineer @ RIPE Atlas
RIPE NCC

@juju4

juju4 commented Jul 6, 2025

Copy link
Copy Markdown
Author

That looks like more manual testing that I partly did on my own.
I was more looking into something automated that could be included in github CI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants