Script to check passwordless connectivity between servers - shell

I have the following script. My requirement is if I give the username and IP address the script should check whether the host server has passwordless connectivity with the given server.
script.sh
#!/bin/sh
echo "Enter username"
read user
echo "Enter IP address"
read ip
echo "Enter condition"
read conditon
if [ $condition == "test" ]
then
ssh -o 'PreferredAuthentications=publickey' $user#$ip "echo"
fi
The above script checks for passwordless connectivity and exits. I want the script to return "success" if the connection is there or "No connection" if there is no passwordless connection between the hosts.
Thanks.

You can give an extra option to ssh that sets it in BatchMode
BatchMode
If set to yes, passphrase/password querying will be disabled. This option is useful in scripts and other batch jobs where no user is present to supply the password. The argument must be yes or no (the default).
source: man sshconfig
The following line will return the requested error code
ssh -oBatchMode=yes user#server echo > /dev/null 2>&1
This will return 0 if it can log in and will return a non-zero value (255) if it fails to login.
So you could do something like:
ssh -oBathMode=yes "${user}#${server}" echo > /dev/null 2>&1 && echo "Success" || echo "No Connection"
Or you could even let the server answer Success as
ssh -oBathMode=yes "${user}#${server}" echo Success 2>/dev/null || echo "No Connection"

Prerequisites
Access to command line/terminal window
User with sudo or root privileges
A local server & a remote server
SSH access to a remote server via command line/terminal window
Before You Start
Check for existing SSH Keys, using the below command
ls -al ~/.ssh/id_*.pub
If the output tells you there are no such files, move on to the next step, which shows you how to generate SSH keys.
Step 1: Generate SSH Key Pair
ssh-keygen -t rsa -b 4096 -C "your_email#domain.com"
Next, type in the path where you want to store the keys or hit
Enter to accept the default path.
It also asks you to set a passphrase, this is to ensure more secure connection. Note that, the Passphrase may be interrupted when you set up automated processes. Else, one can just press Enter to skip this step.
The output shows you the identification & about where is your public key stored along with the key fingerprints.
Verify your newly created SSH key pair, using the below command.
ls -al ~/.ssh/id_*.pub
Step 2: Uploading the Public Key to Remote Server
There are 2 options, that one can adopt:
Using ssh-copy-id Command
Using cat Command
Using ssh-copy-id command
ssh-copy-ide [remote_username]#[server_ip_address]
Using cat Command
ssh [remote_username]#[server_ip_address] mkdir -p .ssh
Type in the password for remote server, and then cat to view the contents of the stored Public Key
cat .ssh/id_rsa.pub | ssh [remote_username]#[server_ip_address] 'cat >> .ssh/authorized_keys'
Step 3: Log in to Server Without Password
Final step is to check whether the setup works fine or not.
ssh [remote_username]#[server_ip_address]
Troubleshooting, if found any errors
If you are still prompted for a password after going through all the steps, start by editing file permissions on the remote server.
Set permissions 700 for the .ssh directory.
Set permissions 640 for the .ssh/authorized_keys directory.
Edit file permissions using this command:
ssh [remote_username]#[server_ip_address] "chmod 700 .ssh; chmod 640 .ssh/authorized_keys"
References:
(https://stackoverflow.com/a/52744882/18154805)

Related

How to run commands on a remote host with an existing user on that machine

I am writing a shell scripts that requires to run commands on multiple remote host based on condition it satisfies. how can i run the commands on the remote host using its key pair and assign the output of those commands to a variable on the primary host.
I tried using
sshpass -f keypair hostname 'command' | 'commands'
but this command executed on the host itself.
Use command substitution to assign the output of a command to a variable. You also need to run the ssh command and specify the remote username.
variable=$(sshpass -f keypair ssh username#hostname 'command')
1) Add host public keys (~/.ssh/id_rsa.pub)to remote user authenticated keys (~/.ssh/authorized_keys)
You will append the content of the public key to the authorized_keys
2) If you don't have this key you may generate it
ssh-keygen -t rsa
3) after that you can
ssh <REMOTE USER NAME>#RemoteHOST <command>
As example
ssh mebada#123.44.2.12 ls
4) If you have list of commands you may scp shell file and execute it from there ( without password too ) and it will override the remote
scp /path/to/shell.file user#host:/path/to/remote
ssh user#host chmod u+x /path/to/remote/shell.file
ssh user#host /path/to/remote/shell.file

Run ssh and execute command

Using heredoc to execute multi-line commands on a remote machine.
Trying to get pid of a server to kill that server located in the remote machine
#!/bin/bash
HOST_IP="10.180.5.23"
read -p "For HOST RESTART press 1" num
if [ "$num" == "1" ]
then
ssh -t -t $HOST_IP << 'EOSSH'
line=$(pgrep -f host_server1)
echo $line
arr=($line)
sudo kill -9 "${arr[1]}"
EOSSH
fi
Error : kill: (15015) - Operation not permitted
There heredoc works fine but sudo is expecting you to type in a password and there is no terminal connected to the ssh executing the commands on the server. You have two options, neither is entirely secure:
Allow the user on the server to sudo without a password
Put the lines from the heredoc into a script on the server and make it setui (sticky) so that it executes as root.
These apply generally to running scripts as root. Your other option that is specific to this case is to log in as the user running the server process so that you do not get operation not permitted from the kill.

Bash Script : Execute unix commands inside a remote server

I am trying to login to Server B from Server A and perform simple UNIX commands on Server B using a shell script. The code is as follows. But ls -al is displaying the result of Server A and not the one that is logged on to i.e Server B. Any inputs are highly appreciated. Thanks
#!/bin/bash
clear
sshpass -p password ssh hostname
ls -al
exit
When the shell interprets a script file, it creates a child process to
execute each command line. So, the command lines after sshpass -p password ssh hostname are not actually executed inside the ssh
session to hostname, but in the host where the bash instance is
running.
To achieve what you want, you can check ssh(1) usage line and note that there is a [command] argument, that says:
If command is specified, it is executed on the remote host instead
of a login shell.
So, one way to do it is sshpass -p password ssh hostname ls -la. Another way which can provide some more flexibility is:
#!/bin/bash
clear
cat | sshpass -p password ssh hostname <<EOF
ls -la
EOF
Which would make ssh start a login shell in the remote host and pass
to its stdin the lines provided in the Here Document. The remote
shell would then interpret those strings as commands and execute them.
If you just want to run ls -al on the remote server, put it on the same line as the ssh command like
sshpass -p password ssh hostname ls -al
it will automatically exit when it gets to the end of the command so you don't need to put exit
Also, if you're going to be doing this and don't want to interactively enter the password, you might want to look at sharing public/private keys and using that so it won't ever ask for a password (unless you password protect your private key)

how to pass password to sftp connection in shell script

I have an sftp connection to a server in Unix.
Without password, I use the syntax to connect and execute command
sftp -b $user#$server_name
Can anyone suggest me how can I write a shell script to connect a remote server non interactively using a password
Try with this below option,
lftp -u $user,$pass sftp://$host << --EOF--
cd $directory
put $srcfile
quit
--EOF--
You could use ~/.ssh/config file.
#
# ~/.ssh/config
#
Host servername
Hostname 127.127.127.127
Port 22
User root
#EOF: config
Then simply connect with "ssh servername" and if you don't want to use password you can use SSH key. Here is good tutorial on how to do that > http://www.cyberciti.biz/tips/linux-multiple-ssh-key-based-authentication.html
If you just want to pass user/server from terminal, you can do this.
#!/bin/bash
sftp -b "$1"#"$2"
then use it like this './sftp.sh user server'
use SCP like this;
scp -P 22 user#server:/dir/file.tgz ~/Desktop/
use SFTP like this;
sftp user#server:/dir/file.tgz ~/Desktop/file.tgz
You can also try this;
sftp user#host <<EOF
get /dir/file.tgz
rm /dir/file.tgz
EOF
The best way to do this would be to create a key pair on the client, and add the key to the target user's ~/.ssh/authorized_keys.
To create a key pair, run ssh-keygen and when it asks for a password, just hit return to indicate "no password". Then either run ssh-copy-id $user#$server_name or manually create a ~/.ssh/authorized_keys on the server and copy the contents of the ~/.ssh/id_rsa.pub from the client into it (ssh-copy-id isn't available on all machines, so on some you'll have to do it manually).
Now you should be able to run ssh or scp without a password, as it should use your key instead. If it doesn't work, make sure that the permissions on your ~/.ssh/ directory and contents are correct on both machines; the directory should be 0700 (drwx------) and the files should be 600 (-rw-------). Also check that key authentication is enabled on both the client and the server.

How to run the sftp command with a password from Bash script?

I need to transfer a log file to a remote host using sftp from a Linux host. I have been provided credentials for the same from my operations group. However, since I don't have control over other host, I cannot generate and share RSA keys with the other host.
So is there a way to run the sftp command (with the username/password provided) from inside the Bash script through a cron job?
I found a similar Stack Overflow question, Specify password to sftp in a Bash script, but there was no satisfactory answer to my problem.
You have a few options other than using public key authentication:
Use keychain
Use sshpass (less secured but probably that meets your requirement)
Use expect (least secured and more coding needed)
If you decide to give sshpass a chance here is a working script snippet to do so:
export SSHPASS=your-password-here
sshpass -e sftp -oBatchMode=no -b - sftp-user#remote-host << !
cd incoming
put your-log-file.log
bye
!
Another way would be to use lftp:
lftp sftp://user:password#host -e "put local-file.name; bye"
The disadvantage of this method is that other users on the computer can read the password from tools like ps and that the password can become part of your shell history.
A more secure alternative which is available since LFTP 4.5.0 is setting the LFTP_PASSWORD environment variable and executing lftp with --env-password. Here's a full example:
export LFTP_PASSWORD="just_an_example"
lftp --env-password sftp://user#host -e "put local-file.name; bye"
# Destroy password after use
export LFTP_PASSWORD=""
LFTP also includes a cool mirroring feature (can include delete after confirmed transfer --Remove-source-files):
lftp -e 'mirror -R /local/log/path/ /remote/path/' --env-password -u user sftp.foo.com
EXPECT is a great program to use.
On Ubuntu install it with:
sudo apt-get install expect
On a CentOS Machine install it with:
yum install expect
Lets say you want to make a connection to a sftp server and then upload a local file from your local machine to the remote sftp server
#!/usr/bin/expect
spawn sftp username#hostname.com
expect "password:"
send "yourpasswordhere\n"
expect "sftp>"
send "cd logdirectory\n"
expect "sftp>"
send "put /var/log/file.log\n"
expect "sftp>"
send "exit\n"
interact
This opens a sftp connection with your password to the server.
Then it goes to the directory where you want to upload your file, in this case "logdirectory"
This uploads a log file from the local directory found at /var/log/ with the files name being file.log to the "logdirectory" on the remote server
You can use lftp interactively in a shell script so the password not saved in .bash_history or similar by doing the following:
vi test_script.sh
Add the following to your file:
#!/bin/sh
HOST=<yourhostname>
USER=<someusername>
PASSWD=<yourpasswd>
cd <base directory for your put file>
lftp<<END_SCRIPT
open sftp://$HOST
user $USER $PASSWD
put local-file.name
bye
END_SCRIPT
And write/quit the vi editor after you edit the host, user, pass, and directory for your put file typing :wq .Then make your script executable chmod +x test_script.sh and execute it ./test_script.sh.
I was recently asked to switch over from ftp to sftp, in order to secure the file transmission between servers. We are using Tectia SSH package, which has an option --password to pass the password on the command line.
example : sftp --password="password" "userid"#"servername"
Batch example :
(
echo "
ascii
cd pub
lcd dir_name
put filename
close
quit
"
) | sftp --password="password" "userid"#"servername"
I thought I should share this information, since I was looking at various websites, before running the help command (sftp -h), and was i surprised to see the password option.
You can override by enabling Password less authentication. But you should install keys (pub, priv) before going for that.
Execute the following commands at local server.
Local $> ssh-keygen -t rsa
Press ENTER for all options prompted. No values need to be typed.
Local $> cd .ssh
Local $> scp .ssh/id_rsa.pub user#targetmachine:
Prompts for pwd$> ENTERPASSWORD
Connect to remote server using the following command
Local $> ssh user#targetmachine
Prompts for pwd$> ENTERPASSWORD
Execute the following commands at remote server
Remote $> mkdir .ssh
Remote $> chmod 700 .ssh
Remote $> cat id_rsa.pub >> .ssh/authorized_keys
Remote $> chmod 600 .ssh/authorized_keys
Remote $> exit
Execute the following command at local server to test password-less authentication.
It should be connected without password.
$> ssh user#targetmachine
The easiest way I found to accomplish this, without installing any third-party library like Expect, SSHPASS...etc, is by using a combination of CURL, and SFTP. Those two are almost in every Linux machine.
This is the command you should execute, after changing the values.
curl -k "sftp://SERVER_IP:SERVER_PORT/FULL_PATH_OF_THE_FILE" --user "SERVER_USER:SERVER_PASSOWRD" -o "THE_NAME_OF_THE_FILE_AFTER_DOWNLOADING_IT"
Example:
curl -k "sftp://10.10.10.10:77/home/admin/test.txt" --user "admin:123456" -o "test.txt"
Explanation:
We are connecting to the server 10.10.10.10:77 using the username admin and password 123456, to move the file /home/admin/test.txt from that server to the server you are using currently to execute the above command.
Combine sshpass with a locked-down credentials file and, in practice, it's as secure as anything - if you've got root on the box to read the credentials file, all bets are off anyway.
Bash program to wait for sftp to ask for a password then send it along:
#!/bin/bash
expect -c "
spawn sftp username#your_host
expect \"Password\"
send \"your_password_here\r\"
interact "
You may need to install expect, change the wording of 'Password' to lowercase 'p' to match what your prompt receives. The problems here is that it exposes your password in plain text in the file as well as in the command history. Which nearly defeats the purpose of having a password in the first place.
You can use sshpass for it. Below are the steps
Install sshpass For Ubuntu - sudo apt-get install sshpass
Add the Remote IP to your known-host file if it is first time
For Ubuntu -> ssh user#IP -> enter 'yes'
give a combined command of scp and sshpass for it.
Below is a sample code for war coping to remote tomcat
sshpass -p '#Password_For_remote_machine' scp /home/ubuntu/latest_build/abc.war #user##RemoteIP:/var/lib/tomcat7/webapps
You can use a Python script with scp and os library to make a system call.
ssh-keygen -t rsa -b 2048 (local machine)
ssh-copy-id user#remote_server_address
create a Python script like:
import os
cmd = 'scp user#remote_server_address:remote_file_path local_file_path'
os.system(cmd)
create a rule in crontab to automate your script
done
A few people have mentioned sshpass but not many clear coding examples...
This is how we are doing it with bash scripts for rsync backups:
sshpass -p "${RSYNC_PASSWORD}" sftp "${RSYNC_USER}"#"${RSYNC_REMOTE_HOST}"
Keep in mind you will have to sudo apt install sshpass before this works properly.

Resources