Get output from a shell script that does ssh two level - bash

I have two shell scripts like below:
Script1:
ssh -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null my_username#jump_box <<EOF
ls
ssh -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null actual_host <<EOF1
sudo docker ps --format='{{json .}}'
EOF1
EOF
Script2:
details=nothing
ssh -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null my_username#jump_box <<EOF
ls
details=$(ssh -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null actual_host "sudo docker ps --format='{{json .}}'")
EOF
echo "${details}"
I need the docker details in a varilable in my local machine so that I can do some operations on it. The first script runs fine and I can see the output of the docker command on my local machine but the second script doesn't work. It seems to be hung/stuck and doesn't do anything and I have to forcefully quit it.

Like the comment from #Gordon Davisson, use a jumpbox.
But you can define it in the ~/.ssh/config file, too.
HOST my_jump_box
hostname jump_box
user my_username
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
HOST actual
hostname actual_hostname
user actual_user
ProxyJump my_jump_box
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
RemoteCommand sudo docker ps --format='{{json .}}'"
Then you can just use ssh actual
To fetch the output details=$(ssh actual).
Btw. Your specific problem could also be solved by changing script2 to:
#!/bin/bash
details=$(./script1)
echo "$details"

Related

Empty ssh invitation (no "user#host:~$") when run command after connect (sh script, sshpass)

Client OS: MacOS 12.1, Server OS: Linux Debian 9 (any server)
case 1:
#!/bin/bash
sshpass -p mypass ssh user#host.ru -o StrictHostKeyChecking=no
works fine:
case 2:
#!/bin/bash
sshpass -p mypass ssh user#host.ru -o StrictHostKeyChecking=no "cd /var/www ; git status ; /bin/bash"
Output of "git status" works fine, but
no "user#host:~$" message in output (input is active).
I tried:
/bin/bash
bash -l
(in server "echo $SHELL" shows /bin/bash)
How to fix it?
Use ssh -t and && inside commands list
#!/bin/bash
sshpass -p mypass ssh -t user#host.ru -o StrictHostKeyChecking=no "cd /var/www && git status && /bin/bash"

Passing a variable in a bash script to sshpass

I am trying to pass a variable in a bash script to sshpass. Here is my code for reference:
NAME="HARRY"
sshpass -p passwd ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -q ipaddress 'bash -s' << 'EOF'
echo $NAME
EOF
How can I pass the variable in a bash script to sshpass? Thank you!
Easiest way is using env just before running bash
NAME="HARRY"
sshpass -p passwd ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -q ipaddress env NAME="$NAME" 'bash -s' << 'EOF'
echo $NAME
EOF
You can pass multiple variables with multiple env statements like
export NAME="HARRY"
export SOMEVAR="hello"
sshpass -p passwd ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -q ipaddress env NAME="$NAME" env SOMEVAR="$SOMEVAR" 'bash -s' << 'EOF'
echo $NAME
EOF
Be aware that your variables might be interpreted when passing them. You can avoid that by changing env NAME="$NAME" to uninterpreted version env NAME="'$NAME'"
Put it after the -p option:
password=YourPassword
sshpass -p "$password" ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -q ipaddress 'bash -s' <<EOF
echo "$NAME"
EOF
You can simply put a dollarsign in front of the variable name, as in this example:
Linux Prompt>cat test.txt
<here you see file content>
Linux Prompt>filename=test.txt
Linux Prompt>cat $filename
<here you see file content>

Weird output observed on executing ssh commands remotely over ProxyCommand

Team, I have two steps to perform:
SCP a shell script file to remote ubuntu linux machine
Execute this uploaded file on remote ubuntu linux machine over SSH session using PROXYCommand because I have bastion server in front.
Code:
scp -i /home/dtlu/.ssh/key.key -o "ProxyCommand ssh -i /home/dtlu/.ssh/key.key lab#api.dev.test.com -W %h:%p" /home/dtlu/backup/test.sh lab#$k8s_node_ip:/tmp/
ssh -o StrictHostKeyChecking=no -i /home/dtlu/.ssh/key.key -o 'ProxyCommand ssh -i /home/dtlu/.ssh/key.key -W %h:%p lab#api.dev.test.com' lab#$k8s_node_ip "uname -a; date;echo "Dummy123!" | sudo -S bash -c 'echo 127.0.1.1 \`hostname\` >> /etc/hosts'; cd /tmp; pwd; systemctl status cachefilesd | grep Active; ls -ltr /tmp/test.sh; echo "Dummy123!" | sudo -Sv && bash -s < test.sh"
Both calls above are working fine. I am able to upload test.sh and also its running but what is bothering me is during the process am observe weird output being thrown out.
output:
/tmp. <<< expected
[sudo] password for lab: Showing one
Sent message type=method_call sender=n/a destination=org.freedesktop.DBus object=/org/freedesktop/DBus interface=org.freedesktop.DBus member=Hello cookie=1 reply_cookie=0 error=n/a
Root directory /run/log/journal added.
Considering /run/log/journal/df22e14b1f83428292fe17f518feaebb.
Directory /run/log/journal/df22e14b1f83428292fe17f518feaebb added.
File /run/log/journal/df22e14b1f83428292fe17f518feaebb/system.journal added.
So, I don't want /run/log/hournal and other lines which don't correspond to my command in sh.
Consider adding -q to the scp and ssh commands to reduce the output they might produce. You can also redirect stderr and stdout to /dev/null as appropriate.
For example:
{
scp -q -i /home/dtlu/.ssh/key.key -o "ProxyCommand ssh -i /home/dtlu/.ssh/key.key lab#api.dev.test.com -W %h:%p" /home/dtlu/backup/test.sh lab#$k8s_node_ip:/tmp/
ssh -q -o StrictHostKeyChecking=no -i /home/dtlu/.ssh/key.key -o 'ProxyCommand ssh -i /home/dtlu/.ssh/key.key -W %h:%p lab#api.dev.test.com' lab#$k8s_node_ip "uname -a; date;echo "Dummy123!" | sudo -S bash -c 'echo 127.0.1.1 \`hostname\` >> /etc/hosts'; cd /tmp; pwd; systemctl status cachefilesd | grep Active; ls -ltr /tmp/test.sh; echo "Dummy123!" | sudo -Sv && bash -s < test.sh"
} >&/dev/null

golang ssh quiet mode

In golang ssh(golang.org/x/crypto/ssh) package how to force the ssh command to use quiet mode i.e. simulate 'ssh -q'
I looked at Config and ClientConfig structures as well as tried searching for 'quiet' or options in the documentation(https://godoc.org/golang.org/x/crypto/ssh) but can't find anything.
Credits: Thanks to #JimB and #Kenster for nailing this.
Quiet mode is not required for (golang.org/x/crypto/ssh). Extra messages that you would usually see when using a ssh CLI won't appear when using (golang.org/x/crypto/ssh). Here is an example of extra messages:
sshpass -ppassword ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no 10.10.10.10 'ls | wc -l'
Warning: Permanently added '10.10.10.10' (ECDSA) to the list of known hosts.
19
sshpass -ppassword ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no 10.10.10.10 'ls | wc -l'
19

SSH command options cause errors when stored in a variable

I have a variable that stores an SSH command, since my script uses it quite often.
SSH_CMD="ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes"
However, I'm running into an issue where the SSH command works fine on its own, but doesn't work when I use the variable
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes $host exit 0
${SSH_CMD} $host exit 0
The first line works great. The second line fails with a No such file or directory message. When I remove -o UserKnownHostsFile=/dev/null from $SSH_CMD, the error message is command not found. If I remove either of the other two options, the message doesn't change, but when $SSH_CMD is just "ssh", it works.
What's causing this problem?
So why does it work without any issues in other scripts?
Many times answered. Try bash alias or bash function:
alias my_ssh='ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes'
my_ssh $host exit 0
Or rahter use ssh_config in your ~/.ssh/config.
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
BatchMode yes
and then you don't need any harakiri like this and just use
ssh $host exit 1

Resources