Remote execute bash scripts that needs input - linux

I am using SSH command to execute the bash scripts remotely:
ssh user#server 'bash -s' < $script_dir/script.sh
And inside the script.sh, I will have the command like below:
ssh-keygen -t rsa
ssh-copy-id postgres#$sqlserver
ssh postgres#$sqlserver -C true
And also
printf "Creating user in postgresql server...\n"
createuser -s -P username
Which need user's input, but I found when I execute the command from the remote server, it will skip getting the users' input and failed.
Another one is:
printf "Please enter your barman server name: \n" ; read -s barmanserver
Which cannot read user's input neither
I know that the script seems cannot read the other terminal's input, but can anyone help me find a solution if I need the user input to continue?
Thanks a lot!!
Eva

I have used something like this in the past. I am not quite sure why I installed sshpass though.
apt-get install sshpass -y
echo "Adding users to new VMs"
adduser adminuser
echo "changing user password"
echo "adminuser:password" | chpasswd
adduser adminuser sudo
It does work, but it gives you some warning.

Related

Running commands as different user from bash script

I have 2 users: usr1 and usr2. Neither is a root user.
usr1 starts a bash script. And from the script, I want to run some commands as usr2.
I understand that the way to do it is:
su -l <usr2> -c "command"
The issue is with passing the password. These are 2 different users with different privileges, so, skipping the password for usr2 is not an option.
This script can go interactive, and ask the user for the password. Is there a way to do this in bash script ?
Note: I am not an expert with scripting. And I have done some research before asking this question, but I couldnt find a suitable answer.
You can try using the read read man page command see example below:
#!/bin/bash
read -s -p "Enter your password: " pass
echo $pass
In that case you will need to use /bin/su -c along with sudo -S
#!/bin/bash
user=$1
read -s -p "Enter pass: " pass
cmd=$(echo $pass|sudo -S <some-command>)
su -c '$cmd' - $user
Where user=$1 additional bash argument, in this case the user id for usr2, then jut run it
$sudo bash -x ./password.sh <target-user>

How to get root access after ssh in a script? [duplicate]

I have a script which runs another script via SSH on a remote server using sudo. However, when I type the password, it shows up on the terminal. (Otherwise it works fine)
ssh user#server "sudo script"
What's the proper way to do this so I can type the password for sudo over SSH without the password appearing as I type?
Another way is to use the -t switch to ssh:
ssh -t user#server "sudo script"
See man ssh:
-t Force pseudo-tty allocation. This can be used to execute arbi-
trary screen-based programs on a remote machine, which can be
very useful, e.g., when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.
I was able to fully automate it with the following command:
echo pass | ssh -tt user#server "sudo script"
Advantages:
no password prompt
won't show password in remote machine bash history
Regarding security: as Kurt said, running this command will show your password on your local bash history, and it's better to save the password in a different file or save the all command in a .sh file and execute it. NOTE: The file need to have the correct permissions so that only the allowed users can access it.
Sudo over SSH passing a password, no tty required:
You can use sudo over ssh without forcing ssh to have a pseudo-tty (without the use of the ssh "-t" switch) by telling sudo not to require an interactive password and to just grab the password off stdin. You do this by using the "-S" switch on sudo. This makes sudo listen for the password on stdin, and stop listening when it sees a newline.
Example 1 - Simple Remote Command
In this example, we send a simple whoami command:
$ ssh user#server cat \| sudo --prompt="" -S -- whoami << EOF
> <remote_sudo_password>
root
We're telling sudo not to issue a prompt, and to take its input from stdin. This makes the sudo password passing completely silent so the only response you get back is the output from whoami.
This technique has the benefit of allowing you to run programs through sudo over ssh that themselves require stdin input. This is because sudo is consuming the password over the first line of stdin, then letting whatever program it runs continue to grab stdin.
Example 2 - Remote Command That Requires Its Own stdin
In the following example, the remote command "cat" is executed through sudo, and we are providing some extra lines through stdin for the remote cat to display.
$ ssh user#server cat \| sudo --prompt="" -S -- "cat" << EOF
> <remote_sudo_password>
> Extra line1
> Extra line2
> EOF
Extra line1
Extra line2
The output demonstrates that the <remote_sudo_password> line is being consumed by sudo, and that the remotely executed cat is then displaying the extra lines.
An example of where this would be beneficial is if you want to use ssh to pass a password to a privileged command without using the command line. Say, if you want to mount a remote encrypted container over ssh.
Example 3 - Mounting a Remote VeraCrypt Container
In this example script, we are remotely mounting a VeraCrypt container through sudo without any extra prompting text:
#!/bin/sh
ssh user#server cat \| sudo --prompt="" -S -- "veracrypt --non-interactive --stdin --keyfiles=/path/to/test.key /path/to/test.img /mnt/mountpoint" << EOF
SudoPassword
VeraCryptContainerPassword
EOF
It should be noted that in all the command-line examples above (everything except the script) the << EOF construct on the command line will cause the everything typed, including the password, to be recorded in the local machine's .bash_history. It is therefore highly recommended that for real-world use you either use do it entirely through a script, like the veracrypt example above, or, if on the command line then put the password in a file and redirect that file through ssh.
Example 1a - Example 1 Without Local Command-Line Password
The first example would thus become:
$ cat text_file_with_sudo_password | ssh user#server cat \| sudo --prompt="" -S -- whoami
root
Example 2a - Example 2 Without Local Command-Line Password
and the second example would become:
$ cat text_file_with_sudo_password - << EOF | ssh va1der.net cat \| sudo --prompt="" -S -- cat
> Extra line1
> Extra line2
> EOF
Extra line1
Extra line2
Putting the password in a separate file is unnecessary if you are putting the whole thing in a script, since the contents of scripts do not end up in your history. It still may be useful, though, in case you want to allow users who should not see the password to execute the script.
Assuming you want no password prompt:
ssh $HOST 'echo $PASSWORD | sudo -S $COMMMAND'
Example
ssh me#localhost 'echo secret | sudo -S echo hi' # outputs 'hi'
The best way is ssh -t user#server "sudo <scriptname>", for example ssh -t user#server "sudo reboot".
It will prompt for password for user first and then root(since we are running the script or command with root privilege.
I hope it helped and cleared your doubt.
NOPASS in the configuration on your target machine is the solution. Continue reading at http://maestric.com/doc/unix/ubuntu_sudo_without_password
echo $VAR_REMOTEROOTPASS | ssh -tt -i $PATH_TO_KEY/id_mykey $VAR_REMOTEUSER#$varRemoteHost
echo \"$varCommand\" | sudo bash
confirming that the answer of #ofirule is working like a charm.
I try ot even with sshpass & it works. This is how to use it with sshpass:
echo $pass | sshpass -p $pass ssh -tt cloud_user#$ip "sudo su -"
you will find yourself in the root shell directly

How do you keep the password hidden when invoked during the su command?

This is the first time it has happened to me where I am using the su command and it actually displays the password on the terminal and doesn't stay hidden. Here is my code snippet:
sshpass -p "password" ssh -q username#74.11.11.11 "su -lc 'mkdir temp/'"
Code explanation: I am accessing a remote server and trying be root on that server to create a folder. In doing so I have to use the su command and it prompts me for the password. When I enter the password, it gets displayed and doesn't stay hidden. How do I fix that?
The solution is to allocate a pseudo TTY (using the -t option on ssh):
sshpass -p "password" ssh -t -q username#74.11.11.11 "su -lc 'mkdir temp/'"
Without this, there's no "terminal" in this context and su is unable to disable echo of the password.
Just like I replied to you here.
It's possible to keep it "hidden" from the command line:
Edit your /etc/profile and paste there:
export SSHPASS='my_pass_here'
Use the -e argument with sshpass command
$ sshpass -e ssh usernmane#hosting.example 'ls -ll'
Another option is to save your password in a different file and use the -f argument:
$ sshpass -f password_filename ssh usernmane#hosting.example 'ls -la'
But the best solution is to follow the #Hristo Mohamed suggestion:
In general please AVOID using sshpass with a password.
You can set up easily a generate ssh key just to do this job and then remove it.

How to run sudo under su?

I have this:
su $username -c ./script.sh
The problem is that within script I have 'sudo' commands and they says me
sudo: no tty present and no askpass program specified
How to do this right?
UPD: I need both sudo and su. What I need to do is run script as USER $username and be able to run certain commands within script as root (for example, pacman -S)
SOLUTION: I've added NOPASSWD option to /etc/sudoers before running script and delete this entry using sed after script finished.
First set chmod +x to your scripts
try:
#!/bin/bash
echo "hello"
su - <your-user> -c /path/to/script.sh
echo "good bye"
UPDATE:
You should find a way to force bash to use pseudo-tty
Force pseudo-tty allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.
If the user is not as sudoers do the following steps:
This is what you need to do in /etc/sudoers:
# User privilege specification
root ALL=(ALL:ALL) ALL
newuser ALL=(ALL:ALL) ALL
you have also ways to do:
you can pipe password if it has password:
echo "yourpassword" | sudo -S
OR
You can run the following script:
#!/usr/bin/expect -f
spawn sudo -s <<EOF
expect "assword for username:"
send -- "user-password\r"
expect eof
Also you can do that:
sudo -kS bash - << EOF
password
whoami
echo "Not a good idea to have a password encoded in plain text"
EOF

How to pass the password to su/sudo/ssh without overriding the TTY?

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.

Resources