Skip to content

test: fix nginx to run as non-root user #179

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

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

tduf
Copy link

@tduf tduf commented Jun 28, 2024

Logs

$ ./test/wait-for-hawkbit-online && dbus-run-session -- pytest -v -o log_cli=true test/test_download.py
[...]
test/test_download.py::test_download_too_slow
-------------------------------------------------------- live log call --------------------------------------------------------
INFO nginx running: nginx -c /tmp/pytest-of-thibaud/pytest-8/nginx0/nginx.conf -p .
INFO nginx nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
INFO nginx 2024/06/28 15:41:56 [emerg] 1450257#1450257: mkdir() "/var/lib/nginx/tmp/client_body" failed (13: Permission denied)
SKIPPED (nginx failed, use -s to see logs)                                                                              [ 42%]
test/test_download.py::test_download_partials_without_resume
------------------------------------------------------- live log setup --------------------------------------------------------
INFO nginx running: nginx -c /tmp/pytest-of-thibaud/pytest-8/nginx1/nginx.conf -p .
INFO nginx nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
INFO nginx 2024/06/28 15:41:56 [emerg] 1450258#1450258: mkdir() "/var/lib/nginx/tmp/client_body" failed (13: Permission denied)
SKIPPED (nginx failed, use -s to see logs)                                                                              [ 57%]
test/test_download.py::test_download_partials_with_resume SKIPPED (nginx failed, use -s to see logs)                    [ 71%]
test/test_download.py::test_download_slow_with_resume
-------------------------------------------------------- live log call --------------------------------------------------------
INFO nginx running: nginx -c /tmp/pytest-of-thibaud/pytest-8/nginx2/nginx.conf -p .
INFO nginx nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
INFO nginx 2024/06/28 15:41:56 [emerg] 1450259#1450259: mkdir() "/var/lib/nginx/tmp/client_body" failed (13: Permission denied)
SKIPPED (nginx failed, use -s to see logs)

Run on Fedora 40 with following rpm packages installed:

meson
ninja-build
libcurl-devel
json-glib-devel
python3-sphinx

# Needed by pip install -r test-requirements.txt
pkg-config
cairo
cairo-devel
cairo-gobject-devel
gobject-introspection
gobject-introspection-devel

nginx
nginx-all-modules

@tduf
Copy link
Author

tduf commented Jun 28, 2024

With this fix, there is still issues with test/test_download.py::test_download_partials_without_resume (download succeed) and test_download_partials_with_resume (download succeed without resume).

@tduf tduf force-pushed the tdu/fix-test-with-nginx branch from d3c867d to 23a6f0d Compare June 28, 2024 14:46
@Bastian-Krause
Copy link
Member

Bastian-Krause commented Dec 18, 2024

It's not clear to me what fails at your end. I can run the tests successfully as an unprivileged user with Debian trixie. The nginx errors are somewhat expected for unprivileged users, but should not be fatal:

# non-fatal alert for /var/log/nginx/error.log will still be shown
# https://trac.nginx.org/nginx/ticket/147

Can you provide logs of a pytest run with -s?

@tduf
Copy link
Author

tduf commented Dec 19, 2024

Here is a run on master branch with Fedora 41 (nginx 1.26.2) with pytest -s:
failure_with_-s_on_master.log

@Bastian-Krause Bastian-Krause marked this pull request as draft March 12, 2025 14:18
@Bastian-Krause Bastian-Krause force-pushed the tdu/fix-test-with-nginx branch from 23a6f0d to e4d3004 Compare March 12, 2025 14:19
@Bastian-Krause
Copy link
Member

Okay, since it's officially documented, we should apply the config directives. Rebased on top of #188 and marked as draft for now. Once the depending PRs are merged, we can mark this as "ready for review".

@Bastian-Krause Bastian-Krause changed the title Fix nginx to run test test_downloadp.y local as non-root user test: fix nginx to run as non-root user Mar 12, 2025
@Bastian-Krause Bastian-Krause self-assigned this Mar 12, 2025
@Bastian-Krause Bastian-Krause force-pushed the tdu/fix-test-with-nginx branch 2 times, most recently from 4d002e2 to f84e82e Compare March 13, 2025 10:04
rvdgracht and others added 11 commits March 13, 2025 11:32
This is preparation for a new authentication method mTLS being
introduced in a future commit.

Move the SSL options up, so mTLS options can be added before bailing out
due to no valid authentication option set. Also move the existence check
for auth/gateway token into a new variable, so we can check for them in
a combined fashion.

Signed-off-by: Robin van der Gracht <[email protected]>
Signed-off-by: Bastian Krause <[email protected]>
Add support for mutual TLS authentication. This is the preferred method
of authentication for bosch-iot-suite.com's hawkBit instance and the only
one that allows keeping the authenticator in a (f)TPM.

Optionally, an OpenSSL engine can be configured if required for access to
the SSL private key.

Signed-off-by: Robin van der Gracht <[email protected]>
Signed-off-by: Bastian Krause <[email protected]>
This works by passing the client key and cert on to RAUC's
"tls-key"/"tls-cert" properties.

Signed-off-by: Robin van der Gracht <[email protected]>
Signed-off-by: Bastian Krause <[email protected]>
A future commit will set up a nginx reverse proxy between
rauc-hawkbit-updater and hawkbit for mTLS testing.

server.forward-headers-strategy=NATIVE makes Hawkbit take the
X-Forwarded-For/X-Forwarded-Proto headers into account.

Signed-off-by: Florian Bezannier <[email protected]>
Signed-off-by: Robin van der Gracht <[email protected]>
Signed-off-by: Bastian Krause <[email protected]>
Inspired by https://eclipse.dev/hawkbit/concepts/authentication/ .

The files in test/pki/ were generated by running this command in the
repository's root directory:

  $ test/gen_pki.sh test/pki

Signed-off-by: Florian Bezannier <[email protected]>
Signed-off-by: Robin van der Gracht <[email protected]>
Signed-off-by: Bastian Krause <[email protected]>
Inspired by https://eclipse.dev/hawkbit/concepts/authentication/, add
options to the nginx proxy configuration for mTLS tests and some new
infrastructure fixtures to make use of this feature in a future commit.

Signed-off-by: Florian Bezannier <[email protected]>
Signed-off-by: Robin van der Gracht <[email protected]>
Signed-off-by: Bastian Krause <[email protected]>
Based on the work of Florain Bezannier.

Client key and certificate are now provided to rauc_dbus_dummy by
rauc-hawkbit-updater through arguments of the InstallBundle method call
(for streaming installations). This also removes the need for a separate
mTLS rauc_dbus_dummy fixture.

Signed-off-by: Robin van der Gracht <[email protected]>
Signed-off-by: Bastian Krause <[email protected]>
The nginx config is getting rather complex. Future commits will even
extend the existing nginx configs with lua scripting. We should not
maintain lua scripting inside nginx configs inside python f-strings.
So let's move the config to a dedicated file and use Python's template
mechanism instead of f-strings and .format().

Signed-off-by: Bastian Krause <[email protected]>
Until now, the partial download tests did not work reliably and relied
on implicit nginx behavior: `limit_rate_after 200k;` combined with
`limit_rate 70k;` lead to nginx sending "206 Partial Content" responses.
As far as I remember, this was found by trial and error.

Let's use a more stable solution: lua scripting allows us to control
reliable and fine grained what hawkBit artifacts nginx serves. So add a
config snippet that makes nginx only serve the first half of the RAUC
bundle, then close the connection prematrely and serve the second half
via range request only. This is basically what the previous solution
tried to achieve in a more reliable fashion.

This means we need to add the lua module and its dependencies to the test
dependencies.

Signed-off-by: Bastian Krause <[email protected]>
The nginx_proxy fixture does not do rate limiting on its own. This was
mixed up with the rate_limited_port fixture. So drop that part of the doc
string.

Signed-off-by: Bastian Krause <[email protected]>
Under some unknown circumstances, the current nginx config run as
non-root still leads to fatal errors:

    $ ./test/wait-for-hawkbit-online && dbus-run-session -- pytest -v -o log_cli=true test/test_download.py
    [...]
    test/test_download.py::test_download_too_slow
    -------------------------------------------------------- live log call --------------------------------------------------------
    INFO nginx running: nginx -c /tmp/pytest-of-thibaud/pytest-8/nginx0/nginx.conf -p .
    INFO nginx nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
    INFO nginx 2024/06/28 15:41:56 [emerg] 1450257#1450257: mkdir() "/var/lib/nginx/tmp/client_body" failed (13: Permission denied)
    SKIPPED (nginx failed, use -s to see logs)                                                                              [ 42%]
    test/test_download.py::test_download_partials_without_resume
    ------------------------------------------------------- live log setup --------------------------------------------------------
    INFO nginx running: nginx -c /tmp/pytest-of-thibaud/pytest-8/nginx1/nginx.conf -p .
    INFO nginx nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
    INFO nginx 2024/06/28 15:41:56 [emerg] 1450258#1450258: mkdir() "/var/lib/nginx/tmp/client_body" failed (13: Permission denied)
    SKIPPED (nginx failed, use -s to see logs)                                                                              [ 57%]
    test/test_download.py::test_download_partials_with_resume SKIPPED (nginx failed, use -s to see logs)                    [ 71%]
    test/test_download.py::test_download_slow_with_resume
    -------------------------------------------------------- live log call --------------------------------------------------------
    INFO nginx running: nginx -c /tmp/pytest-of-thibaud/pytest-8/nginx2/nginx.conf -p .
    INFO nginx nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
    INFO nginx 2024/06/28 15:41:56 [emerg] 1450259#1450259: mkdir() "/var/lib/nginx/tmp/client_body" failed (13: Permission denied)
    SKIPPED (nginx failed, use -s to see logs)

The section "Running nginx as a non-root user" of the official nginx
docker image [1] gives a hint what options must be set to not run into
errors. Apply the config directives appropriate for our use case.

[1] https://hub.docker.com/_/nginx

Signed-off-by: Thibaud Dufour <[email protected]>
[bst: dropped unused options fastcgi_temp_path, uwsgi_temp_path, scgi_temp_path, rebased]
Signed-off-by: Bastian Krause <[email protected]>
@Bastian-Krause Bastian-Krause force-pushed the tdu/fix-test-with-nginx branch from f84e82e to b18ac03 Compare March 13, 2025 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants