Crontab to send dump data to windows machine - linux

I have mysql Database in Linux machine which should be dumped by using crontab and the data directly should have to store in a remote windows system. Is this possible? if yes, how?

You will need a script similar to the one below.
It would be best if you tested the script before running it from cron.
The scp command will prompt for the user's password on the destination machine - unless the ssh key setup on the scp destination machine contains public key authorization. For this to work with cron the scp command must be able to copy without user input of a password.
Once it works then set up the crontab entry. Specify the full path of the script in the entry.
export DB_DUMP_DIR=/home/database_dump
export DB_NAME=database_name_$(date '+%Y_%m_%d').sql
mysqldump -u root -p database_name > ${DB_DUMP_DIR}/${DB_NAME}
if [ $? -eq 0 ];then
scp ${DB_DUMP_DIR}/${DB_NAME} user#windows_machine:
else
echo "Error generating database dump"
fi

Related

ssh-copy-id fails when run from within a remote session

I have a task to copy ssh keys from one node to all others in an array. For this, I wrote a simple bash script which copies itself to other nodes and runs it there. What confuses me is the fact that ssh-copy-id works fine on the node where the script is executed manually but it fails if run remotely in an ssh session. Here’s the script:
1 #!/bin/bash
2 # keys-exchange.sh
4 nodes=( main worker-01 worker-02 worker-03 )
6 for n in $( echo "${nodes[#]}" ); do
7 [ $n != $HOSTNAME ] && ssh-copy-id $n
8 done
10 if [ -z $REMOTE ]; then
11 for n in $( echo ${nodes[#]} ); do
12 if [ $n != $HOSTNAME ]; then
13 scp $0 $USER#$n:$0 > /dev/null
14 ssh $USER#$n "REMOTE=yes HOSTNAME=$n $0 ; rm -f $0"
15 fi
16 done
17 fi
The code in rows 6-8 works fine copying the ssh key to all nodes other than itself. Then, if the REMOTE variable is not set, code in rows 11-16 copies the script to remote nodes (except the node it’s running on, row 12) and runs it there. In row 14, I set and pass the variable REMOTE to skip the code block in rows 10-17 (so the script copies itself only from the source node to others), and the variable HOSTNAME because I found it’s not set in an ssh session. The user’s name and the script path are completely the same on the source node and all destination nodes.
When running on the source node, it works properly asking for a confirmation and the remote host's password. But the script that has just run successfully on the source node fails running in the remote ssh session: ssh-copy-id fails with the following error:
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/username/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: ERROR: Host key verification failed.
At that moment, no .ssh/known_hosts file is present on a remote node so I can't do ssh-keygen -R. What am I missing and how to make it work?
ssh $USER#$n "REMOTE=yes HOSTNAME=$n $0 ; rm -f $0"
Try running ssh with the "-tt" option to request a PTY (pseudo-TTY) for the remote session:
ssh -tt $USER#$n "REMOTE=yes HOSTNAME=$n $0 ; rm -f $0"
^^^
In the case that you're describing, you're launching ssh on the remote system to connect to a third system. The ssh instance doesn't have a saved copy of the third host's host key. So you'd normally expect ssh to prompt the user whether to continue connecting to the third host. Except that it's not prompting the user--it's just refusing to connect to the third host.
When ssh is invoked with a command to run on the remote system, by default it runs that command without a TTY. In this case, the remote ssh instance sees that it's running without a TTY and runs non-interactively. When it's non-interactive, it doesn't prompt the user for things like passwords and whether to accept a host key or not.
Running the local ssh instance with "-tt" causes it to request a PTY for the remote session. So the remote ssh instance will have a TTY and it will prompt the user--you--for things like host key confirmations.
ssh-copy-id is not copying your keys to remote hosts, it's adding them to ~/.ssh/authorized_keys and when you jump to that remote host there are no keys(or are they?) so there is nothig to copy further. And if ssh-copy-id run without -i option it'll copy(add to authorized_keys) all .pub keys from your ~/.ssh dir wich could be not desired so i suggest to run it like this ssh-copy-id -i $key $host
Be sure that on the destination side, the /etc/ssh/sshd_config is configured to accept the type of key that was generated.
PubkeyAcceptedKeyTypes ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa
I generated the key using ssh-keygen -t rsa -b 4096 ... however, up above the following line did not include the ,ssh-rsa at the end, so even though the ssh-copy-id updated my destination, the sshd did not accept rsa type generated keys. Once i added ,sha-rsa, the did systemctl restart sshd it worked!

How to make scp in Shell Script ask me for password

I am making a script to securely transfer data between my two machines through scp.
But in the script, it shows an error due to no password. So how can I make my shell script to ask me for password after executing scp command?
Here is my csh script.
# ssh shahk#sj-shahk
# ls -al
echo "Source Location of Remote Server - $1"
echo "Destination Location of Local Server - $2"
echo "File/Folder to be Transferred from Remote Server - $3"
echo "File Transfer Starts"
scp -rv $1/$3 <username>#<hostname>:$2
echo "File Transfer Completed"
# exit
Now I am using the above script with ssh in following way.
ssh <username>#<hostname> "<script name> <args>"
When I use in the above manner, it does not prompt for password while executing scp command.
You can use sshpass
https://www.cyberciti.biz/faq/noninteractive-shell-script-ssh-password-provider/
I have used it once to directly scp or ssh without prompting password.
For example :
sshpass -p 'password' scp file.tar.gz root#xxx.xxx.xxx.194:/backup
As mentioned by the other answer, sshpass will do the job perfectly. In the case where you can not install new packages on your local computer, you can also use expect (installed by default on most distros) to automate your interactive session.
The basic syntax of expect is to wait for the program to display a specific string (expect mystring), which triggers a specific behaviour (send command)
The following script shows the basic structure to implement what you need :
#!/usr/bin/expect -f
# syntax to specify which command to monitor
spawn scp myfile user#remote.host:/dest_folder
# this syntax means we expect the spawned program to display "password: "
# expect can understand regex and glob as well. read the man page for more details
expect "password: "
# the \r is needed to submit the command
send "PASSWORD\r"
# expect "$ " means we wait for anything to be written.
# change if you want to handle incorrect passwords
expect "$ "
send "other_command_to_execute_on_remote\r"
expect "$ "
send "exit\r"
As a side note, you can also set up passwordless authorizations through ssh keys.
#1) create a new ssh key on your local computer
> ssh-keygen -t rsa
#2) copy your public key to your remote server
# you will need to login, but only once. Once the key is on the remote server, you'll be able to connect without password.
> ssh-copy-id -i ~/.ssh/id_rsa.pub user#ip_machine
# OR
> cat ~/.ssh/id_rsa.pub | ssh user#ip_machine "cat - >> ~/.ssh/authorized_keys"
This tutorial explains how to use the keychain tool to manage several ssh keys and users.
ssh <username>#<hostname> "<script name> <args>"
scp will only read a password from a TTY, and it doesn't have a TTY in this case. When you run ssh and specify a command to be executed on the remote system (as you're doing here), ssh by default doesn't allocate a PTY (pseudo-tty) on the remote system. Your script and all of the commands launched from it--including scp--end up running without a TTY.
You can use the ssh -t option to make it allocate a tty on the remote system:
ssh -t <username>#<hostname> "<script name> <args>"
If you get a message like "Pseudo-terminal will not be allocated because stdin is not a terminal", then add another -t:
ssh -tt <username>#<hostname> "<script name> <args>"

SSH to Remote Server Bash Programming

I programmed a script which SSH to remote server and get status of GPU server by executing following "nvidia-smi", well that was just a description and purpose of script, but the question is I run this as "root" which can ssh to another server passwordless but users can not, how can I program the script to let user to run the script and get status? of course without entering password to remote server, any authentication can I use?
Here is the script:
#!/bin/bash
HOSTS="gpuserver01\ngpuserver02"
SCRIPTS="nvidia-smi"
echo -e "which GPU server do you want to check?\n$HOSTS\n"-----------------""
echo "Please Enter Numebr of GPU Server"
read ans
#for HOSTNAME in $ans ; do
if [ $ans = '1' ]; then
HOSTNAME="gpuserver01"
ssh ${HOSTNAME} "${SCRIPTS}"
else
HOSTNAME="gpuserver02"
ssh ${HOSTNAME} "${SCRIPTS}"
fi
#done
Thank you.
You can give permissions to your script for other users to run as root privileges.
run visudo, add below;
Cmnd_Alias CUSTOM_CMD=/path/to/script/myscript.sh
myUser1 ALL = (root) NOPASSWD:CUSTOM_CMD
if other users have same group.Let say otherUsers
Cmnd_Alias CUSTOM_CMD=/path/to/script/myscript.sh
%otherUsers ALL = (root) NOPASSWD:CUSTOM_CMD
Add normal user to remote host (example gpuuser01).
Create SSH keys for that user. [1] Then check, you can log in to gpuuser01 without password.
Create new script on remote host (eg. gpuserver01), with setuid flag [2], that will run nvidia-smi.
Now you can connect to remote host and execute your script as root wihout password.
Rewrite your script (that one from question).
[1] https://kb.iu.edu/d/aews
[2] http://www.cyberciti.biz/faq/unix-bsd-linux-setuid-file/

how to send different commands to multiple hosts to run programs in Linux

I am an R user. I always run programs on multiple computers of campus. For example, I need to run 10 different programs. I need to open PuTTY 10 times to log into the 10 different computers. And submit each of programs to each of 10 computers (their OS is Linux). Is there a way to log in 10 different computers and send them command at same time? I use following command to submit program
nohup Rscript L_1_cc.R > L_1_sh.txt
nohup Rscript L_2_cc.R > L_2_sh.txt
nohup Rscript L_3_cc.R > L_3_sh.txt
First set up ssh so that you can login without entering a password (google for that if you don't know how). Then write a script to ssh to each remote host to run the command. Below is an example.
#!/bin/bash
host_list="host1 host2 host3 host4 host5 host6 host7 host8 host9 host10"
for h in $host_list
do
case $h in
host1)
ssh $h nohup Rscript L_1_cc.R > L_1_sh.txt
;;
host2)
ssh $h nohup Rscript L_2_cc.R > L_2_sh.txt
;;
esac
done
This is a very simplistic example. You can do much better than this (for example, you can put the ".R" and the ".txt" file names into a variable and use that rather than explicitly listing every option in the case).
Based on your topic tags I am assuming you are using ssh to log into the remote machines. Hopefully the machine you are using is *nix based so you can use the following script. If you are on Windows consider cygwin.
First, read this article to set up public key authentication on each remote target: http://www.cyberciti.biz/tips/ssh-public-key-based-authentication-how-to.html
This will prevent ssh from prompting you to input a password each time you log into every target. You can then script the command execution on each target with something like the following:
#!/bin/bash
#kill script if we throw an error code during execution
set -e
#define hosts
hosts=( 127.0.0.1 127.0.0.1 127.0.0.1)
#define associated user names for each host
users=( joe bob steve )
#counter to track iteration for correct user name
j=0
#iterate through each host and ssh into each with user#host combo
for i in ${hosts[*]}
do
#modify ssh command string as necessary to get your script to execute properly
#you could even add commands to transfer the file into which you seem to be dumping your results
ssh ${users[$j]}#$i 'nohup Rscript L_1_cc.R > L_1_sh.txt'
let "j=j+1"
done
#exit no error
exit 0
If you set up the public key authentication, you should just have to execute your script to make every remote host do their thing. You could even look into loading the users/hosts data from file to avoid having to hard code that information into the arrays.

Linux script - password step cuts the flow

Lets assume the script i want to write ssh to 1.2.3.4 and then invokes
ls.
The problem is that when the line "ssh 1.2.3.4" is invoked, a password is
Required, hence, the flow is stopped, even when i fill the password,
The script wont continue.
How can i make the script continue after the password is given?
Thx!
You want to do public key authentication. Here are some resources which should get you going.
http://magicmonster.com/kb/net/ssh/auto_login.html
http://www.cs.rpi.edu/research/groups/vision/doc/auto/ssh/ssh_public_key_authentication.html
I would post a couple more links, but I don't have enough reputation points. ;) Just google on "SSH automated login" or "SSH public key authentication" if you need more help.
Actually you're trying to run ls locally but you have an ssh session opened. So it won't run ls until the session is opened. If you want to run ls remotely, you should use
ssh username#host COMMAND
Where command is the command you want to run. Ssh session will finish as soon as the command is invoked and you can capture its output normally.
I would suggest you to use RSA authentication method for script that needs ssh.
I just tried this script:
#!/bin/sh
ssh vps1 ls
mkdir temp
cd temp
echo test > file.txt
And it works. I can connect to my server and list my home. Then, locally, it creates temp dir, cd into it and then creates file.txt with 'test' inside.
write simple login bash script named login_to and give exec permissions (chmod 744 login_to)
#!/bin/bash
if [ $1 = 'srv1' ]; then
echo 'srv1-pass' | pbcopy
ssh root#11.11.11.11
fi
if [ $1 = 'foo' ]; then
echo 'barbaz' | pbcopy
ssh -t dux#22.22.22.22 'cd ~/somedir/someotherdir; bash'
fi
now use it like this
login_to srv1
login_to foo
When asked for password, just pate (ctrl+v or command+v) and you will be logged in.

Resources