Skip to content

Commit f3274bb

Browse files
authored
pipeline: inputs: exec: document exit code propagation (fluent#1080)
Document new options Exit_After_Oneshot and Propagate_Exit_Code for the related core fluent-bit PR. Add a security warning about shell metacharacter processing in commands. Add an example about how to use the exec plugin as a command wrapper in one-shot mode. Signed-off-by: Craig Ringer <craig.ringer@enterprisedb.com>
1 parent 2911c5e commit f3274bb

File tree

1 file changed

+87
-1
lines changed

1 file changed

+87
-1
lines changed

pipeline/inputs/exec.md

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
The **exec** input plugin, allows to execute external program and collects event logs.
44

5+
**WARNING**: Because this plugin invokes commands via a shell, its inputs are
6+
subject to shell metacharacter substitution. Careless use of untrusted input in
7+
command arguments could lead to malicious command execution.
8+
59
## Container support
610

711
This plugin will not function in the distroless production images (AMD64 currently) as it needs a functional `/bin/sh` which is not present.
@@ -13,12 +17,14 @@ The plugin supports the following configuration parameters:
1317

1418
| Key | Description |
1519
| :--- | :--- |
16-
| Command | The command to execute. |
20+
| Command | The command to execute, passed to [popen(...)](https://man7.org/linux/man-pages/man3/popen.3.html) without any additional escaping or processing. May include pipelines, redirection, command-substitution, etc. |
1721
| Parser | Specify the name of a parser to interpret the entry as a structured message. |
1822
| Interval\_Sec | Polling interval \(seconds\). |
1923
| Interval\_NSec | Polling interval \(nanosecond\). |
2024
| Buf\_Size | Size of the buffer \(check [unit sizes](https://docs.fluentbit.io/manual/configuration/unit_sizes) for allowed values\) |
2125
| Oneshot | Only run once at startup. This allows collection of data precedent to fluent-bit's startup (bool, default: false) |
26+
| Exit\_After\_Oneshot | Exit as soon as the one-shot command exits. This allows the exec plugin to be used as a wrapper for another command, sending the target command's output to any fluent-bit sink(s) then exiting. (bool, default: false) |
27+
| Propagate\_Exit\_Code | When exiting due to Exit\_After\_Oneshot, cause fluent-bit to exit with the exit code of the command exited by this plugin. Follows [shell conventions for exit code propagation](https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html). (bool, default: false) |
2228

2329
## Getting Started
2430

@@ -64,3 +70,83 @@ In your main configuration file append the following _Input_ & _Output_ sections
6470
Name stdout
6571
Match *
6672
```
73+
74+
## Use as a command wrapper
75+
76+
To use `fluent-bit` with the `exec` plugin to wrap another command, use the
77+
`Exit_After_Oneshot` and `Propagate_Exit_Code` options, e.g.:
78+
79+
```
80+
[INPUT]
81+
Name exec
82+
Tag exec_oneshot_demo
83+
Command for s in $(seq 1 10); do echo "count: $s"; sleep 1; done; exit 1
84+
Oneshot true
85+
Exit_After_Oneshot true
86+
Propagate_Exit_Code true
87+
88+
[OUTPUT]
89+
Name stdout
90+
Match *
91+
```
92+
93+
`fluent-bit` will output
94+
95+
```
96+
[0] exec_oneshot_demo: [[1681702172.950574027, {}], {"exec"=>"count: 1"}]
97+
[1] exec_oneshot_demo: [[1681702173.951663666, {}], {"exec"=>"count: 2"}]
98+
[2] exec_oneshot_demo: [[1681702174.953873724, {}], {"exec"=>"count: 3"}]
99+
[3] exec_oneshot_demo: [[1681702175.955760865, {}], {"exec"=>"count: 4"}]
100+
[4] exec_oneshot_demo: [[1681702176.956840282, {}], {"exec"=>"count: 5"}]
101+
[5] exec_oneshot_demo: [[1681702177.958292246, {}], {"exec"=>"count: 6"}]
102+
[6] exec_oneshot_demo: [[1681702178.959508200, {}], {"exec"=>"count: 7"}]
103+
[7] exec_oneshot_demo: [[1681702179.961715745, {}], {"exec"=>"count: 8"}]
104+
[8] exec_oneshot_demo: [[1681702180.963924140, {}], {"exec"=>"count: 9"}]
105+
[9] exec_oneshot_demo: [[1681702181.965852990, {}], {"exec"=>"count: 10"}]
106+
```
107+
108+
then exit with exit code 1.
109+
110+
Translation of command exit code(s) to `fluent-bit` exit code follows
111+
[the usual shell rules for exit code handling](https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html).
112+
Like with a shell, there is no way to differentiate between the command exiting
113+
on a signal and the shell exiting on a signal, and no way to differentiate
114+
between normal exits with codes greater than 125 and abnormal or signal exits
115+
reported by fluent-bit or the shell. Wrapped commands should use exit codes
116+
between 0 and 125 inclusive to allow reliable identification of normal exit.
117+
If the command is a pipeline, the exit code will be the exit code of the last
118+
command in the pipeline unless overridden by shell options.
119+
120+
### Parsing command output
121+
122+
By default the `exec` plugin emits one message per command output line, with a
123+
single field `exec` containing the full message. Use the `Parser` directive to
124+
specify the name of a parser configuration to use to process the command input.
125+
126+
### Security concerns
127+
128+
**Take great care with shell quoting and escaping when wrapping commands**.
129+
A script like
130+
131+
```bash
132+
#!/bin/bash
133+
# This is a DANGEROUS example of what NOT to do, NEVER DO THIS
134+
exec fluent-bit \
135+
-o stdout \
136+
-i exec \
137+
-p exit_after_oneshot=true \
138+
-p propagate_exit_code=true \
139+
-p command='myscript $*'
140+
```
141+
142+
can ruin your day if someone passes it the argument
143+
`$(rm -rf /my/important/files; echo "deleted your stuff!")'`
144+
145+
The above script would be safer if written with:
146+
147+
```bash
148+
-p command='echo '"$(printf '%q' "$@")" \
149+
```
150+
151+
... but it's generally best to avoid dynamically generating the command or
152+
handling untrusted arguments to it at all.

0 commit comments

Comments
 (0)