Rex
Rex copied to clipboard
sudo TRUE; - code gets stuck
When I set sudo TRUE; running rex got stuck. Using -d I fund that the problem is this command
sudo -p '' -S sh -c "LC_ALL=C ; export LC_ALL; which perl "
being stuck. (It does not even ask for password, probably because of the -p '')
All this because I was trying to restrict the command the user can execute using sudo.
I can, of course, add sudo to the individual commands I execute, but I am not sure if this behaviour is correct. shouldn't sudo TRUE;
mean every user-generated command is executed with sudo?
Why are the internal Rex-commands executed with sudo?
Hi,
indeed, if sudo TRUE
is set, every command gets executed with sudo, not only the commands the user wants to execute in a task.
If you only want to execute some commands with sudo you can do the following:
user "someuser";
sudo_password "the-sudo-password-if-there-is-one";
task "mytask", group => "myserver", sub {
sudo sub {
run "execute with sudo";
pkg "vim-enhanced", ensure => "present"; # also executes with sudo
};
};
But for sudo, rex is always executing the sudo command with /bin/sh. So currently it is not possible to limit the commands that can be executed with sudo.
There is a feature flag called: sudo_without_sh
(http://www.rexify.org/howtos/backward_compatibility.html). With this enabled it is possible to limit the commands, but this will prevent some commands to work correctly (especially file editing).
What we can do, to prevent freezing, we can add a timeout to the which perl
command, so that we can detect if sudo needs a password, and then we can display a proper error message.
Such timeout would be great for every command. Not just the internal Rex commands. If the length of the timeout was user configurable, that would be probably even better. Oh I just saw I got a response to a related question I asked on the mailing list: https://groups.google.com/forum/#!topic/rex-users/TT9dwfFvxfE
There's also a timeout
setting for "the ssh connection and other network related stuff", described on this page. Nevertheless the timeout
option for run
needs to be included in the documentation (and we need to fix the searchbox, thanks for reporting @szabgab! ;)
At the same time, I would prefer to determine whether sudo needs a password in a different way. If there is something that directly checks for it, that would be the best option IMHO (unfortunately nothing like this comes to my mind instantly). As a second option we could try detecting the password prompt, and if there's no sudo_password
specified, then we could throw an error about it.
Or if we would like to wait for something to timeout, it might be a good idea to run something very simple that is as closely related to the issue as possible, like sudo -l
or sudo -v
(i.e. to check if sudo itself times out, not the command it tries to run).
We might only need to run this check when there's no sudo_password
specified but sudo
is turned on.
In the pass_auth
cases, we can also try and fallback to use the user's password
as sudo_password
first, when it is not specified directly.
user "someuser";
sudo_password "the-sudo-password-if-there-is-one";
task "mytask", group => "myserver", sub { sudo sub { run "execute with sudo"; pkg "vim-enhanced", ensure => "present"; # also executes with sudo }; };
But for sudo, rex is always executing the sudo command with /bin/sh. So currently it is not possible to limit the commands that can be executed with sudo.
do you mean every sudo will use sh?
even if I write run "sudo command"
?
@szabgab no, if you use the "run" command, it will execute it the way you write it.
run "sudo id";
Will result in something like:
PATH=/bin/:/usr/bin:/and/some/other/paths/considered/safe sudo id
No way, this is not working. I'm trying
desc "Install git";
task "git", group => "fiware", sub {
run "sudo apt-get install git";
};
and it still gets stuck. Also whatever has been mentioned above.
@JJ
Could you please paste the output of rex -d git
?
But please remove all passwords and other secret things from the output.
Thanks
[2014-11-30 12:34:58] DEBUG - Command Line Parameters [2014-11-30 12:34:58] DEBUG - d = 1
[2014-11-30 12:34:58] DEBUG - Rexfile exists [2014-11-30 12:34:58] DEBUG - Checking Rexfile Syntax... [2014-11-30 12:34:58] DEBUG - Found Rexfile.lock [2014-11-30 12:34:58] DEBUG - Found stale lock file. Removing it. [2014-11-30 12:34:58] DEBUG - Creating lock-file (Rexfile.lock) [2014-11-30 12:34:58] DEBUG - Including/Parsing Rexfile [2014-11-30 12:34:58] DEBUG - Registering task: Rex::CLI::git [2014-11-30 12:34:58] DEBUG - Creating new distribution class of type: Base [2014-11-30 12:34:58] DEBUG - new distribution class of type Rex::TaskList::Base created. [2014-11-30 12:34:58] DEBUG - Creating task: git [2014-11-30 12:34:58] DEBUG - Registering task: Rex::CLI::docker [2014-11-30 12:34:58] DEBUG - Returning existing distribution class of type: Rex::TaskList::Base [2014-11-30 12:34:58] DEBUG - Creating task: docker [2014-11-30 12:34:58] DEBUG - Returning existing distribution class of type: Rex::TaskList::Base [2014-11-30 12:34:58] WARN - Task docker already exists. Overwriting... [2014-11-30 12:34:58] DEBUG - Creating task: docker [2014-11-30 12:34:58] DEBUG - eval your Rexfile. [2014-11-30 12:34:58] DEBUG - Returning existing distribution class of type: Rex::TaskList::Base [2014-11-30 12:34:58] DEBUG - Returning existing distribution class of type: Rex::TaskList::Base [2014-11-30 12:34:58] DEBUG - Returning existing distribution class of type: Rex::TaskList::Base [2014-11-30 12:34:58] DEBUG - Initializing Logger from parameters found in Rexfile [2014-11-30 12:34:58] DEBUG - Returning existing distribution class of type: Rex::TaskList::Base [2014-11-30 12:34:58] DEBUG - Running task: git [2014-11-30 12:34:58] DEBUG - Returning existing distribution class of type: Rex::TaskList::Base [2014-11-30 12:34:58] DEBUG - Returning existing distribution class of type: Rex::TaskList::Base [2014-11-30 12:34:58] INFO - Running task git on 130.206.127.211 [2014-11-30 12:34:58] DEBUG - $VAR1 = '';
[2014-11-30 12:34:58] DEBUG - $VAR1 = { 'auth_type' => 'pass', 'public_key' => undef, 'sudo_password' => '', 'sudo' => 0, 'port' => undef,
'user' => 'jjmerelo',
'private_key' => undef
};
[2014-11-30 12:34:58] DEBUG - Using Net::SSH2 for connection [2014-11-30 12:34:58] DEBUG - Using user: jjmerelo [2014-11-30 12:34:58] DEBUG - Using password: *********** [2014-11-30 12:34:58] INFO - Connecting to 130.206.127.211:22 (jjmerelo) [2014-11-30 12:34:58] DEBUG - Current Error-Code: 0 [2014-11-30 12:34:58] INFO - Connected to 130.206.127.211, trying to authenticate. [2014-11-30 12:34:58] DEBUG - Using password authentication. [2014-11-30 12:35:09] INFO - Successfully authenticated on 130.206.127.211. [2014-11-30 12:35:09] DEBUG - Executing: which perl [2014-11-30 12:35:09] DEBUG - Shell/Bash: Got options: [2014-11-30 12:35:09] DEBUG - $VAR1 = {};
[2014-11-30 12:35:09] DEBUG - SSH/executing: LC_ALL=C ; export LC_ALL; which perl [2014-11-30 12:35:09] DEBUG - /usr/bin/perl
[2014-11-30 12:35:09] DEBUG - Executing git [2014-11-30 12:35:09] DEBUG - Executing: sudo apt-get install git [2014-11-30 12:35:10] DEBUG - Shell/Bash: Got options: [2014-11-30 12:35:10] DEBUG - $VAR1 = { 'auto_die' => undef };
[2014-11-30 12:35:10] DEBUG - SSH/executing: LC_ALL=C ; export LC_ALL; PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/pkg/bin:/usr/pkg/sbin; export PATH; sudo apt-get install git
@JJ
could you please try to run "sudo apt-get -y install";
.
It seems that the command is waiting for some input.
You can also use the pkg() command to install packages:
desc "Install git";
task "git", group => "fiware", sub {
sudo sub {
pkg "git", ensure => 'present';
};
};
Tried that, and
install "git";
Same problem.
@JJ
if you login manually via ssh and run sudo apt-get install -y git
does it ask for a password?
I ran into this problem with sudo (on a mac) where it would hang and then was fixed by opening a new bash process. Here is what happened with me:
- ran a task with a command as sudo without providing sudo_passowrd
- rex hangs (as expected). Ctrl-c to exit.
- add
sudo_password the_password_here
to Rexfile. - run rex command again
- rex still hangs
- open new bash process.
- run rex command again
- it works!
To refresh my earlier comment above, there are quite a few options related to this topic.
Ideally we would be able to determine if sudo needs password or not:
- if there's a way to determine in advance whether sudo would ask for a password or not (without actually prompting for it), let's use that and either abort or prompt for it interactively
- otherwise, let's try to detect the output if it prompts for the password, and if there's no
sudo_password
set, fail with an error (current use ofsudo -p
might need to be changed; also using Expect wouldn't work on Windows, so would be nice to find some other way) - alternatively, let's first call something that is sudo only, like
sudo -l
or especiallysudo -v
and let it time out in the worst case - then let it fail with a nice message, or handle some fallback
Alternatively we could try detect potentially weird use cases before the first sudo command is called:
- if there's no
sudo_password
specified butsudo
is turned on, let's issue a warning/error, prompt for password (optionally with an "I know what I'm doing, I don't need no sudo password" setting that overrides this check) - if
pass_auth
is specified, we can also try and fallback to use the user'spassword
assudo_password
first, when the latter is not specified directly