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

[Heartbeat] Setuid to regular user / lower capabilities when possible #27878

Merged
merged 51 commits into from
Oct 13, 2021
Merged
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
88d2d1d
Checkpoint
andrewvc Sep 11, 2021
66d2e6b
Checkpoint
andrewvc Sep 11, 2021
f050f79
Checkpoint
andrewvc Sep 11, 2021
dbe92db
Add comment
andrewvc Sep 11, 2021
7413b0e
Fix unncessary changes
andrewvc Sep 11, 2021
0d791d9
Fix unncessary changes
andrewvc Sep 11, 2021
992a3c6
Cleanup
andrewvc Sep 11, 2021
f938856
Add license override
andrewvc Sep 11, 2021
58ef9a3
Be more particular
andrewvc Sep 11, 2021
b295517
Tweaks
andrewvc Sep 11, 2021
206b346
Checkpoint
andrewvc Sep 12, 2021
576ca31
Checkpoint
andrewvc Sep 13, 2021
7e26638
Checkpoint
andrewvc Sep 13, 2021
61ae19c
SECCOMP Checkpoint
andrewvc Sep 13, 2021
fa24f7e
More fixes
andrewvc Sep 13, 2021
61542a0
Cleanup and fixes
andrewvc Sep 13, 2021
eaadc02
More fixes
andrewvc Sep 13, 2021
2835b98
CHANGELOG
andrewvc Sep 13, 2021
faa0989
More tweaks
andrewvc Sep 13, 2021
84d7eac
Rename seccomp->security
andrewvc Sep 13, 2021
ddbbf6e
Fix overrides
andrewvc Sep 13, 2021
1623137
Fix seccomp.go
andrewvc Sep 14, 2021
e1799f6
Cleanup
andrewvc Sep 14, 2021
94f95e4
Merge remote-tracking branch 'origin/master' into root-caps
andrewvc Sep 14, 2021
bf90094
Fix lint
andrewvc Sep 14, 2021
d055eb7
Fix lint
andrewvc Sep 14, 2021
7ba5301
separate setcaps
andrewvc Sep 14, 2021
f757217
Apply security to regular heartbeat too
andrewvc Sep 14, 2021
9b7c6e6
Only lookup groups etc. on linux
andrewvc Sep 14, 2021
793214e
Use simpler logic
andrewvc Sep 14, 2021
0aa410c
Fix lint
andrewvc Sep 14, 2021
c9532f3
Make portable to win/darwin
andrewvc Sep 20, 2021
cee1ad6
Fix setcap notation
andrewvc Sep 21, 2021
de41310
Make debugging build failure simpler
andrewvc Sep 21, 2021
3cafd9c
Merge branch 'master' into root-caps
mergify[bot] Sep 21, 2021
1ad68d3
Merge branch 'master' into root-caps
mergify[bot] Sep 22, 2021
7cddfa8
Merge branch 'master' into root-caps
mergify[bot] Sep 23, 2021
1a90113
Only target linux x86/amd64
andrewvc Sep 27, 2021
9dcd749
Merge branch 'root-caps' of github.com:andrewvc/beats into root-caps
andrewvc Sep 27, 2021
735aa76
Merge remote-tracking branch 'origin/master' into root-caps
andrewvc Sep 27, 2021
ea805d9
Fix setcap syntax
andrewvc Sep 27, 2021
0a292ee
Fix extra trailing slash
andrewvc Sep 27, 2021
bdc4c19
Fix setcap
andrewvc Sep 28, 2021
6a49b88
Follow link for setcap
andrewvc Sep 30, 2021
64a9d9e
fix
andrewvc Sep 30, 2021
c55cd77
Finalize
andrewvc Oct 1, 2021
7c2fc33
Merge remote-tracking branch 'origin/master' into root-caps
andrewvc Oct 1, 2021
d5da29c
Remove stdout
andrewvc Oct 1, 2021
39218ae
Incorporate PR feedback
andrewvc Oct 1, 2021
393bd27
Merge remote-tracking branch 'origin/master' into root-caps
andrewvc Oct 12, 2021
70fcce6
Update heartbeat security
andrewvc Oct 12, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Checkpoint
andrewvc committed Sep 11, 2021
commit f050f79263a2c6462b4c6107a78985c871074820
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@ FROM {{ .from }}
# Contains the elastic agent image variant, an empty string for the standard variant
# or "complete" for the bigger one.
ENV ELASTIC_AGENT_IMAGE_VARIANT={{.Variant}}
ENV BEAT_LOCAL_USER={ .user }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we call this just LOCAL_USER? I assume it could apply to any subprocess, it does not have to be a Beat? Or LOCAL_USER_SUBPROCESS?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've renamed it to BEAT_SETUID_AS I think it should be obscure and not something with any risk of clashing.


{{- if contains .from "ubi-minimal" }}
RUN for iter in {1..10}; do microdnf update -y && microdnf install -y shadow-utils jq && microdnf clean all && exit_code=0 && break || exit_code=$? && echo "microdnf error: retry $iter in 10s" && sleep 10; done; (exit $exit_code)
2 changes: 2 additions & 0 deletions dev-tools/packaging/templates/docker/Dockerfile.tmpl
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@ FROM {{ .buildFrom }} AS home

COPY beat {{ $beatHome }}

ENV BEAT_LOCAL_USER={ .user }

RUN mkdir -p {{ $beatHome }}/data {{ $beatHome }}/logs && \
chown -R root:root {{ $beatHome }} && \
find {{ $beatHome }} -type d -exec chmod 0755 {} \; && \
1 change: 0 additions & 1 deletion heartbeat/monitors/active/icmp/stdloop.go
Original file line number Diff line number Diff line change
@@ -392,7 +392,6 @@ func createListener(name, network string) *icmp.PacketConn {
// XXX: need to check for conn == nil, as 'err != nil' seems always to be
// true, even if error value itself is `nil`. Checking for conn suppresses
// misleading log message.
fmt.Printf("LISTEN NOW %s\n", err)
//os.Exit(123)
andrewvc marked this conversation as resolved.
Show resolved Hide resolved
if conn == nil && err != nil {
return nil
70 changes: 35 additions & 35 deletions x-pack/heartbeat/seccomp_linux.go
Original file line number Diff line number Diff line change
@@ -7,7 +7,9 @@ package main
import (
"fmt"
"os"
"os/user"
"runtime"
"strconv"

"github.com/elastic/beats/v7/libbeat/common/seccomp"
"kernel.org/pub/linux/libs/security/libcap/cap"
@@ -16,53 +18,51 @@ import (
func init() {
switch runtime.GOARCH {
case "amd64", "386":
// We require a number of syscalls to run. This list was generated with
// mage build && env ELASTIC_SYNTHETICS_CAPABLE=true strace --output=syscalls ./heartbeat --path.config sample-synthetics-config/ -e
// then filtered through: cat syscalls | cut -d '(' -f 1 | egrep '\w+' -o | sort | uniq | xargs -n1 -IFF echo \"FF\"
// We should tighten this up before GA. While it is true that there are probably duplicate
// syscalls here vs. the base, this is probably OK for now.
var err error
if os.Getuid() == 0 {
err = cap.SetUID(1000)
if localUserName := os.Getenv("BEAT_LOCAL_USER"); localUserName != "" {
localUser, err := user.Lookup(localUserName)
if err != nil {
panic(fmt.Sprintf("could not lookup BEAT_LOCAL_USER=%s: %s", localUser, err))
}
localUserUid, err := strconv.Atoi(localUser.Uid)
if err != nil {
panic(err)
panic(fmt.Sprintf("could not parse UID '%s' as int: %s", localUser.Uid, err))
}

err = cap.SetUID(localUserUid)
if err != nil {
panic(fmt.Sprintf("could not setuid to %d: %s", localUserUid, err))
}

// Start with an empty capability set
newcaps := cap.NewSet()
/*
err = newcaps.SetFlag(cap.Effective, false, cap.CHOWN, cap.DAC_OVERRIDE, cap.DAC_READ_SEARCH, cap.FOWNER, cap.FSETID, cap.KILL, cap.SETGID, cap.SETUID, cap.SETPCAP, cap.LINUX_IMMUTABLE, cap.SYS_MODULE, cap.SYS_CHROOT, cap.SYS_PTRACE, cap.SYS_PACCT, cap.SYS_ADMIN, cap.SETUID)
err = newcaps.SetFlag(cap.Effective, false, cap.CHOWN, cap.DAC_OVERRIDE, cap.DAC_READ_SEARCH, cap.FOWNER, cap.FSETID, cap.KILL, cap.SETGID, cap.SETUID, cap.SETPCAP, cap.LINUX_IMMUTABLE, cap.SYS_MODULE, cap.SYS_CHROOT, cap.SYS_PTRACE, cap.SYS_PACCT, cap.SYS_ADMIN, cap.SETUID)
err = newcaps.SetFlag(cap.Effective, false, cap.CHOWN, cap.DAC_OVERRIDE, cap.DAC_READ_SEARCH, cap.FOWNER, cap.FSETID, cap.KILL, cap.SETGID, cap.SETUID, cap.SETPCAP, cap.LINUX_IMMUTABLE, cap.SYS_MODULE, cap.SYS_CHROOT, cap.SYS_PTRACE, cap.SYS_PACCT, cap.SYS_ADMIN, cap.SETUID)
if err != nil {
panic(err)
}
*/
err = newcaps.SetFlag(cap.Effective, true, cap.NET_RAW, cap.NET_BIND_SERVICE)
err = newcaps.SetFlag(cap.Inheritable, false, cap.NET_RAW, cap.NET_BIND_SERVICE)
// Both permitted and effective are required! Permitted makes the permmission
// possible to get, effective makes it 'active'
err = newcaps.SetFlag(cap.Permitted, true, cap.NET_RAW, cap.NET_BIND_SERVICE)
if err != nil {
panic(err)
panic(fmt.Sprintf("error setting permitted setcap: %s", err))
}
newcaps.SetProc()
err = newcaps.SetFlag(cap.Effective, true, cap.NET_RAW, cap.NET_BIND_SERVICE)
if err != nil {
panic(err)
panic(fmt.Sprintf("error setting effective setcap: %s", err))
}
curcaps := cap.GetProc()
e, _ := curcaps.GetFlag(cap.Effective, cap.NET_RAW)
i, _ := curcaps.GetFlag(cap.Inheritable, cap.NET_RAW)
p, _ := curcaps.GetFlag(cap.Permitted, cap.NET_RAW)

fmt.Printf("\nCHECK EIP=%v|%v|%v mode:%v\n", e, i, p, cap.GetMode())
fmt.Printf("CAPS=%v | %s\n", curcaps, curcaps)
fmt.Printf("NCAPS=%v | %s\n", newcaps, newcaps)
// We do not want these capabilities to be inherited by subprocesses
err = newcaps.SetFlag(cap.Inheritable, false, cap.NET_RAW, cap.NET_BIND_SERVICE)
if err != nil {
panic(fmt.Sprintf("error setting inheritable setcap: %s", err))
}

/*
err = cap.SetUID(0)
if err != nil {
panic(err)
}
*/
newcaps.SetProc()
if err != nil {
panic(fmt.Sprintf("error setting new process capabilities via setcap: %s", err))
}
}

// We require a number of syscalls to run. This list was generated with
// mage build && env ELASTIC_SYNTHETICS_CAPABLE=true strace --output=syscalls ./heartbeat --path.config sample-synthetics-config/ -e
// then filtered through: cat syscalls | cut -d '(' -f 1 | egrep '\w+' -o | sort | uniq | xargs -n1 -IFF echo \"FF\"
// We should tighten this up before GA. While it is true that there are probably duplicate
// syscalls here vs. the base, this is probably OK for now.
syscalls := []string{
"access",
"arch_prctl",
Loading