-
Notifications
You must be signed in to change notification settings - Fork 5k
[Filebeat/Journald] allow to use a chroot when calling journalctl
#48008
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
base: main
Are you sure you want to change the base?
Changes from 20 commits
9f84117
a12aa54
624405b
25ee4d3
7bc0cfd
1e77ec8
ec3b019
09eb57d
f19ab67
d51036b
b303a39
295f7b8
21cf345
df0ff3f
ec90ee8
e36d12b
f4c55ce
b132d06
29f4920
20893dd
c6e7918
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10941,11 +10941,11 @@ SOFTWARE | |
|
|
||
| -------------------------------------------------------------------------------- | ||
| Dependency : github.com/elastic/elastic-agent-libs | ||
| Version: v0.26.2 | ||
| Version: v0.28.0 | ||
| Licence type (autodetected): Apache-2.0 | ||
| -------------------------------------------------------------------------------- | ||
|
|
||
| Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.26.2/LICENSE: | ||
| Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.28.0/LICENSE: | ||
|
|
||
| Apache License | ||
| Version 2.0, January 2004 | ||
|
|
@@ -28994,13 +28994,13 @@ Contents of probable licence file $GOMODCACHE/go.uber.org/[email protected]/LICENSE: | |
|
|
||
| -------------------------------------------------------------------------------- | ||
| Dependency : go.uber.org/zap | ||
| Version: v1.27.0 | ||
| Version: v1.27.1 | ||
| Licence type (autodetected): MIT | ||
| -------------------------------------------------------------------------------- | ||
|
|
||
| Contents of probable licence file $GOMODCACHE/go.uber.org/[email protected].0/LICENSE: | ||
| Contents of probable licence file $GOMODCACHE/go.uber.org/[email protected].1/LICENSE: | ||
|
|
||
| Copyright (c) 2016-2017 Uber Technologies, Inc. | ||
| Copyright (c) 2016-2024 Uber Technologies, Inc. | ||
|
|
||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # Kind can be one of: | ||
| # - breaking-change: a change to previously-documented behavior | ||
| # - deprecation: functionality that is being removed in a later release | ||
| # - bug-fix: fixes a problem in a previous version | ||
| # - enhancement: extends functionality but does not break or fix existing behavior | ||
| # - feature: new functionality | ||
| # - known-issue: problems that we are aware of in a given version | ||
| # - security: impacts on the security of a product or a user’s deployment. | ||
| # - upgrade: important information for someone upgrading from a prior version | ||
| # - other: does not fit into any of the other categories | ||
| kind: feature | ||
|
|
||
| # Change summary; a 80ish characters long description of the change. | ||
| summary: The Journald input now supports setting a chroot to use when calling the journalctl binary | ||
|
|
||
| # Long description; in case the summary is not enough to describe the change | ||
| # this field accommodate a description without length limits. | ||
| # NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment. | ||
| #description: | ||
|
|
||
| # Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc. | ||
| component: filebeat | ||
|
|
||
| # PR URL; optional; the PR number that added the changeset. | ||
| # If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added. | ||
| # NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number. | ||
| # Please provide it if you are adding a fragment for a different PR. | ||
| pr: https://github.com/elastic/beats/pull/48008 | ||
|
|
||
| # Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of). | ||
| # If not present is automatically filled by the tooling with the issue linked to the PR number. | ||
| issue: https://github.com/elastic/beats/issues/47164 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,16 +15,18 @@ The Wolfi-based Docker image does not contain the `journalctl` binary and the `j | |
| ::: | ||
|
|
||
| :::{important} | ||
| When using the Journald input from a Docker container, make sure the | ||
| `journalctl` binary in the container is compatible with your | ||
| Systemd/journal version. To get the version of the `journalctl` binary | ||
| in Filebeat's image run the following, adjusting the image name/tag | ||
| according to the version that you are running: | ||
|
|
||
|
|
||
| ```sh | ||
| docker run --rm -it --entrypoint "journalctl" docker.elastic.co/beats/filebeat-wolfi:<VERSION> --version | ||
| ``` | ||
| When using the Journald input from a Docker container, make sure that | ||
| either: | ||
| - {applies_to}`stack: ga 9.3.0` [`chroot`](#filebeat-input-journald-chroot), [`journalct_path`](#filebeat-input-journald-journalctl-path) are set, or | ||
| - The `journalctl` binary in the container is compatible with your | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. List the container variants that include journald by default. |
||
| Systemd/journal version. To get the version of the `journalctl` binary | ||
| in Filebeat's image run the following, adjusting the image name/tag | ||
| according to the version that you are running: | ||
|
|
||
|
|
||
| ```sh | ||
| docker run --rm -it --entrypoint "journalctl" docker.elastic.co/beats/filebeat-wolfi:<VERSION> --version | ||
| ``` | ||
| ::: | ||
|
|
||
| If the `journalctl` process exits unexpectedly the journald input will terminate with an error and Filebeat will need to be restarted to start reading from the journal again. | ||
|
|
@@ -110,8 +112,24 @@ input will only ingest the journal files found when started. New | |
| files will not be ingested. | ||
| ::: | ||
|
|
||
| ### `chroot` [filebeat-input-journald-chroot] | ||
| ```{applies_to} | ||
| stack: ga 9.3.0 | ||
| ``` | ||
| A folder to be used as chroot when calling `journalctl`. This allows | ||
| Filebeat to call the host's `journalctl` directly. If using this | ||
| option, {{filebeat}} must be run as root and | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The wolfi containers are not root by default, you will need examples of how to give the capabilities needed to do this. You potentially only need
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we can say that you just need |
||
| [`journalct_path`](#filebeat-input-journald-journalctl-path) must be | ||
| set. | ||
|
|
||
|
|
||
| ### `journalct_path` [filebeat-input-journald-journalctl-path] | ||
| ```{applies_to} | ||
| stack: ga 9.3.0 | ||
| ``` | ||
| The absolute path for the `journalctl` binary. If not set {{filebeat}} | ||
| will look for `journalctl` in `PATH`. When using | ||
| [`chroot`](#filebeat-input-journald-chroot), `journalct_path` must be | ||
| an absolute path from within the chroot directory. | ||
|
|
||
|
|
||
| ### `merge` [filebeat-input-journald-merge] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -817,6 +817,15 @@ filebeat.inputs: | |
| #paths: | ||
| #- /var/log/custom.journal | ||
|
|
||
| # Specify a folder to be used as chroot when calling the journalct binary | ||
| #chroot: | ||
|
|
||
| # The absolute path for the `journalctl` binary. If not set Filebeat | ||
| # will look for `journalctl` in `PATH`. When using | ||
|
Comment on lines
+823
to
+824
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to allow executing whatever thing called That seems less secure than requiring the absolute path to the binary, as there is only a single file system path that can be exploited now.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Especially if we execute
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only reason to just look for
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On an ubuntu24 box I see it as the following which is certainly not hard to find. If we think using PATH is necessary we could make it optional and default to off.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That is the current (before this PR) behaviour. Since we migrated to calling
I don't know for sure if the Btw, the OpenTelemetry Collector behaves in the same way:
|
||
| # `chroot`, `journalct_path` must be | ||
| # an absolute path from within the chroot directory. | ||
| #journalctl_path: | ||
|
|
||
| # When enabled, log entries will be ingested interleaved from all | ||
| # available journals, including remote ones. | ||
| #merge: false | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,8 @@ | |
| import ( | ||
| "errors" | ||
| "fmt" | ||
| "os" | ||
| "path/filepath" | ||
| "strconv" | ||
| "time" | ||
|
|
||
|
|
@@ -57,8 +59,9 @@ | |
| Facilities []int | ||
| SaveRemoteHostname bool | ||
| Parsers parser.Config | ||
| Journalctl bool | ||
| Merge bool | ||
| Chroot string | ||
| JournalctlPath string | ||
| } | ||
|
|
||
| type checkpoint struct { | ||
|
|
@@ -112,6 +115,21 @@ | |
| sources[i] = pathSource(p) | ||
| } | ||
|
|
||
| if config.Chroot != "" { | ||
| chrootStat, err := os.Stat(config.Chroot) | ||
| if err != nil { | ||
| return nil, nil, fmt.Errorf("cannot stat chroot: %w", err) | ||
| } | ||
| if !chrootStat.IsDir() { | ||
| return nil, nil, fmt.Errorf("provided chroot (%s) is not a directory", config.Chroot) | ||
| } | ||
|
|
||
| fullPath := filepath.Join(config.Chroot, config.JournalctlPath) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We may want to verify the ownership of the file, maybe that it is only writable by root so it can't be replaced by something from an arbitrary user, especially if we are going to execute it as root. Speaking of executing it as a root, if we can execute this as a lower privileged user that would help the security boundary here too. |
||
| if _, err := os.Stat(fullPath); err != nil { | ||
| return nil, nil, fmt.Errorf("cannot stat journalctl binary in chroot: %w", err) | ||
| } | ||
| } | ||
|
|
||
| return sources, &journald{ | ||
| ID: config.ID, | ||
| Since: config.Since, | ||
|
|
@@ -124,6 +142,8 @@ | |
| SaveRemoteHostname: config.SaveRemoteHostname, | ||
| Parsers: config.Parsers, | ||
| Merge: config.Merge, | ||
| Chroot: config.Chroot, | ||
| JournalctlPath: config.JournalctlPath, | ||
| }, nil | ||
| } | ||
|
|
||
|
|
@@ -143,7 +163,7 @@ | |
| inp.Since, | ||
| src.Name(), | ||
| inp.Merge, | ||
| journalctl.Factory, | ||
| journalctl.NewFactory(inp.Chroot, inp.JournalctlPath), | ||
| ) | ||
| if err != nil { | ||
| return err | ||
|
|
@@ -179,7 +199,7 @@ | |
| inp.Since, | ||
| src.Name(), | ||
| inp.Merge, | ||
| journalctl.Factory, | ||
| journalctl.NewFactory(inp.Chroot, inp.JournalctlPath), | ||
| ) | ||
| if err != nil { | ||
| wrappedErr := fmt.Errorf("could not start journal reader: %w", err) | ||
|
|
@@ -347,7 +367,7 @@ | |
| } | ||
|
|
||
| m := reader.Message{ | ||
| Ts: time.UnixMicro(int64(data.RealtimeTimestamp)), | ||
| Content: content, | ||
| Bytes: len(content), | ||
| Fields: fields, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.