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

Use sudo for privileged process checks on filedescriptors #715

Merged
merged 2 commits into from
Feb 1, 2018
Merged

Use sudo for privileged process checks on filedescriptors #715

merged 2 commits into from
Feb 1, 2018

Conversation

pdecat
Copy link
Contributor

@pdecat pdecat commented Aug 29, 2017

What does this PR do?

Repackaged the patch I suggested at DataDog/dd-agent#2033 (comment) in a dd-agent-omnibus compatible way (no additional python file, only process/check.py is modified).

Motivation

Datadog does not provide out of box support for monitoring file descriptors used by processes not running under the same user (dd-agent by default).

The suggested work-around of running the datadog agent as root is explicitly not recommended which is probably reasonable: https://help.datadoghq.com/hc/en-us/articles/115000066506-Why-don-t-I-see-the-system-processes-open-file-descriptors-metric-

Additional Notes

This requires the addition of the following sudo policies in the deb and rpm packages:

dd-agent ALL=NOPASSWD: /opt/datadog-agent/embedded/bin/python /opt/datadog-agent/agent/checks.d/process.py num_fds *
dd-agent ALL=NOPASSWD: /opt/datadog-agent/embedded/bin/python /opt/datadog-agent/agent/checks.d/process.pyc num_fds *

Usage of sudo generates frequent logging in /var/log/auth.log. That may be silenced with additional PAM rules in /etc/pam.d/sudo if desired.

Resolves DataDog/dd-agent/issues#2033

The same may be done for the io_counters method.

@bits-bot
Copy link
Collaborator

@pdecat, thanks for your PR! By analyzing the history of the files in this pull request, we identified @masci and @truthbk to be potential reviewers.

@gmmeyer
Copy link
Contributor

gmmeyer commented Oct 26, 2017

Hey @pdecat! Thanks a lot for your contribution!

This is a good idea but I am not sure that it should be turned on by default in the package. I am wary about giving our agent any sudo power that it doesn't absolutely need. So I don't think this should be turned on by default in the packages. Can you add instructions to turn it on in the readme and in the case of failure after attempting to use sudo.

Thanks a lot, again, for your contribution! 😄

@pdecat
Copy link
Contributor Author

pdecat commented Oct 26, 2017

Hi @gmmeyer , I'll document the sudoers part in the README.

Also, what would you think about adding an option to the process check's configuration to enable the use of sudo, disabled by default? That would avoid failed sudo executions in case the sudoers part is not set up.

@gmmeyer
Copy link
Contributor

gmmeyer commented Oct 31, 2017

I think that's very wise, it shouldn't fail when it doesn't have the proper permissions. It should log something on info but not fail.

Copy link
Contributor

@gmmeyer gmmeyer left a comment

Choose a reason for hiding this comment

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

Hey @pdecat! Thanks again for this PR!

This is a cool solution. I have two comments, and after you resolve them in one way or another I'm pretty happy to merge.

process/check.py Outdated
if method == 'num_fds' and Platform.is_unix():
try:
# It is up the agent's packager to grant corresponding sudo policy on unix platforms
result = int(subprocess.check_output(['sudo', sys.executable, __file__, method, str(process.pid)]))
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a cool solution but I am not certain it will work with Agent6, where we're calling the python library from within golang. At least for now, you'd have to ensure this happens only in Agent5. You can import the version from here: https://github.com/DataDog/dd-agent/blob/master/config.py#L44.

@masci how do you think we would be able to do this in Agent6?

Copy link
Contributor

Choose a reason for hiding this comment

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

As a second note here, why did you choose to execute this file rather than including that as a string that would be passed to the interpreter? I think that's more likely to work in Agent6 than this is.

Copy link
Contributor Author

@pdecat pdecat Dec 19, 2017

Choose a reason for hiding this comment

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

Hi @gmmeyer, I chose to invoke this script on purpose for two reasons:

  1. For security reasons: passing the process id to this script requires wildcards. Knowing that this script can only accept a process id and not anything else feels safe to me.
    Passing an arbitrary string to an interpreter with a wildcard has dangerous implications: https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-4-wildcards/
    An alternative may be to have several sudoers entries to match all possible pid lengths:
dd-agent ALL=NOPASSWD: /opt/datadog-agent/embedded/bin/python -c "import psutil; import sys; psutil.num_fds(sys.argv[1])" [1-9]
dd-agent ALL=NOPASSWD: /opt/datadog-agent/embedded/bin/python -c "import psutil; import sys; psutil.num_fds(sys.argv[1])" [1-9][0-9]
dd-agent ALL=NOPASSWD: /opt/datadog-agent/embedded/bin/python -c "import psutil; import sys; psutil.num_fds(sys.argv[1])" [1-9][0-9][0-9]
dd-agent ALL=NOPASSWD: /opt/datadog-agent/embedded/bin/python -c "import psutil; import sys; psutil.num_fds(sys.argv[1])" [1-9][0-9][0-9][0-9]
dd-agent ALL=NOPASSWD: /opt/datadog-agent/embedded/bin/python -c "import psutil; import sys; psutil.num_fds(sys.argv[1])" [1-6][0-5][0-9][0-9][0-9]
  1. For easy distribution: as the omnibus packaging rename files, this solution should work everywhere, no need to know the path to the script.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, so that makes sense. However, in Agent v6 we're not using a python interpreter, though, it's embedded within a go application. I think (I haven't verified this) that this would just call the go application instead of the python interpreter.

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 tested github.com/sbinet/go-python that is used in agent 6 to wrap the python interpreter and it seems to be ok:

main.go:

package main

import (
        "fmt"
        "log"

        "github.com/sbinet/go-python"
)

func init() {
        err := python.Initialize()
        if err != nil {
                log.Panic(err.Error())
        }
}

func main() {
        module := python.PyImport_ImportModule("testsys")
        if module == nil {
                log.Fatal("could not import 'testsys'")
        }

        name := module.GetAttrString("__name__")
        if name == nil {
                log.Fatal("could not getattr '__name__'")
        }
        defer name.DecRef()
        fmt.Printf("testsys.__name__: %q\n", python.PyString_AsString(name))

        testsys := module.GetAttrString("testsys")
        if testsys == nil {
                log.Fatal("could not getattr 'testsys'")
        }
        defer testsys.DecRef()

        o1 := testsys.CallFunction()
        if o1 == nil {
                log.Fatal("could not call 'testsys.testsys()'")
        }
        fmt.Printf("%s\n", python.PyString_AsString(o1))
        o1.DecRef()
}

testsys.py:

#!/usr/bin/env python2

import sys

def testsys():
    return "sys.executable=" + sys.executable

Result:

# PYTHONPATH=.:$PYTHONPATH go run ./main.go 
testsys.__name__: "testsys"
sys.executable=/usr/bin/python

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm down to merge this then! I'll approve it!

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you rebase it and then I'll approve, sorry for taking so long on this 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No prob, rebased!

However, I did not yet implement the part about adding an option to the process check's configuration to enable the use of sudo, disabled by default.

@pdecat
Copy link
Contributor Author

pdecat commented Jan 18, 2018

Added try_sudo setting with some documentation.

Copy link
Contributor

@gmmeyer gmmeyer left a comment

Choose a reason for hiding this comment

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

🎉 we're gonna merge!

@gmmeyer gmmeyer added this to the 5.22 milestone Feb 1, 2018
@zippolyte zippolyte merged commit e1f1d53 into DataDog:master Feb 1, 2018
@pdecat pdecat deleted the f-process-check-with-sudo branch February 1, 2018 19:24
@pdecat
Copy link
Contributor Author

pdecat commented Feb 1, 2018

Thanks! 🎉

ChristineTChen added a commit that referenced this pull request Feb 9, 2018
…)"

This reverts commit e1f1d53.

Check is not sending the open_file_descriptor metric. Reverting for 5.22.0 release.
ChristineTChen added a commit that referenced this pull request Feb 9, 2018
…)"

This reverts commit e1f1d53.

Check is not sending the open_file_descriptor metric. Reverting for 5.22.0 release.
hush-hush pushed a commit that referenced this pull request Feb 9, 2018
…)"

This reverts commit e1f1d53.

Check is not sending the open_file_descriptor metric. Reverting for 5.22.0 release.
@pdecat pdecat restored the f-process-check-with-sudo branch February 14, 2018 12:48
@pdecat
Copy link
Contributor Author

pdecat commented Feb 14, 2018

Hi @hush-hush / @ChristineTChen, I get that this was reverted for 5.22.

What issues did you have?

Did you enable the sudo part to actually get open_file_descriptor metrics?

@jippi
Copy link

jippi commented Mar 12, 2018

Bump ^ @hush-hush @ChristineTChen

@pdecat
Copy link
Contributor Author

pdecat commented Mar 12, 2018

Re-submitted this PR as #1235

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants