Shell repeat execute ssh and scp command - bash

I have two line need to repeat doing in for loop
ssh tam#192.168.174.43 mkdir -p $location
scp -r $i tam#192.168.174.43:$location
but each time it need to input password, how can i change code then just need input one time or more fast way

You can use public/private key generation method using ssh-keygen (https://help.ubuntu.com/community/SSH/OpenSSH/Keys)
And then use the below script.
for VARIABLE in dir1 dir2 dir3
do
ssh tam#192.168.174.43 mkdir -p $location
scp -r $i tam#192.168.174.43:$location
done
Alternative solution :
You can use sshpass
for VARIABLE in dir1 dir2 dir3
do
ssh tam#192.168.174.43 mkdir -p $location sshpass -p '<password>' <command>
scp -r $i tam#192.168.174.43:$location sshpass -p '<password>' <command>
done

While public/private keys is the easiest option, without need to change the existing script, there is another option, of using sshfs. sshfs may not be installed by default.
With this approach, you basically mount the remote file system to a local directory, over ssh protocol. Then you can simply use commands like mkdir / cp etc.
NOTE: These command are from YOUR system & not from REMOTE system.
Mounting over ssh is a one time job, which will require your manual intervention. Do this before running the script.e.g. for your case:
mkdir /tmp/tam_192.168.174.43
sshfs tam#192.168.174.43:/ /tmp/tam_192.168.174.43
tam#192.168.174.43's password: <ENTER PASSWORD HERE>
& then, in your script, use simple commands like:
mkdir -p /tmp/tam_192.168.174.43/$location
cp -r $i /tmp/tam_192.168.174.43/$location
& to unmount:
fusermount -u /tmp/tam_192.168.174.43

Related

sshpass want to use parameter of sftp

Hi i created following script to initialize my storage box to use rsync without password later. Last year it works if i remember correct...
cat .ssh/id_rsa.pub >> .ssh/storagebox_authorized_keys
echo -e "mkdir .ssh \n chmod 700 .ssh \n put $.ssh/storagebox_authorized_keys" \
".ssh/authorized_keys \n chmod 600 .ssh/authorized_keys" | sshpass -p ${storage_password} \
sftp -P ${storage_port} -i .ssh/id_rsa ${storage_user}#${storage_address}
today I get following error:
sshpass: invalid option -- 'i'
but the parameter -i belongs to sftp and not sshpass - is there an possibility to parse the parameters in the correct way?
edit: i switched the position of
-i .ssh/id_rsa ${storage_user}#${storage_address}
and get this error
sshpass: Failed to run command: No such file or directory
edit: it seems like an sftp problem...
after discussion, updating answer to properly support automation
step 1:
create an sftp "batch file" e.g: ~/.ssh/storage-box_setup.sftp
mkdir .ssh
chmod 700 .ssh
put /path/to/authorized_keys_file ".ssh/authorized_keys
chmod 600 .ssh/authorized_keys
/path/to/authorized_keys_file is a file containing public keys of ONLY the keys that should have access to your storage box (.ssh/storagebox_authorized_keys)
step 2:
update automation script command to
sshpass -p <password> -- sftp -P <port> -b ~/.ssh/storage-box_setup.sftp user#host
the -b flag was the answer you needed.
refer: man sftp
-b batchfile
Batch mode reads a series of commands from an input batchfile instead of stdin. Since it lacks user interaction it should be used in conjunction with non-interactive authentication.
--
sshpass -p ${storage_password} -- \
sftp -P ${storage_port} -i .ssh/id_rsa \
${storage_user}#${storage_address}
the -- before sftp is a way to tell sshpass (and most other programs) to stop parsing arguments.
everything after -- is assumed as the last argument, which in the case of sshpass is the command to be executed ssh -i ~/.id_rsa ...
in case you're wondering switching the position of -i tells sshpass to execute -i as a program and hence fails with command not found

Execute multiple commands on remote server using bash

I want to execute cd and scp commands on a remote server which have to be logged in with a different sudo user. Below code snippet asks for the password(echos on screen) for my user but hangs there. It doesn't execute cd
#!/bin/bash
server=myserver.com
ssh $server 'sudo -S -u <user> -i; cd dir1/dir2/; scp file1 user#local-sever'
The issue is that you have a semi colon before cd and so sudo has no command to execute. Remove the ; and it should work:
ssh $server 'sudo -S -u <user> -i scp dir1/dir2/file1 user#local-sever'
There are several ways to address this, but most boil down to wrapping up the commands into a set of instructions. Raman's solution is good since it handles the issue by using full paths, but sometimes that isn't an option. Here's another take -
Assuming your command list can afford the quotes, I like here-strings.
ssh -t sa-nextgen-jenkins.eng.rr.com <<< "
echo 'set -x; cd /tmp; whoami; touch foo; ls -l foo; rm -f foo;'|sudo -iSu user
"
If you need the quotes, try a here-doc.
ssh -t sa-nextgen-jenkins.eng.rr.com <<END
echo 'set -x; echo "$RANDOM"; cd /tmp; whoami; touch foo; ls -l foo; rm -f foo;'|sudo -iSu $user
END
You can also write a small script that has arbitrarily complex commands and scp it over, then use a remote ssh call to execute it as the relevant user.

How to retain password for Rsync across the same script?

I have written this script:
#!/bin/bash
SSH_USER=${SSH_USER:=$USER}
for department in A B C E L M V
do
mkdir -p ./resources/${div}
rsync -Pruzh --copy-links \
${SSH_USER}#server:${department}/foo/files \
${SSH_USER}#server:${department}/foo/photos \
./resources/${department}/foo
rsync -Pruzh \
${SSH_USER}#server:${department}/bar/documents \
./resources/${department}/bar
done
It works perfect except that I have to write my password 14 times which is not really practical.
I have heard of ssh_agent but for some reasons it does not work on my WSL.
Is there any alternative that I can use to type my password only once?
If you are using openssh, then you can set up a master connection and reuse it with something like:
DEST="${SSH_USER}#server"
TMPL=/tmp/sshctl/"%L-%r#%h:%p"
mkdir -p /tmp/sshctl
if ! ssh -nNf -o ControlMaster=yes -o ControlPath="${TMPL}" "${DEST}"; then
echo "# Failed to setup SSH ControlMaster. Aborting."
exit
fi
# ...
rsync -e "ssh -o 'ControlPath=${TMPL}'" ... "${DEST}":... ...
rsync -e "ssh -o 'ControlPath=${TMPL}'" ... "${DEST}":... ...
# ...
ssh -O exit -o ControlPath="${TMPL}" "${DEST}"
Be sure to secure the socket.
Best practice would be to set up SSH key pairs for automated authentication; i.e. create an SSH key pair and copy the public key to the server where these files are located, then use the private key in the rsync command: rsync -Pruzh --copy-links -e "ssh -i /path/to/private.key" .... This is fairly simple, secure, and gets rid of the prompt.
You can also use a utility like sshpass to enter the password in the prompt, but that kind of approach is less secure.

scp shell stops when permission denied

I have a shell script that continuously put some data from one server to another. It works fine but I want to make it more secure. So at the moment if the other server denied the permission because the password was changed the scipts freezes. Is there a possibility so if this occurs it just ignores this line and just goes on?
inotifywait -m /srv/watchfolderfilme -e create -e moved_to |
while read path action file; do
...
sshpass -p "****" scp -r /srv/newtorrentfiles/* user#0.0.0.0:/srv/torrentfiles && rm -r /srv/newtorrentfiles/*
done
scp is no the best tool to deal with your problem.
As George said, using public keys with ssh is the best way to get rid of password change.
Also you can do the trick with rsync like this :
rsync -ahz --remove-source-files /srv/newtorrentfiles/ user#SRVNAME:/srv/torrentfiles/
or
rsync -ahz /srv/newtorrentfiles/ user#SRVNAME:/srv/torrentfiles/ && rm -r /srv/newtorrentfiles/*
To be sure that all is done like you wanted (make this script more "secure"), you can send you an email if the script fails for one reason or another not due to lack of permission.
Maybe not the answer you're looking for but why don't you use SSH keys?
Updated Script:
inotifywait -m /srv/watchfolderfilme -e create -e moved_to |
while read path action file; do
...
scp -r /srv/newtorrentfiles/* b#B:/srv/torrentfiles && rm -r /srv/newtorrentfiles/*
done
How to do it
a#A:~> ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/a/.ssh/id_rsa):
Created directory '/home/a/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/a/.ssh/id_rsa.
Your public key has been saved in /home/a/.ssh/id_rsa.pub.
The key fingerprint is:
3e:4f:05:79:3a:9f:96:7c:3b:ad:e9:58:37:bc:37:e4 a#A
Now use ssh to create a directory ~/.ssh as user b on B. (The directory may already exist, which is fine):
a#A:~> ssh b#B mkdir -p .ssh
b#B's password:
Finally append a's new public key to b#B:.ssh/authorized_keys and enter b's password one last time:
a#A:~> cat .ssh/id_rsa.pub | ssh b#B 'cat >> .ssh/authorized_keys'
b#B's password:
From now on you can log into B as b from A as a without password:
a#A:~> ssh b#B
Source >> http://www.linuxproblem.org/art_9.html

Bash scp several files password issue

I am trying to copy several files from a remote server into local drive in Bash using scp.
Here's the part of the code
scp -r -q $USR#$IP:/home/file1.txt $PWD
scp -r -q $USR#$IP:/home/file2.txt $PWD
scp -r -q $USR#$IP:/root/file3.txt $PWD
However, the problem is that EVERY time that it wants to copy a file, it keeps asking for the password of the server, which is the same. I want it to ask only once and then copy all my files.
And please, do not suggest rsync nor making a key authentication file since I do not want to do that.
Are there any other ways...?
Any help would be appreciated
You can use expect script or sshpass
sshpass -p 'password' scp ...
#!/usr/bin/expect -f
spawn scp ...
expect "password:"
send "ur_password"
An disadvantage is that your password is now in plaintext
I'm assuming that if you can scp files from the remote server, you can also ssh in and create a tarball of the remote files.
The -r flag is recursive, for copying entire directories but your listing distinct files in your command, so -r becomes superfluous.
Try this from the bash shell on the remote system:
$ mkdir /home/file_mover
$ cp /home/file1.txt /home/file_mover/
$ cp /home/file2.txt /home/file_mover/
$ cp /root/file3.txt /home/file_mover/
$ tar -cvf /home/myTarball.tar /home/file_mover/
$ scp -q $USR#$IP:/home/myTarball.tar $PWD
Well, in this particular case, you can write...
scp -q $USR#$IP:/home/file[1-3].txt $PWD

Resources