perl sudo using Net::Openssh not working - perl

I am using salvas' Net::Openssh module, but not able to figure how to use sudo. I have tried the following, but it is not working...
There is nothing printed in results. Single word commands like ls, pwd are also not producing anything.
version of sudo on target system:
$ /usr/local/bin/sudo -V
CU Sudo version 1.5.7p2
$ /usr/local/bin/sudo -h
CU Sudo version 1.5.7p2
usage: /usr/local/bin/sudo -V | -h | -l | -v | -k | -H | [-b] [-p prompt] [-u username/#uid] -s | <command>
since CU sudo does not allow more than 1 option at a time, i supply -k before supplying the command.
please note that this sudo version does not have -S switch to pass password using stdin. so it expects password from terminal. can u pl help more. thx.
$ssh->system("$sudo_path -k");
my #output = $ssh->capture({tty => 1,
stdin_data => "$PASS"},
$sudo_path,
"-p",'', "$cmd");
print " result=#output \n";
OR
$ssh->system("$sudo_path -k");
my #output = $ssh->capture({stdin_data => "$PASS"},
$sudo_path,
"-p",'', "$cmd");
print " result=#output \n";

It would be more helpful if you explained more of what you were trying to accomplish in your question, but I'm assuming you're trying to run a command that requires sudo via ssh using the Net::OpenSSH module in perl.
If that is the case, you should consider trying a 'heredoc' to script a series of commands.
Here is the PerlDoc for Quote-Like operators - look for the area talking about <<EOF as I've often used here docs to script things like this.
If for some reason using a heredoc within the Net::OpenSSH command doesn't work - Net::OpenSSH also works with Expect as documented here.
And if for some reason that doesn't work for you, you could always create a shell script that runs the command with sudo via a heredoc on the remote system, and just execute that script via your Net::OpenSSH connection.

Related

Sending a command in Paramiko as sudo

How can I run a command in a linux box through Paramiko as a sudo user and send the sudo password alomg with it, then get the output?
I tried the following code but since it did not return the output ( I tried testing ls -l /root) I am not sure if it’s working or not.
stdin, stdout, stderr = ssh.exec_command("sudo ls -l")
stdin.write('sudo_password\n')
stdin.flush()
Output = stdout.read.splitlines()
A second question is that My understanding is that we cannot ”sudo -s” in the first command and then run the next commands as root while we have used a non-root command to start the session with at first, right?
(Imagine there is no root password on the box)
What is a functional piece of code to send a command as sudo, then provide the password and get the output?
What is a functional code to do the same thing for multiple commands? Can we send the password once and then use the it for the rest of the commands?
sudo on the target system is configured to require a terminal emulation for password prompt.
It suggests you to use -S switch to allow password input from the stdin (what you code is attempting to do). So do that.
thanks to everyone taking their time and posting their answers.
there is a straightforward answer to this question and here it is:
command = 'echo "sudo-password" | sudo <the-command-to-run-as-sudo>'
stdin, stdout, stderr = SESSION.exec_command(command)
stdout = stdout.read().decode()
example command:
command = 'echo "123456" | sudo ls-l /root'
stdin, stdout, stderr = SESSION.exec_command(command)
stdout = stdout.read().decode()

How to log the output along with error messages to a file while running a script on psql command line on Freebsd OS?

On RHEL, the below command works:
psql -h hostname -U username -p port_no -d database -f /tmp/myfile.sql &> logfile01.txt
On FreeBSD, this throws error:
"Invalid null command"
Please suggest.
If you use this only on the command line then there is no need to change the shell.
To redirect stdout and stderr to a file in C-Shell synthax simply use ">& filename".
Different story is, if you want to write shell scripts. Bourne Shell and it's clones (like i.e. Bash) are better suited for writing script. See this Unix FAQ "Csh Programming Considered Harmful": http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/
This redirection works in bash
&> logfile01.txt
, but it does not work in csh which is the default shell in FreeBSD.
# set | grep shell
shell /bin/csh
# ls -la &> logfile01.txt
Invalid null command.
Bash is not installed by default. You can install it
pkg install bash
and configure it as the default shell.

Standard Input setting after configuring process.launchPath = "/usr/bin/sudo" in swift [duplicate]

I'm writing a C Shell program that will be doing su or sudo or ssh. They all want their passwords in console input (the TTY) rather than stdin or the command line.
Does anybody know a solution?
Setting up password-less sudo is not an option.
expect could be an option, but it's not present on my stripped-down system.
For sudo there is a -S option for accepting the password from standard input. Here is the man entry:
-S The -S (stdin) option causes sudo to read the password from
the standard input instead of the terminal device.
This will allow you to run a command like:
echo myPassword | sudo -S ls /tmp
As for ssh, I have made many attempts to automate/script it's usage with no success. There doesn't seem to be any build-in way to pass the password into the command without prompting. As others have mentioned, the "expect" utility seems like it is aimed at addressing this dilemma but ultimately, setting up the correct private-key authorization is the correct way to go when attempting to automate this.
I wrote some Applescript which prompts for a password via a dialog box and then builds a custom bash command, like this:
echo <password> | sudo -S <command>
I'm not sure if this helps.
It'd be nice if sudo accepted a pre-encrypted password, so I could encrypt it within my script and not worry about echoing clear text passwords around. However this works for me and my situation.
For ssh you can use sshpass: sshpass -p yourpassphrase ssh user#host.
You just need to download sshpass first :)
$ apt-get install sshpass
$ sshpass -p 'password' ssh username#server
For sudo you can do this too:
sudo -S <<< "password" command
I've got:
ssh user#host bash -c "echo mypass | sudo -S mycommand"
Works for me.
The usual solution to this problem is setuiding a helper app that performs the task requiring superuser access:
http://en.wikipedia.org/wiki/Setuid
Sudo is not meant to be used offline.
Later edit: SSH can be used with private-public key authentication. If the private key does not have a passphrase, ssh can be used without prompting for a password.
Maybe you can use an expect command?:
expect -c 'spawn ssh root#your-domain.com;expect password;send "your-password\n";interact
That command gives the password automatically.
This can be done by setting up public/private keys on the target hosts you will be connecting to.
The first step would be to generate an ssh key for the user running the script on the local host, by executing:
ssh-keygen
Enter file in which to save the key (/home/myuser/.ssh/id_rsa): <Hit enter for default>
Overwrite (y/n)? y
Then enter a blank password. After that, copy your ssh key onto the target host which you will be connecting to.
ssh-copy-id <remote_user>#<other_host>
remote_user#other_host's password: <Enter remote user's password here>
After registering the ssh keys, you would be able to perform a silent ssh remote_user#other_host from you local host.
When there's no better choice (as suggested by others), then man socat can help:
(sleep 5; echo PASSWORD; sleep 5; echo ls; sleep 1) |
socat - EXEC:'ssh -l user server',pty,setsid,ctty
EXEC’utes an ssh session to server. Uses a pty for communication
between socat and ssh, makes it ssh’s controlling tty (ctty),
and makes this pty the owner of a new process group (setsid), so
ssh accepts the password from socat.
All of the pty,setsid,ctty complexity is necessary and, while you might not need to sleep as long, you will need to sleep. The echo=0 option is worth a look too, as is passing the remote command on ssh's command line.
Take a look at expect linux utility.
It allows you to send output to stdio based on simple pattern matching on stdin.
ssh -t -t me#myserver.io << EOF
echo SOMEPASSWORD | sudo -S do something
sudo do something else
exit
EOF
Set SSH up for Public Key Authentication, with no pasphrase on the Key. Loads of guides on the net. You won't need a password to login then. You can then limit connections for a key based on client hostname. Provides reasonable security and is great for automated logins.
echo <password> | su -c <command> <user>
This is working.
a better sshpass alternative is: passh
https://github.com/clarkwang/passh
Login to a remote server
$ passh -p password ssh user#host
Run a command on remote server
$ passh -p password ssh user#host date
other methods to pass the password
-p The password (Default: `password')
-p env: Read password from env var
-p file: Read password from file
here I explained why it is better than sshpass, and other solutions.
You can also pass various parameters as follows:
echo password | echo y | sudo -S pacman -Syu
(Although that's a bad idea, it's just an example)
I had the same problem. dialog script to create directory on remote pc.
dialog with ssh is easy. I use sshpass (previously installed).
dialog --inputbox "Enter IP" 8 78 2> /tmp/ip
IP=$(cat /tmp/ip)
dialog --inputbox "Please enter username" 8 78 2> /tmp/user
US=$(cat /tmp/user)
dialog --passwordbox "enter password for \"$US\" 8 78 2> /tmp/pass
PASSWORD = $(cat /tmp/pass)
sshpass -p "$PASSWORD" ssh $US#$IP mkdir -p /home/$US/TARGET-FOLDER
rm /tmp/ip
rm /tmp/user
rm /tmp/pass
greetings from germany
titus
Building on #Jahid's answer, this worked for me on macOS 10.13:
ssh <remote_username>#<remote_server> sudo -S <<< <remote_password> cat /etc/sudoers
I once had a use case where I needed to run Sudo and ssh in the same command without stdin specifying all the variables needed.
This is the command I used
echo sudopassword | sudo -S -u username sshpass -p extsshpassword ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no username#ipaddress " CMD on external machine"
Breaking that command into pieces!
This will allow you to run commands through your machine using Superuser:
echo password | sudo -S -u username
This will allow you to pass ssh password and execute commands on external machines:
sshpass -p sshpassword ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no username#ipaddress " CMD on external machine"
make sure you install the sudo and openssh packages on your machine.
One way would be to use read -s option .. this way the password characters are not echoed back to the screen. I wrote a small script for some use cases and you can see it in my blog:
http://www.datauniv.com/blogs/2013/02/21/a-quick-little-expect-script/
USE:
echo password | sudo command
Example:
echo password | sudo apt-get update; whoami
Hope It Helps..
You can provide password as parameter to expect script.
su -c "Command" < "Password"
Hope it is helpful.

How to send data to command line after calling .sh file?

I want to install Anaconda through EasyBuild. EasyBuild is a software to manage software installation on clusters. Anaconda can be installed with sh Anaconda.sh.
However, after running I have to accept the License agreement and give the installation location on the command line by entering <Enter>, yes <Enter>, path/where/to/install/ <Enter>.
Because this has to be installed automatically I want to do the accepting of terms and giving the install location in one line. I tried to do it like this:
sh Anaconda.sh < <(echo) >/dev/null < <(echo yes) >/dev/null \
< <(echo /apps/software/Anaconda/1.8.0-Linux-x86_64/) > test.txt
From the test.txt I can read that the first echo works as <Enter>, but I can't figure out how to accept the License agreement, as it sees it now as not sending yes:
Do you approve the license terms? [yes|no]
[no] >>> The license agreement wasn't approved, aborting installation.
How can I send the yes correctly to the script input?
Edit: Sorry, I missed the part about having to enter more then one thing. You can take a look at writing expect scripts. thegeekstuff.com/2010/10/expect-examples. You may need to install it however.
You could try piping with the following command: yes yes | sh Anaconda.sh. Read the man pages for more information man yes.
Expect is a great way to go and probably the most error proof way. If you know all the questions I think you could do this by just writing a file with the answers in the correct order, one per line and piping it in.
That install script is huge so as long as you can verify you know all the questions you could give this a try.
In my simple tests it works.
I have a test script that looks like this:
#!/bin/sh
echo -n "Do you accept "
read ANS
echo $ANS
echo -n "Install path: "
read ANS
echo $ANS
and an answers file that looks like this:
Y
/usr
Running it like so works... perhaps it will work for your monster install file as well.
cat answers | ./test.sh
Do you accept Y
Install path: /usr
If that doesn't work then the script is likely flushing and you will have to use expect or pexpect.
Good luck!
Actually, I downloaded and looked at the anaconda install script. Looks like it takes command line arguments.
/bin/bash Anaconda-2.2.0-Linux-x86_64.sh -h
usage: Anaconda-2.2.0-Linux-x86_64.sh [options]
Installs Anaconda 2.2.0
-b run install in batch mode (without manual intervention),
it is expected the license terms are agreed upon
-f no error if install prefix already exists
-h print this help message and exit
-p PREFIX install prefix, defaults to /home/cody.stevens/anaconda
Use the -b and -p options...
so use it like so:
/bin/bash Anaconda-2.2.0-Linux-x86_64.sh -b -p /usr
Also of note.. that script explicitly says not to run with '.' or 'sh' but 'bash' so they must have some dependency on a feature of bash.
--
Cody

perl run two system commands error

So in my script I need to make to calls to unix, and I do it via the system command like so:
system "bash -i -c 'addmothernode'";
...
perl code ...
...
system "bash -i -c 'addnode -ip=$_'";
However, whenever I run both of these commands in the same script, for some reason my process is stopped like this:
[1]+ Stopped perl boot.pl
And the script can only be finished when I run fg %1. When I only have one of these system calls in, the perl script finishes successfully. But I need both commands because they depend on each other. Anyone have any ideas about what's going on? Thanks!
UPDATE:
A lot of answers below are saying I don't need to use bash -i to run a system command, and I know typically this is true but I need to use aliases that I have created and if I do not use this the aliases won't be recognized. So I do need bash -i.
This problem is unrelated to perl. You can easily reproduce the situation if you start two bashes in the interactive mode (-i) one after another:
$ cat 1.sh
bash -i -c 'sleep 1'
bash -i -c 'sleep 1'
$ bash 1.sh
[1]+ Stopped bash 1.sh
Of course it would be better to run bash in the non-interactive mode (without -i) or run the program directly, without bash, but if you need for some reason bash -i you can protect its run with setsid:
$ cat 1.sh
setsid bash -i -c 'sleep 1'
setsid bash -i -c 'sleep 1'
echo done
$ bash 1.sh
done
The bash -i means run an interactive shell; so you have two shells both reading from the terminal.
Try removing the -i options.
system "addmothernode";
should work.
To execute a command, bash is not needed. The Perl system function is like the system C function, it calls by default sh.
man system
exec
The standard to which the caller conforms determines which shell is used. See standards(5).
Standard Shell Used
______________________________________________________________
1989 ANSI C, 1990 ISO C, 1999 ISO C, /usr/xpg4/bin/sh
POSIX.1 (1990-2001), SUS, SUSv2, SUSv3,
XPG4
POSIX.1 (1988), SVID3, XPG3, no standard /usr/bin/sh
specified