command module and --sudo

Hi folks,

I am evaluating ansible 0.7.2 (using the Ubuntu PPA packages).

My first attempt at remote execution already failed. :frowning:
User 'madduck' may run `apt-get update` on arnold.madduck.net, using
sudo without a password.

But if I run

  ansible -v arnold.madduck.net -a "/usr/bin/apt-get update" --sudo

it fails:

  arnold.madduck.net | FAILED >> {
      "failed": true,
      "msg": "\r\n\nSorry, user madduck is not allowed to execute '/bin/zsh -c /home/madduck/.ansible/tmp/ansible-1350291485.22-74945524909437/command' as root on arnold.madduck.net.\r\n",
      "parsed": false
  }

The reason is obvious: ansible calls sudo and passes it $SHELL,
calling a script (that is actually Python).

This raises two questions:

  1. The docs explicitly say: "It [the command] will not be
     processed through the shell…", and yes, either the Python
     script, nor the command itself is processed through the shell,
     and so the documentation is right. But why is the shell even
     invoked? It seems like Paramiko or whatever executes the
     command through the SSH session could just call the Python
     script directly.

  2. In combination with --sudo, the way this works means that
     I have to give the remote user full rights with sudo
     (user = (ALL) ALL). This kind of defeats the purpose, I think.

     Since the raw module also invokes the shell (!?), there seems
     to be no way to directly execute commands through ansible,
     without a shell. In combination with --sudo, this means that it
     is not possible to use ansible with a tightened sudo setup, or
     is it?

Of course I can just specify 'sudo' as command manually or write
a connection plugin to do things differently, but I'd really rather
not have to customise core behaviour before even starting to use
your software.

Therefore, I would appreciate if you would consider my case. Could
it be that the invocation of the shell is a little too ubiquitous?
Or am I overlooking something obvious? Or is this actually designed
as desired and ansible does not fit my use case?

Thanks for your time,

The reason is obvious: ansible calls sudo and passes it $SHELL,
calling a script (that is actually Python).

So your sudo is not configured to let you run your shell. I
understand, though even if we were executing

This raises two questions:

  1. The docs explicitly say: "It [the command] will not be
     processed through the shell…", and yes, either the Python
     script, nor the command itself is processed through the shell,
     and so the documentation is right. But why is the shell even
     invoked? It seems like Paramiko or whatever executes the
     command through the SSH session could just call the Python
     script directly.

This states that that command module does not intrepret the "-a"
through the shell, and if you are using ">" and so on, you should use
the 'shell' module.

You are correct that it would be technically possible to rip the
interpreter line out of the top of the module if present and just run
that, but it seems a lot cleaner to just rely on the interpreter line.

  2. In combination with --sudo, the way this works means that
     I have to give the remote user full rights with sudo
     (user = (ALL) ALL). This kind of defeats the purpose, I think.

     Since the raw module also invokes the shell (!?), there seems
     to be no way to directly execute commands through ansible,
     without a shell. In combination with --sudo, this means that it
     is not possible to use ansible with a tightened sudo setup, or
     is it?

There's the raw module, but this doesn't provide you access to the
resource model.

Anyway, I think what you're asking for, executing the interpreter
directly versus the shell, doesn't buy you anything. Python is at
least as powerful, if not more, than your configured shell.

Of course I can just specify 'sudo' as command manually or write
a connection plugin to do things differently, but I'd really rather
not have to customise core behaviour before even starting to use
your software.

It doesn't sound like you are using core behavior at all to me, as
your sudo file is non-stock.

That being said, it's not really a use case I see us carrying about
very much as it's the first I've heard of anyone wanting to constrain
this.

It seems fairly nonsensical to try, as the goal of this is something
that can run arbitrary commands, restart services, create users, and
so on.

To do this, if you are using "sudo:", which you don't have to do of
course, it means you need to pick a user that can actually the execute
things ansible needs to do.

Dear Michael,

unfortunately, Google Groups didn't want me to get your message by
mail, so I only found it in the forums now. Furthermore, since
Google Groups don't expose the message ID, I cannot properly reply
to your message.

Anyway, thank you for your reply on 15 October:

  https://groups.google.com/forum/?fromgroups=#!topic/ansible-project/ccZ72NSJr2Q

Let me pick up your points:

1. Your first sentence is incomplete, but I think I know what you
   were trying to say. Yes, indeed, you would be running the
   temporary Python script from sudo, which is almost as permissive
   as allow sudo to invoke a shell, and I can imagine that even
   passing sudo to subprocess.Popen wouldn't work because the script
   might need root rights to check for existence or absence of
   a file (command module), at the very least the raw module should
   do what I want:

     -m raw -a '/usr/sbin/apt-get update' --sudo

   I don't really need to be able to use --sudo and would be happy
   to run

     -m raw -a '/usr/bin/sudo apt-get update'

   instead, but it does seem to me like there's also a shell
   invoked.

2. This brings me to the second point: you do not need a shell to
   execute scripts on Unix according to the interpreter line
   ("shebang line"). This is a function of the linker. You can just
   call the script directly and it will be executed using Python.
   The shell is *not* needed.

   The reason why I think the shell should thus not be invoked is
   simply a question of overhead. Your approach will use more memory
   and take longer.

3. It's true that recent desktop-oriented Linux distributions have
   turned sudo into an all-purpose setuid wrapper. However, this is
   not what it was designed for. If a user may use sudo to gain root
   access for anything, you might just as well provide a setuid
   shell. In my experience, it's better to disable the root account,
   force all administration through sudo, disable direct execution
   of a shell, and spend some time to configure and maintain the set
   of allowed commands. This gives you some poor-man's-auditing, can
   be used to ensure policy and serves as a safety belt.

   There is no reason that ansible needs to be able to do everything
   as root on the target system when an adequate sudo policy is in
   place.

   It's sad that you rule out my use-case.

Thanks,

   There is no reason that ansible needs to be able to do everything
   as root on the target system when an adequate sudo policy is in
   place.

   It's sad that you rule out my use-case.

We can't do everything.

I'd prefer we are great for 75% of everyone, than acceptable for 100%
of everyone.

Thanks i found this post, was fighting with Ansible, checking there should be some option to run it plane with invoking $SHELL,
now i got know its not possible, i will run it in command: with stdin password,
pls let me know if this is fixed, means if there is an option to exclude shell.

I’m not sure I understand the question, can you show an example of what you want, how it fails and how you expect it to work?