Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow running as arbitrary UID for unprivileged Container Environments (OpenShift) #10307

Open
rezemble opened this issue Jan 18, 2025 · 4 comments · May be fixed by #10321
Open

Allow running as arbitrary UID for unprivileged Container Environments (OpenShift) #10307

rezemble opened this issue Jan 18, 2025 · 4 comments · May be fixed by #10321
Assignees

Comments

@rezemble
Copy link

Is your feature request related to a problem? Please describe.

In order to be able to run Icinga in a context with indeterminate User IDs, such as OpenShift, the group-injection logic from icinga.cpp seems to be an obstacle:

  if (!pw) {
  	if (errno == 0) {
  		Log(LogCritical, "cli")
  			<< "Invalid user specified: " << user;
  		return EXIT_FAILURE;
  	} else {
  		Log(LogCritical, "cli")
  			<< "getpwnam() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
  		return EXIT_FAILURE;
  	}
  }
  // also activate the additional groups the configured user is member of
  ...

Describe the solution you'd like

From my testing, activating additional groups in such a context is superfluous, since there are none; since the process is run as an arbitrary UID with GID 0, removing the if (!pw) { check and instead wrapping the group activating logic in

if (pw) {
 // also activate the additional groups the configured user is member of
 ...
}

works fine

Describe alternatives you've considered

I've considered wrapping the image with dynamic user and group renaming, but this adds unnecessary complexity and image layers

@rezemble rezemble changed the title Allow Running as Arbitrary UID for unprivileged Container Environments (OpenShift) Allow running as arbitrary UID for unprivileged Container Environments (OpenShift) Jan 18, 2025
@oxzi
Copy link
Member

oxzi commented Jan 21, 2025

Thanks for creating this issue.

Unless I am missing something, you cited code is about the user and not group switching logic.

  1. String user = Configuration::RunAsUser;
  2. struct passwd *pw = getpwnam(user.CStr());
    if (!pw) {

After having taken a first look at your PR #10308, I followed the definition logic of Configuration::RunAs{User,Group} and ended at the following snippet. Both the desired user and group may be defined at runtime via the ICINGA2_USER and ICINGA2_GROUP environment variables, same as for compile time.

String icingaUser = Utility::GetFromEnvironment("ICINGA2_USER");
if (icingaUser.IsEmpty())
icingaUser = ICINGA_USER;
String icingaGroup = Utility::GetFromEnvironment("ICINGA2_GROUP");
if (icingaGroup.IsEmpty())
icingaGroup = ICINGA_GROUP;
Configuration::RunAsUser = icingaUser;
Configuration::RunAsGroup = icingaGroup;

As verified below, icinga2 may run with the configured user and group.

$ icinga2 daemon
critical/cli: Invalid group specified: icinga2

$ export ICINGA2_USER="$(id -un)"
$ export ICINGA2_GROUP="$(id -gn)"
$ icinga2 daemon
[2025-01-21 10:18:55 +0100] information/cli: Icinga application loader (version: r2.14.3-1)
[ . . . ]

Does this already help you with your OpenShift setup?

Furthermore, how does your Icinag 2 container startup script look like? After switching/impersonating (or re-configuring) the desired user, this user needs access to the icinga2.pid file as well as to the configuration.

@rezemble
Copy link
Author

rezemble commented Jan 21, 2025

Thanks @oxzi for taking a look - unfortunately I don't think this alone solves the problem - the containers run with an arbitrary UID within a pre-set range that cannot be user-selected, and for said UID, no passwd entry exists, hence id -un and id -gn would not work either - there is no username, there are no groups other than root, hence the cited check if (!pw) always fails since there exists no passwd entry for the arbitrary user

Edit:
The initgroups call is what actually fails in the instance - for any of the arbitrary UIDs, no passwd entry will ever exist unless applying some passwd masking - hence no groups can be selected - and the running user will not have permissions to impersonate other users, hence overriding with ICINGA2_USER does not work

@oxzi oxzi self-assigned this Jan 24, 2025
oxzi added a commit that referenced this issue Jan 24, 2025
By default, icinga2 uses icinga:icinga as user and group, or whatever is
configured via ICINGA2_USER and ICINGA2_GROUP. Thus, it is required to
launch icinga2 as this user or as a privileged user, allowed to setuid.

The only command where no user impersonation is necessary is "icinga2
console".

However, in certain scenarios one cannot switch to a static user. There
might also be the case that privileges are already dropped, e.g., by an
init manager. Therefore, the "--no-impersonate" flag was introduced,
skipping all impersonation logic.

> $ icinga2 daemon
critical/cli: Invalid group specified: icinga
> $ icinga2 daemon --no-impersonate
[2025-01-24 10:42:41 +0100] information/cli: Icinga application loader (version: v2.14.0-439-ga5980d362)

Closes #10307.
@oxzi oxzi linked a pull request Jan 24, 2025 that will close this issue
@oxzi
Copy link
Member

oxzi commented Jan 24, 2025

Thanks for your response. I have taken another look at this and created #10321, effectively allowing to bypass all impersonation/user-switching logic. Please feel free to try this PR, @rezemble.

@rezemble
Copy link
Author

Thanks for the input @oxzi - from what I can tell, this solves the issue - my tests run fine on your feature branch!

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 a pull request may close this issue.

2 participants