Specify password to sftp in a Bash script [duplicate] - bash

This question already has answers here:
How to run the sftp command with a password from Bash script?
(12 answers)
Closed 7 years ago.
I am trying to write a script to back up a file over SFTP. The problem is, it requires a password, and I see no way to manually specify a password to SFTP. I've heard about requiring no password by using public keys, but that requires being able to ssh into the remote server and modify some configuration files, which I cannot do.
Currently my solution is to use cURL, but that is insecure (uses normal FTP). I also looked at the .netrc file, but that seems to be for FTP instead of SFTP. How do I manually specify a password for sftp?

Lftp allows specifying passwords for both ftp and sftp and does not require public keys at all. Your sh sync script may look like this:
#!/bin/sh
# Define folders
THEFOLDER='/mnt/my/folder'
# List files
THEFILES=`ls -p $THEFOLDER | grep -v "/"`
for file in $THEFILES
do
echo "Processing $file"
lftp -u login,password -e "put $THEFOLDER/$file;quit" theftp/sub/folder
done

cURL can support sftp, as documented by the manual:
USING PASSWORDS
FTP
To ftp files using name+passwd, include them in the URL like:
curl ftp://name:passwd#machine.domain:port/full/path/to/file
or specify them with the -u flag like
curl -u name:passwd ftp://machine.domain:port/full/path/to/file
FTPS
It is just like for FTP, but you may also want to specify and use
SSL-specific options for certificates etc.
Note that using FTPS:// as prefix is the "implicit" way as described in the
standards while the recommended "explicit" way is done by using FTP:// and
the --ftp-ssl option.
SFTP / SCP
This is similar to FTP, but you can specify a private key to use instead of
a password. Note that the private key may itself be protected by a password
that is unrelated to the login password of the remote system. If you
provide a private key file you must also provide a public key file.

You might also want to consider using python (the paramiko module), as it can quickly be called from the shell.
Install the Module
pip install paramiko
Example FTP Upload Script
import paramiko
username = 'my_username'
password = 'my_password'
transport = paramiko.Transport((server, 22))
transport.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(transport)
local_filename = '/tmp/filename'
remote_filename = 'MyFiles/temp.txt'
sftp.put( local_filename, remote_filename )

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 \"assword\"
send \"your_password_here\r\"
interact "
Put that in a file called sftp_autologin.sh. The \r sends an to sftp to execute the command. I don't include the 'p' in password because on some systems it's uppercase, others lowercase. expect spawns the sftp command. Waits for the string 'assword' to be seen and sends a command. Then ends.
To get this to work:
Install expect, I'm using 5.44.1.15
Make sure you can sftp to your box in interactive mode and supply a password.
Make sure this bash script has executable permissions.
Then run it:
chmod +x sftp_autologin.sh
./sftp_autologin.sh
It should drop you into the sftp commandline without prompting you for a password.
Is it insecure?
It's about the most unsecure command you can run. It exposes the password to the commandline history, to anyone else who can read 'ps' output, and basically defeats the entire purpose of passwords all together.
But hey what's another log on the fraud fire, it's only about 250b dollars in victim losses per year. Lets go for 500b.
This automatically runs some commands with the sftp shell and exits automatically when done:
#!/bin/bash
expect -c "
spawn sftp myuser#myserver.com
expect \"assword\"
send \"yourpassword\r\"
expect \"sftp\"
send \"get your_directory/yourfilename.txt\r\"
expect \"sftp\"
send \"exit\r\"
interact "

In order to use public keys you do not need to modify any "configuration files". You merely need to leave a copy of your public key in a place where ssh knows to look (normally ~/.ssh/authorized_keys). You can do this with sftp. If you haven't established any authorized_keys file on the server, you can simply put your id_rsa.pub file in its place.

You can't specify a password to ssh / scp or sftp from the command line. The only way to connect without prompting for a password is to use public key authentication.
You say that you can't ssh to the server to modify configuration files but if you can sftp to the server you can probably upload your public key.
Your public key just has to go under the .ssh directory in your home directory.

Related

Automating SFTP password authentication on macOS for use with -b batch processing?

I want a script to upload daily files using sftp. Unfortunately, the remote server doesn't support ssh keys (it's my customer's server and for some reason they can't or won't change it despite countless recommendations). So I need to somehow log in automatically using password authentication.
I found many different solutions (here on SO and elsewhere) but they all seem to use tools like sshpass, spawn, expect, send etc. Unfortunately my script is to be used on macOS and these tools aren't available there.
I fully realize it is NOT secure to use plaintext passwords in a script or on the command line. But using ssh keys is simply not an option at this stage.
So, is it possible to run sftp from the shell and specify the password either on the command line in plaintext, or specify some argument with a filename that contains the password?
Addition: after #MartinPrikryl's comment I got sshpass to work, by using brew install esolitos/ipa/sshpass.
However now I found out this doesn't work properly when I use the -b batch.txt parameter for sftp to process a bunch of commands. The batches I'm processing are typically a bunch of get and put commands.
So this works:
sshpass -f MyPassword.txt sftp rocketnuts#example.com
(I am logged in and getting the sftp prompt)
But this does not:
sshpass -f MyPassword.txt sftp -b list.txt rocketnuts#example.com
I'm getting this error:
rocketnuts#example.com: Permission denied (password).
So apparently the way sshpass sends the password to sftp somehow interferes with the batch input from the -b parameter.
Is there a way to make sshpass (or another form of scriptable authentication) work in combination with the -b option??
First, you can install sshpass even on MacOS:
How to install sshpass on Mac?
Though indeed, with -b switch, the sftp probably cannot accept a password, as the -b disables all interactive input (what sshpass simulates).
As an alternative to -b, you can use an input redirection:
sshpass -f MyPassword.txt sftp rocketnuts#example.com < list.txt

Running a script that's requires password in between

I'm running a script that copies files from another server.... It's prompting for a password of that server... Every time I need to enter the password manually... So s there any way to automate this?
scp root#ip:file_location destination
Note for security purposes I was not supposed to use password less login, or ssh
You can try to use sshpass which takes the password from an evironment variable named "SSHPASS" if switch -e is provided. So you can use something like:
export SSHPASS=<yourpw>
sshpass -e scp <sourcefile> user#ip:<targetpath/filename>
But of course it still uses ssh underneath, like Sergiy explained in the comment.

How to hardcode password in shell script?

I am writing a recursive code to copy a file (mak.txt) from one linux server to multiple other servers. It fetches the server name from mserver.txt file. But for each server we have to provide password which I want to hard code in the script itself. I tried below code but it didn't worked:
while read SERVER PASSWORD
do
sshpass -p "$PASSWORD" scp mak.txt user#$server:/tmp/
done <./mserver.txt

ssh to another server with different username

I have to write a shell script which ssh to another server with other username without actually asking for a password from the user?
Due to constraints I cannot use key based authentication.
let,
Source Server -- abc.efg.com
Source UserName -- tom
Source Password -- tom123
Destination Server -- xyz.efc.com
Destination UserName -- bob
destination Password -- bob123
I have to place the bash script in source server.
Please let me know if something could be done using expect tool and/or sshpass.
It is okay for me to hardcode the password for destination server in the bash script but I cannot bear an interactive session, simply when I run he script, I want to see the destination server logged in with another username.
Thanks in Advance.
You want to use key-authentication http://ornellas.apanela.com/dokuwiki/pub:ssh_key_auth
Generate your keys ssh-keygen
Copy the keys to your new box ssh-copy-id -i ~/.ssh/id_rsa.pub me#otherhost.com
ssh to other host without password ssh me#otherhost.com
You can use expect to wrap ssh, but it's pretty hectic, and fails easily when there are network errors, so test it well or use a script specifically designed for wrapping ssh passwords. Key based authentication is better.
You can prevent interactive sessions by redirecting standard input from the null device, ie.
ssh me#destination destination-command < /dev/null
About placing the script in the source server, if the script you are running is local, rather than remote, then you can pass the script on standard input, rather than the command line:
cat bashscript.sh | ssh me#destination
You can install the sshpass program, which lets you write a script like
#!/bin/bash
sshpass -p bob123 ssh UserName#xyz.efc.com
The answer is that you can't as OpenSSH actively prevent headless password-based authentication. Use key-based authentication.
You may be able to fork the OpenSSH client code and patch it, but I think that is a bit excessive.

SSH in shell script with password

I want to write one shell script like
command1
ssh vivek#remotehost
fire command on remote host
Now I have password in pass.txt . But when I change stdin with file. It is not reading password from file.
script.sh < password.txt
It is prompting for the password in place of reading password from the file.
What I am doing wrong ?
Second problem is that shell script don't shows the command fired. Is there a way , I can show fired command from it ?
Note :
I don't have key based access on remote system. I can only use password based login for ssh.
You can use ssh-agent or expect (the programing language) to do this.
OpenSSH ssh does not reads the password from stdin but from /dev/tty. That's why you have to use Expect or some other similar tool to automate it.
plink is another client, also available for Linux/Unix that accepts the password as a parameter on the command line... though that has some ugly security implications.
Okay, just to mention yet another option: sshpass is a tool developed for exactly the task of "fooling" regular openssh client to accept password non-interactively.

Resources