How to not echo here document to terminal? - bash

I have a script that prompts the user for their sudo password, and then iterates through a list of hosts and performs commands on remote hosts. I can 'read -s' to get their password silently, but each time their password is used on a remote host, it's echoed back to the terminal. Changing stty on the local host doesn't help. Example:
#!/bin/sh -x
echo "Enter sudo pass:"
read -s SUDOPASS
stty_orig=$(stty -g)
stty -echo
ssh -tt remote_host sudo cat /etc/cma.conf <<EOP
$SUDOPASS
EOP
stty $stty_orig
The output still includes the password:
+ ssh -tt remote_host sudo cat /etc/cma.conf
My_P4ssW0rd!
Password:
<?xml version="1.0" encoding="UTF-8"?>
...
It also doesn't help to play with stty on the remote host:
stty_orig=$(ssh -t remote_host stty -g)
ssh -t remote_host stty -echo
ssh -tt remote_host sudo cat /etc/cma.conf <<EOP
$SUDOPASS
EOP
ssh -t remote_host stty $stty_orig
FWIW, I'm mainly concerned with OSX bash/sh

Try expect:
#!/bin/sh
echo "Enter sudo pass:"
read -s SUDOPASS
expect -c 'spawn ssh -tt remote_host sudo cat /etc/cma.conf ; expect -re "\\\[sudo\\\] password for .*:"; send "'"$SUDOPASS"'\n";interact'

To be honest, I haven't spotted the problem here. But I often redirect the output manually to silence it:
ssh -tt remote_host sudo cat /etc/cma.conf <<EOP >& /dev/null
I'm not sure if this will help.

Related

Execute commands as different user via sudo over SSH in a justfile

I have this justfile:
remote:
#!/usr/bin/env bash
read -p 'Password:' -s password
ssh -tt somewhere 'bash -l -s' << 'ENDSSH'
whoami
echo "$password" | sudo su someone 'bash -l -s' << 'ENDSUDO'
whoami
ENDSUDO
ENDSSH
It should:
Ask me for a password
SSH into somewhere
sudo to change the user
execute some scripts
What it does:
It asks for a password a second time.
It stucks on input (no error message).
How to solve this problem?
Update
As suggested by #xhienne, this does almost work, but it says, I use the wrong password:
remote:
#!/usr/bin/env bash
read -p 'Password:' -s password
ssh -tt somewhere 'bash -l -s' << 'ENDSSH'
sudo -S -i -u someone << ENDSUDO
$password
whoami
ENDSUDO
exit
ENDSSH
But this does work:
remote:
#!/usr/bin/env bash
read -p 'Password:' -s password
ssh -tt somewhere 'bash -l -s' << 'ENDSSH'
sudo -S -i -u someone << ENDSUDO
clear-text-password
whoami
ENDSUDO
exit
ENDSSH
Update 2
The answer of #xhienne does work.
With
echo "$password" | sudo su someone 'bash -l -s' << 'ENDSUDO'
whoami
ENDSUDO
You are redirecting stdin twice:
once with |
a second time with <<
Try this:
sudo -S -i -u someone << ENDSUDO
$password
whoami
ENDSUDO
sudo -S will read the password from stdin. sudo -i is a substitute for the ugly sudo su bash -l (but it needs that sudo be properly configured for -u someone)
Note that I removed the quotes around ENDSUDO. Beware of inadvertent substitutions. If you must keep ENDSUDO quoted, then you can try this instead:
{
echo "$password"
cat << 'ENDSUDO'
whoami
ENDSUDO
} | sudo -S -i -u someone
I believe the following will work, if you only want to run whoami instead of several commands:
#!/usr/bin/env bash
read -s -p 'Password: ' password
ssh somewhere whoami
echo "$password" | ssh somewhere sudo -S -u someone whoami
The -S tells sudo to read the password from stdin.
If you want to run several commands with a here-document, see #xhienne's answer.

Run bash script on remote server

I'm trying to run a bash script on the remote server that is already on the remote server. I'm using ssh pass to do it but I'm seeing errors
test.sh (resides on the remote server)
#!/usr/bin/env bash
echo "This is test"
adb start-server
sshpass command (I'm running this sshpass command from docker ubuntu image
sshpass -p password ssh -oStrictHostKeyChecking=no -oCheckHostIP=no user#host "bash -s" < /Users/user/Documents/workspace/test.sh
I also tried
sshpass -p password ssh -oStrictHostKeyChecking=no -oCheckHostIP=no user#host 'cd /Users/user/Documents/workspace/; sh test.sh'
I get this error message
bash: /Users/user/Documents/workspace/test.sh: No such file or directory
The examples you're showing are for a local script, and you said it's a remote script.
sshpass -p password ssh -oStrictHostKeyChecking=no -oCheckHostIP=no user#host "bash /path/to/test.sh"
that ought to do it.
you can try to find your test.sh on the remote computer:
sshpass -p password ssh -oStrictHostKeyChecking=no -oCheckHostIP=no user#host "find ~/ -name \"test.sh\""
Try with here-document:
sshpass -p password ssh -oStrictHostKeyChecking=no -oCheckHostIP=no -T user#host <<EOF
bash /Users/user/Documents/workspace/test.sh
EOF
Include -T option for ssh command, as mentioned above, to disable pseudo-tty.
[AT REMOTE MATCHINE] Ensure that path of adb executable is included in PATH environment variable. Else, specify it with absolute path in the Shell script.

Creating an SSH Key Pair for User Authentication with Expect in Bash

I have tried the following steps to set ssh passwordless (SSH Key Pair Authentication)login.
Set ip and port in bash.
ip="xxxx"
port="xxxx"
Set ssh config file on client side
cat > $HOME/.ssh/config <<EOF
Host $ip
IdentityFile $HOME/.ssh/id_rsa
User root
EOF
Create a ssh key pair on client side
ssh-keygen -t rsa -f $HOME/.ssh/id_rsa -q -b 2048 -N ""
Push id_rsa into ssh server from client side.
Prepare for ssh server
ssh -p $port root#$ip "mkdir -p /root/.ssh"
Push authorized file into ssh server
scp -P $port id_rsa.pub root#$ip:/root/.ssh/authorized_keys
Set permission for authorized file
ssh -p $port root#$ip "chmod 700 .ssh; chmod 640 .ssh/authorized_keys"
Succeeded!
Now i want to write all steps into a one-click bash script for the job.
Here is my try.
#! /bin/bash
ip="xxxx"
port="xxxx"
pass="yyyy"
cat > $HOME/.ssh/config <<EOF
Host $ip
IdentityFile $HOME/.ssh/id_rsa.bwg_root
User root
EOF
ssh-keygen -t rsa -f $HOME/.ssh/id_rsa.bwg_root -q -b 2048 -N ""
cd $HOME/.ssh
/usr/bin/expect <<EOF
spawn ssh -p $port root#$ip "mkdir -p /root/.ssh"
expect "password:"
send "$pass\r"
spawn scp -P $port id_rsa.pub root#$ip:/root/.ssh/authorized_keys
expect "password:"
send "$pass\r"
spawn ssh -p $port root#$ip "chmod 700 .ssh; chmod 640 .ssh/authorized_keys"
expect "password:"
send "$pass\r"
EOF
It got the following output info:
spawn ssh -p xxxx root#yyyy mkdir -p /root/.ssh
root#yyyy's password: spawn scp -P xxxx id_rsa.bwg.pub root#yyyy:/root/.ssh/authorized_keys
root#yyyy's password: spawn ssh -p xxxx root#yyyy chmod 700 .ssh; chmod 640 .ssh/authorized_keys
Why and how to fix it?
I'd simplify it with sshpass.
#!/bin/bash
ip="x.x.x.x"
port="xx"
export SSHPASS="yyy"
cat >$HOME/.ssh/config <<EOF
Host $ip
IdentityFile $HOME/.ssh/id_rsa.bwg_root
User root
EOF
ssh-keygen -t rsa -f "$HOME/.ssh/id_rsa.bwg_root" -q -b 2048 -N ""
cd "$HOME/.ssh" || exit 1
sshpass -e ssh -oStrictHostKeyChecking=no -p "$port" "root#$ip" "mkdir -p -m 700 /root/.ssh"
sshpass -e scp -oStrictHostKeyChecking=no -P "$port" id_rsa.bwg_root.pub "root#$ip:/root/.ssh/authorized_keys"
sshpass -e ssh -oStrictHostKeyChecking=no -p "$port" "root#$ip" "chmod 640 .ssh/authorized_keys"
Btw: I replaced last id_rsa.pub with id_rsa.bwg_root.pub and added -m 700 to mkdir and removed chmod 700 .ssh.
Use ssh-copy-id to push the new key to the remote host. You'll need to enter the password for that login, of course, but it's the last time you'll have to use it.
#!/bin/bash
ip="x.x.x.x"
port="xx"
id_file=$HOME/.ssh/id_rsa_$ip
cat > $HOME/.ssh/config <<EOF
HOST $ip
IdentityFile $id_file
User root
EOF
ssh-keygen -t rsa -f "$HOME/.ssh/id_rsa_$ip" -q -b 2048 -N ""
ssh-copy-id -i "$id_file" -p "$port" root#"$ip"
As a general rule, always look for a non- (or less) interactive solution using existing tools before trying except.

How to run shell script with sudo inside through nohup on remote machine

I ran the following command from my local machine:
ssh -i key remote_host "nohup sh test.sh > nohup.out 2> nohup.err < /dev/null &"
then I got error: sudo: sorry, you must have a tty to run sudo
I added -tt option:
ssh -tt -i key remote_host "nohup sh test.sh > nohup.out 2> nohup.err < /dev/null &"
I checked on the remote, test.sh was not running (there was no process id).
I took out the nohup, everything runs fine, ssh -tt -i key remote_host "sh test.sh" but I need to use nohup. Can someone help me? Thanks a lot!
One remote_host: test.sh script:
#!/bin/bash
sudo iptables -A OUTPUT -p tcp --dport 443 -j DROP
sleep 30
sudo iptables -D OUTPUT -p tcp --dport 443 -j DROP
sudo is probably trying to prompt you for a password. You need to set up NOPASSWD in your remote_host's sudoers file or you can use expect

sudo and chpasswd on one line

I need connect to server via ssh and change users' passwords without typing ssh or sudo password.
I found some example but I cannot complete one command.
I found this command for ssh connection without typing password and running sudo command for delete user:
sshpass -p $admin_password ssh -t $admin#$server "echo $admin_password | sudo -S /usr/sbin/userdel -r $usr"
then I found command for change users password:
echo "$usr:$password" | sudo -S /usr/sbin/chpasswd;
Finaly, I want something like this:
sshpass -p $admin_password ssh -t $admin#$server "echo $admin_password | sudo -S echo "$usr:$password" | sudo -S /usr/sbin/chpasswd;"
Do you have any ideas?
Your question is actually going to require 2 things. The command to change a password remotely for a user:
ssh remoteserver 'echo -e "passwdofuser\npasswdofuser" | passwd username'
In order to do that you probably need to be root, or in the sudo config, have "passwd" NOT require a password for your user to run.
visudo
Edit the file:
Cmnd_Alias MYPASSWD = /usr/bin/passwd
yourusername ALL = NOPASSWD: MYPASSWD
That should allow you to ssh in and not have to use a password to run the passwd command.

Resources