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

authentication error when connecting from systemd-nspawn container using dynamic users #264

Closed
superchalupa opened this issue Aug 4, 2021 · 1 comment · Fixed by #265

Comments

@superchalupa
Copy link

superchalupa commented Aug 4, 2021

We have an application that is running inside a container that we are starting using systemd-nspawn. Note the systemd-nspawn config uses dynamic users where the process in the container believes it is root, but it is running as a non-root process from perspective of system dbus instance. We bind mount in the system's dbus socket so that we can access the System bus. This all works fine when using the 'sdbus' library from C code. When we did the exact same thing using godbus, we get an authentication error. Debugging, it comes down to 2 'main' things, but we also found 2 other issues worth reporting:

  1. (main issue) sdbus C library sends "AUTH EXTERNAL\r\n", godbus sends "AUTH EXTERNAL 30\r\n"
    Inside the container, we are running as getuid() == 0 (ie. root). But we are using the systemd dynamic user to run as an actual non-root user outside the container (ie. uid 12345). Because we are telling dbus that we are UID 0 (hex 0x30) in the "AUTH EXTERNAL 30" line, dbus refuses to allow us to connect because we are actually UID 12345 (for example).

  2. (main issue) dbus sends a "spurious" line of "DATA\r\n" and expects a reply of "DATA\r\n". The godbus code specifically checks for DATA lines without parameters and fails. It also falls out of the state machine with an auth error because it is expecting "OK" when the "DATA" string arrives instead.

  3. (side issue) sdbus C library "pipelines" all of the initial connection details instead of doing the query and back and forth. This allows sdbus to connect much faster. (Not related to the failure, but worth a note).

  4. (side issue) godbus sends SCM_CREDENTIALS with the initial null byte. This seems completely superfluous and appears to be unused by linux dbus. This doesnt cause the container authentication failure, but seems like something that probably should be removed lest it cause issues in the future. It sends SCM_CREDENTIALS saying it's UID 0, GID 0, which dbus would reject if it actually checked these.

@R2Dtwo
Copy link
Contributor

R2Dtwo commented Aug 4, 2021

Attached is the proposed patch to fix the authentication issue when connecting to the DBUS via private user container
(0001-GODBUS-264-do-not-send-data-with-DBUS-auth-mechanism.txt).

0001-GODBUS-264-do-not-send-data-with-DBUS-auth-mechanism.txt

Also attached is the system traces for sdbus (sdbus_strace.txt), godbus (godbus_strace.txt), and godbus with the above patch applied (godbus_strace_patched.txt).

sdbus_strace.txt
godbus_strace.txt
godbus_strace_patched.txt

R2Dtwo added a commit to R2Dtwo/dbus that referenced this issue Aug 5, 2021
When running inside a container using systemd dynamic user to run as an
actual non-root user outside the container (i.e. UID 12345), the DBUS
refuses to allow the godbus code to connect. This is because the godbus
code sends the UID of the user.

The sdbus C library sends "AUTH EXTERNAL\r\n", whereas godbus sends
"AUTH EXTERNAL 30\r\n". Since godbus goes the extra step to tell DBUS
that the current UID is 0 (hex 0x30, getuid() == 0, i,e, root), DBUS
refuses to allow the process to connect because it sees the process is
actually running as UID 12345 (for example) outside of the container.

When the UID is not specified by just sending "AUTH EXTERNAL\r\n", DBUS
sends back a line of "DATA\r\n" and expects a reply of "DATA\r\n". The
godbus code specifically checks for "DATA" when waitingForOk in
tryAuth(), but sends a "CANCEL\r\n" to the DBUS and errors out.

Instead of erroring out, the tryAuth() code in godbus should reply with
"DATA\r\n" when the status is 'waitingForOk' and the line read back from
the DBUS begins with "DATA".

Fixes godbus#264
jsouthworth pushed a commit that referenced this issue Aug 5, 2021
When running inside a container using systemd dynamic user to run as an
actual non-root user outside the container (i.e. UID 12345), the DBUS
refuses to allow the godbus code to connect. This is because the godbus
code sends the UID of the user.

The sdbus C library sends "AUTH EXTERNAL\r\n", whereas godbus sends
"AUTH EXTERNAL 30\r\n". Since godbus goes the extra step to tell DBUS
that the current UID is 0 (hex 0x30, getuid() == 0, i,e, root), DBUS
refuses to allow the process to connect because it sees the process is
actually running as UID 12345 (for example) outside of the container.

When the UID is not specified by just sending "AUTH EXTERNAL\r\n", DBUS
sends back a line of "DATA\r\n" and expects a reply of "DATA\r\n". The
godbus code specifically checks for "DATA" when waitingForOk in
tryAuth(), but sends a "CANCEL\r\n" to the DBUS and errors out.

Instead of erroring out, the tryAuth() code in godbus should reply with
"DATA\r\n" when the status is 'waitingForOk' and the line read back from
the DBUS begins with "DATA".

Fixes #264
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