Getting values from properties file using shell from a specific section - linux

I'm trying to Get values from a properties file (ansible hosts file) using shell script from a specific section of the hosts file.
So I have this hosts file:
[windows]
myd-vm14945.company.net
myd-vm01431.company.net
[windows-web]
vmpweb314.company.net
[linux]
myd-vm11409.company.net
myd-vm14296.company.net
myd-vm20125.company.net
mydvm0091.company.net
And this script I want to run, when every server under Linux section should replace the parameter ${REMOTE_SERVER} in the shell script:
#add remote server to ansible host known_host file
ssh-keyscan ${REMOTE_SERVER}>> /root/.ssh/known_hosts
#remmber password
sshpass -p ROOT_PASSWORD ssh root#${REMOTE_SERVER}
So that the final result will be like that:
#add remote server to ansible host known_host file
ssh-keyscan myd-vm11409.company.net >> /root/.ssh/known_hosts
ssh-keyscan myd-vm14296.company.net>> /root/.ssh/known_hosts
#remmber password
sshpass -p ROOT_PASSWORD ssh root#myd-vm11409.company.net
sshpass -p ROOT_PASSWORD ssh root#myd-vm14296.company.net
And so on...for all the values under Linux.

If you really want to do it from bash, see the following awk magic, partially taken from Read certain key from certain section of ini file (sed/awk ?)
So you can create the following script, adjust for your inventory file and section and run it!
addkeys.sh
#!/bin/bash
INVENTORY="inventory.ini"
SECTION="[linux]"
I_HOSTS="$(awk -v section="$SECTION" ' # Enable a flag when the line is like your section
$0==section{ f=1; next } # For any lines with [ disable the flag
/\[/{ f=0; next } # If flag is set - print the line
f && $0' "$INVENTORY")"
for I_HOST in $I_HOSTS
do
#add remote server to ansible host known_host file
echo "ssh-keyscan "$I_HOST" >> /root/.ssh/known_hosts"
#remmber password
echo "sshpass -p ROOT_PASSWORD ssh "root#$I_HOST""
done
Results with echoed sshpass and keyscan commads:
ssh-keyscan myd-vm11409.company.net >> /root/.ssh/known_hosts
sshpass -p ROOT_PASSWORD ssh root#myd-vm11409.company.net
ssh-keyscan myd-vm14296.company.net >> /root/.ssh/known_hosts
sshpass -p ROOT_PASSWORD ssh root#myd-vm14296.company.net
ssh-keyscan myd-vm20125.company.net >> /root/.ssh/known_hosts
sshpass -p ROOT_PASSWORD ssh root#myd-vm20125.company.net
ssh-keyscan mydvm0091.company.net >> /root/.ssh/known_hosts
sshpass -p ROOT_PASSWORD ssh root#mydvm0091.company.net

Related

cat command not working as expected using ssh

I am creating a yaml file in GitHub Actions to install softwares on Linux servers created using terraform. Using the pipeline i am able to ssh into the linux servers. In one of the servers i am creating a .ssh directory and an id_rsa file (which contains the private key of the other server) which i intend to use to scp into the other server to copy some files. I have used the echo command to copy the private key to id_rsa file. I want to view the content of id_rsa to make sure the correct private key is copied. I am using the cat command but it does not work. here is my code
ssh chefnode -T
ssh chefnode -t 'sudo apt-get update && sudo apt-get upgrade -y'
ssh chefnode -t 'echo "$INFRA_PRIVATE_KEY" > "/home/'$SSH_NODE_USER'/.ssh/id_rsa"'
ssh chefnode -t 'cat "/home/'$SSH_NODE_USER'/.ssh/id_rsa"'
the commands run but the cat command does not return any output. It does not fail. the pipeline passes but this command does not render any output. I have tried the following combinations as well but nothing works
ssh chefnode -t 'cat /home/"$SSH_NODE_USER"/.ssh/id_rsa'
ssh chefnode -t 'cat /home/$SSH_NODE_USER/.ssh/id_rsa'
ssh chefnode -t cat /home/'$SSH_NODE_USER'/.ssh/id_rsa
ssh chefnode -t cat /home/$SSH_NODE_USER/.ssh/id_rsa
I tried this too
ssh chefnode -t 'echo "$INFRA_PRIVATE_KEY" > "/home/'$SSH_NODE_USER'/.ssh/id_rsa"'
ssh chefnode -t 'cd "/home/'$SSH_NODE_USER'/.ssh";"cat id_rsa"'
says cat command not found. I just want to view the contents of id_rsa file, not sure what i am doing wrong.
ssh chefnode -t 'echo "$INFRA_PRIVATE_KEY" > "/home/'$SSH_NODE_USER'/.ssh/id_rsa"'
Unless $INFRA_PRIVATE_KEY is a variable set by the login environment on chefnode, this is likely to be empty.
I assume you wanted to send a variable set on the local console, but as written this literally sends "$INFRA_PRIVATE_KEY" to the server which probably expands to nothing (i.e. the file is actually empty).
you probably instead want something like:
ssh chefnode -t 'echo "'"$INFRA_PRIVATE_KEY"'" > "/home/'$SSH_NODE_USER'/.ssh/id_rsa"'
which locally expands the variable and then sends it with quoting (assuming there are no quotes embedded in the variable value itself)

SCP is creating two directories (One in the other) with same name, where it is supposed to create only one

This is the bash script I'm trying:
#!/usr/bin/bash
password = SECRET
sshpass -p $password ssh root#destination_ip "mkdir -p /PVs"
sshpass -p $password scp -r /path/to/clear-nginx-deployment/ root#destination_ip:/PVs/
Basically, I'm trying to copy my local directory clear-nginx-deployment into the remote directory /PVs as it is.
The result I get on the destination machine, after running the script:
/PVs/clear-nginx-deployment/clear-nginx-deployment/content.html
The result which I expect:
/PVs/clear-nginx-deployment/content.html
Please help to get through this.
Thanks.

Execute remote SSH command and evaluate this command on remote side

Let's consider a following code:
CMD=echo $(hostname --fqdn) >> /tmp/hostname_fqdn
ssh some_user#10.9.11.4 -i ~/.ssh/id_rsa $CMD
And now, on remote side created file /tmp/hostname_fqdn contains hostname of client side instead of hostname of remote side. Is it possible to evaluate part of command (hostname --fqdn) on remote side? How to do it?
ssh some_user#10.9.11.4 -i ~/.ssh/id_rsa hostname --fqdn >> /tmp/hostname_fqdn
or, if the CMD may change at runtime:
CMD="hostname --fqdn" && ssh cloud.luminrobotics.com $CMD >> /tmp/xxx
You cannot, however, keep the redirection of the output (>> filename) be part of the command variable, because the command will be executed on the remote host.
PS: If what you want to do with the output changes at runtime as well, then you need to use a pipe and a separate command variable, e.g.,:
CMD_REMOTE="hostname --fqdn"
CMD_LOCAL="tee /tmp/hostname_fqdn"
ssh cloud.luminrobotics.com $CMD | $CMD_LOCAL
First,
CMD=echo $(hostname --fqdn) >> /tmp/hostname_fqdn
will likely do nothing like what you expect.
CMD=echo will be pasred as setting echo as the value of $CMD, and then the return from the hostname subshell we be executed, and likely fail, creating an empty file /tmp/hostname_fqdn
ssh on the other hand is pretty flexible. You could use
ssh some_user#10.9.11.4 -i ~/.ssh/id_rsa 'hostname --fqdn >> /tmp/hostname_fqdn'
if you want the remote hostname saved to a file on the remote host, or
ssh some_user#10.9.11.4 -i ~/.ssh/id_rsa 'hostname --fqdn' >> /tmp/hostname_fqdn
if you want the remote hostname on the local server, or
hostname --fqdn | ssh some_user#10.9.11.4 -i ~/.ssh/id_rsa 'cat >> /tmp/hostname_fqdn'
if you want the local hostname on the remote server...
You have options. :)

Remote execute bash scripts that needs input

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.

Bash script to push ssh_keys

I'm trying to read a file with the names of approx 500 server names on their own individual lines, and then for each of those, ssh in and append the roots authorized_keys file for each. I keep getting errors each time I run the script and/or modify it. Can you please help me figure out what's wrong? My OS is Mac OS X:
#!/usr/bin/expect
set timeout 60
set SERVERS "cat /Users/macuser/server.lst"
set USER "myuser"
set MY_PASS "mypasswordhere"
for EACH in $SERVERS; do
cat /Users/macuser/.ssh/id_rsa.pub | ssh $USER#$EACH "tee -a .ssh/authorized_keys"
expect {
eof {break}
"The authenticity of host" {send "yes\r"}
"password:" {send "$MY_PASS\r"}
}
interact
done
here is the error:
wrong # args: should be "for start test next command"
while executing
"for EACH in $SERVERS"
(file "./keyssh_push.sh" line 7)
From Use expect in bash script to provide password to SSH command, sshpass looks like the easiest way to do this. I would do:
#!/bin/sh
servers=`cat /Users/macuser/server.lst`
user="myuser"
my_pass="mypasswordhere"
for server in $servers
do
</Users/macuser/.ssh/id_rsa.pub sshpass -p"$my_pass" \
ssh -o StrictHostKeyChecking=no $user#$server cat '>>.ssh/authorized_keys'
done
Update
With #alvits's suggestion:
#!/bin/sh
servers=`cat /Users/macuser/server.lst`
user="myuser"
my_pass="mypasswordhere"
for server in $servers
do
sshpass -p"$my_pass" ssh-copy-id -o StrictHostKeyChecking=no \
-i /Users/macuser/.ssh/id_rsa $user#$server
done

Resources