Answer "Yes" or "No" ONLY IF a command request it - linux

I a writing a script. There is a command that colud request to answer yes or no to override a certain file.
I want to automate the script to answer YES or NO ONLY IF the command request it (i don't want to echo yes inside the command).
The command I am referring to is ssh-keygen, which requires to override the key in case already exists.
In my mind there is something like this...
if (ssh-keygen requests input) --> Sends yes to the ssh-keygen
In particular, I am using the following command:
ssh-keygen -t rsa -b 4096 -N '' -f ~/.ssh/id_rsa -q
Even if i am using -q, still asks yes or no to override the file.
Thanks in advance

i suggest using the echo command to send "yes" to the command.
echo "yes" | ssh-keygen -t rsa -b 4096 -N '' -f ~/.ssh/id_rsa -q

I would suggest you to check the yes command.
It is sending a loop of y.
If you want to force the acceptation of the command it should work.
But if the keygen request for an input (filename, etc.) it will also send 'y'.
the command would be :
yes | ssh-keygen -t rsa -b 4096 -N '' -f ~/.ssh/id_rsa -q

Related

how to cat file from local to remote while using sudo without typing password

I'm trying to cat the local file to remote file and use diff to compare the difference of the two files.
I need to use sudo to run the command and hope it can run automaticall wihtout typing password manually.
The followings are my code now.
cat
cat password.txt | sshpass -p ${USER_PASSWORD} ssh -o StrictHostKeyChecking=no -o "ConnectTimeout 5" -tt ${USER_NAME}#${PEER_IPADDRESS[${i}]} "sudo cat > ${DIR_SET}${FILE_NAME}.txt"< ${DIR_SET}${FILE_NAME}.txt
diff
DIFF=$(diff ${DIR_SET}${FILE_NAME}.txt <(cat password.txt | sshpass -p ${USER_PASSWORD} ssh -o StrictHostKeyChecking=no -o "ConnectTimeout 5" -tt ${USER_NAME}#${PEER_IPADDRESS[${i}]} "sudo cat ${DIR_SET}${FILE_NAME}.txt"))
At first, I try to use pipeline to cat and diff the local file to the remote one.
However, it seems that to use sudo without typing password also need to use the vertical pipe.
My question is:
1.Is it possible to use two pipeline in one line code, and how to run them seperatley to make my code work.
2.Are there any way to use sudo without typing password or to use cat/diff without useing pipeline.
Thank you very much.

Linux terminal: pass the answer(or arg values) in advance when installing package?

When I run a command like ssh-keygen -t rsa -b 2048, it asks me:
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
I'd like to write the path in advance and tried like this: ssh-keygen -t rsa -b 2048 | cat '/root/.ssh/id_rsa.pub'.
But this doesn't work....
How can I do this?
Your attempt was in reverse, meaning you were trying to pass the output of ssh-keygen to cat. But we need to pass the output of cat to ssh-keygen:
# using multiline here doc
$ cat <<EOF | ssh-keygen -t rsa -b 2048
/tmp/id_rsa
/tmp/id_rsa.pub
password
EOF
OR
$ echo -e "/tmp/id_rsa\n/tmp/id_rsa.pub" | ssh-keygen -t rsa -b 2048
But use it with caution, this just feeds the entire input to the piped command. Depending on how that command processes input this might fail if the expected input is different from what is being piped in.
It may be fine for simple scripts/commands (will NOT work for ssh-keygen reliably in all cases [because it seems to spawn another process in some cases to ask for the passphrase]).
ref. https://tldp.org/LDP/abs/html/here-docs.html for heredoc

Bash Scripting - passing no value

My aim is to create a bash script that can add new users to Ec2 and give access to ssh keys but I am having abit of an issue.
This is my current script and the script stops whenever it requires to generate a private/public key because it asks for the passphrase . How can I configure my script to just press enter?
#!/bin/bash
username=$1
ssh-keygen -b 1024 -f $username -t dsa
chmod 600 $username.pub
useradd $username
mkdir /home/$username/.ssh
chmod 700 /home/$username/.ssh
chown ball:ball /home/$username/.ssh
cat ball.pub >> /home/$username/.ssh/authorized_keys
chown 600 /home/.ssh/$username/authorized_keys
chown ball:ball /home/$username/.ssh/authorized_keys
[root#ip-172- /]# ssh-keygen -b 1024 -f ball -t dsa
Generating public/private dsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ball.
You can pipe empty lines to ssh-keygen:
ssh-keygen -b 1024 -f ball -t dsa <<< ''
or
printf "" | ssh-keygen -b 1024 -f ball -t dsa
or reading from /dev/null:
ssh-keygen -b 1024 -f ball -t dsa < /dev/null

Bash script does not ssh all the entries of a csv file

I am trying to patch a bunch of CENT OS machines with the latest fix pack. I have the below bash script that takes csv file as a input which has the ip address and password for those machines.
The code works fine however, it would only work for the first row it does not seem to be working for the rest of the list as my output.txt only has the entry only for the first row host .
patch.sh
INPUT=hosts_test.cvs
OLDIFS=$IFS
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read privateip password
do
sshpass -p$password ssh -t -o "StrictHostKeyChecking no" user123#$privateip "
hostname
hostname -I --all-ip-addresses
sudo yum -y update bash
env x='() { :;}; echo vulnerable' bash -c \"echo If you see the word vulnerable above, then you are vulnerable to shellshock\"
echo ""
exit
" >> output.txt
done < $INPUT
IFS=$OLDIFS
hosts_test.cvs
10.xxx.xx.219,abcd~qY1
10.xxx.xx.226,l4~abcdefg
10.xxx.xx.221,l4#abcdefgh
Terminal Output
Pseudo-terminal will not be allocated because stdin is not a terminal.
Add at the end of your sshpass command </dev/null.
Add Defaults:username !requiretty to your /etc/sudoers config
Get rid of -t from your ssh command
Optional, but recommended: set up public key auth so you don't have your passwords lying around in text files.
You can pass ssh another -t to force pty allocation:
ssh -t -t

ssh-keygen accepting stdin

I am trying to call ssh-keygen using a variable through bash as an input instead of a file to get a fingerprint of a public key. I am aware that I could use a temp file to get around this issue, but for reasons out of scope of this question, I do not want to.
This method does not work as it says the key file is invalid (it's correct for sure)
echo $pubkey | ssh-keygen -lf /dev/stdin
This does work, but is not using a variable, rather a file.
ssh-keygen -lf alpha.pub
This does work, but is not using a variable, rather a redirected file.
ssh-keygen -lf /dev/stdin < alpha.pub
This does not work because I get an ambiguous redirect
ssh-keygen -lf /dev/stdin < $(echo $pubkey)
I would appreciate some insight as to how to get ssh-keygen to read from a variable with a public key and if possible, an explanation as to why the redirects aren't doing what I think they should be doing. In specific why the | behaves differently than the < and why the third example is an ambiguous redirect. I searched online but many of the redirect tutorials didn't seem to answer my questions.
echo $pubkey | ssh-keygen -lf /dev/stdin
/dev/stdin is not a public key file.
/dev/stdin is actually a unix pipe, not a regular file, so ssh-keygen fails to open the file
ssh-keygen -lf /dev/stdin <<<$key
1024 92:6a:3f:5c:1f:78:.....
/dev/stdin refers to a regular file, created by using a bash heredoc. You can verify this:
# ls -l /dev/stdin <<<$pubkey
lrwxrwxrwx 1 root root 15 Feb 11 08:07 /dev/stdin -> /proc/self/fd/0
# ls -l /proc/self/fd/0 <<<$pubkey
lr-x------ 1 juergen juergen 64 Apr 14 13:31 /proc/self/fd/0 -> /tmp/sh-thd-1271250023 (deleted)
Since version 7.2 (released on on 2016-02-28), this is now possible by passing - as the file name. From the release notes:
ssh-keygen(1): allow fingerprinting from standard input, e.g. ssh-keygen -lf -
If you want to redirect a string as stdin, use this syntax:
cmd <<< "some $STR here"
If you want to redirect the output of a command as if it was a file, you do it like this:
cmd <( /bin/somecmd )
And if you want to use a command as an OUTPUT file, it's more or less the same:
cmd >( /bin/othercmd )
Here is a one liner using the file /dev/stdin as described in other answers.
$ ssh-keygen -lf /dev/stdin <<< $( ssh-keygen -f ~/.ssh/keyname.pem -y )
2048 14:df:c7:b7:f1:26:7f:87:d5:e7:10:6c:ac:af:a2:03 /dev/stdin (RSA)
Note that this will break with private keys that use a passphrase. It will work with pem files generated by AWS or OpenStack which do not use passphrases.
I would recommend using a temporary file. The issue is that redirecting, BASH expects a file. By using $(echo $pubkey), bash will complain because when it's done with the substitution, it will look for a file of that name that the substitution creates.

Resources