Bash: How to use a secret file for a script? - bash

I've created a really long script which fully automates installation and configuration of a web server in my company. During the script runtime it accesses some remote server using scp and ssh in order to download configuration files and I'd like to be able to have a secret file which holds the password (it's always the same password) and that the script will use this file without the need that i'll insert it manually. some lines from the script look like this:
/usr/bin/scp root#192.168.1.10:/etc/mail/sendmail.cf /etc/mail/
/usr/bin/scp -r root#192.168.1.10:/etc/yum.repos.d /etc/
/usr/bin/ssh root#192.168.1.10 'rpm -qa --queryformat "%{NAME}\n" >/tmp/sw.lst'
/usr/bin/scp root#192.168.1.10:/tmp/sw.lst /tmp/
/usr/bin/xargs yum -y install < /tmp/sw.lst
I know about the method of #ssh-keygen and #ssh-copy-id but the problem is that the script will run every time on a different machine and I don't want to exchange the keys before each run.

When i had to do something like that, i used expect and a wrapper script that would fetch a password from a file.
I.e. in my password file i'd have something like
root#192.168.1.10 ThisIsMyPass
user#localhost thisIsMyOtherPass
and then have the wrapper script get (it could be simple as grep "root#192.168.1.10" ~/.passwords | cut -d ' ' -f2)
Im guessing there are more appropriate methods, but with this one you only need to keep your wrapper and password file protected and you can make your setup script public.

Related

FTP using Unix shell script and then triggering a task

I have a requirement at hand in Unix where I need to build a shell script.
The requirement is below:
I need to SFTP a file (let's say CSV file) from my dev server to uat server.
After the SFTP is done to that server, as soon as the file comes there and the exit code of the previous SFTP is 0, I need to trigger a task (this task I can take care of).
I have the basic idea on SFTP but I am not aware of how to trigger the next task as soon as the file comes to the uat server.
Please need a pseudo code to start my exploration.
If you want to copy from somewhere to your local machine and run a command locally
If you have access to ssh then it can be done easily which I am doing it usually.
For example I have a backup file from one of my server. We can get a copy this way using scp
scp root#server:/home/weekly.sql.zip .
. means put the file with its name here on this directory I am in now
the problem with this command is that it has an interaction for getting password so to eliminate this we can install sshpass and use it this way:
sshpass -p'your-password' scp root#server:/home/weekly.sql.zip .
Since we are using bash and it take care of exiting code if you add and && operator then you can add a second command so to be triggered after first command has successfully done.
sshpass -p'your-password' scp root#server:/home/weekly.sql.zip . && unzip weekly.sql.zip
First task is copying a file and second is to unzip it.
installing sshpass:
sudo apt install -y sshpass
If you want to copy from your local machine to somewhere and run a command remotely
sshpass -p'your-password' scp test.txt root#address:/home/ && sshpass -p'your-password' ssh root#address cat /home/test.txt
Which does this:
copy file test.txt to the server
then read it by cat command

How to use signify in ubuntu 16.04?

I am trying to do a remote desktop connection between Ubuntu desktop and another Ubuntu system. I want to develop an application so it is necessary to use shell command.
ssh -X or -Y username#server_ip
I know this command is for trusted and untrusted connection between two systems but here username is necessary for connection so it is necessary to ask username and password to each user for connection. so I have created a bash file for getting input from the user. its name myscript.sh
#!/bin/bash
read -p 'Username: ' uservar
read -sp 'Password: ' passvar
sleep 10
and I want to use this variable value in another file. I wrote below code and file name terminal.sh.
#!/bin/bash<br>
xterm -e /file_path/myscript.sh
sshpass -p $passvar ssh -X $uservar#$remote_ip /usr/bin/xfce4-session
but this code is not working. I want myscript.sh user input value in terminal.sh file. one person suggests me to use signify. how to use signify here? Can anyone suggest a solution? thanks in advance.
Normally, you should set-up public/private key authentication with ssh. Anything else is a hack to get the same result.
In this case, you have to store the credentials (uid/pw) somewhere to be able to use them in your second script. That could be:
#!/bin/bash
read -p 'Username: ' uservar
read -sp 'Password: ' passvar
and call as . myscript.sh, or store them somewhere in a file for use (which is security-wise a little issue).
If you really cannot set-up your p/p-keys, you should probably put (as Inian suggests) put the prompting in the same script..

Concatenating a local file with a remote one

These three lines of code require authentication twice. I don't yet have password-less authentication set up on this server. In fact, these lines of code are to copy my public key to the server and concatenate it with the existing file.
How can I re-write this process with a single ssh command that requires authentication only once?
scp ~/local.txt user#server.com:~/remote.txt
ssh -l user user#server.com
cat ~/remote.txt >> ~/otherRemote.txt
I've looked into the following possibilities:
command sed
operator ||
operator &&
shared session: Can I use an existing SSH connection and execute SCP over that tunnel without re-authenticating?
I also considered placing local.txt at an openly accessible location, for example, with a public dropbox link. Then if cat could accept this as an input, the scp line wouldn't be necessary. But this would also require an additional step and wouldn't work in cases where local.txt cannot be made public.
Other references:
Using a variable's value as password for scp, ssh etc. instead of prompting for user input every time
https://superuser.com/questions/400714/how-to-remotely-write-to-a-file-using-ssh
You can redirect the content to the remote, and then use commands on the remote to do something with it. Like this:
ssh user#server.com 'cat >> otherRemote.txt' < ~/local.txt
The remote cat command will receive as its input the content of ~/local.txt, passed to the ssh command by input redirection.
Btw, as #Barmar pointed out, specifying the username with both -l user and user# was also redundant in your example.

How to automate password entry?

I want to install a software library (SWIG) on a list of computers (Jenkins nodes). I'm using the following script to automate this somewhat:
NODES="10.8.255.70 10.8.255.85 10.8.255.88 10.8.255.86 10.8.255.65 10.8.255.64 10.8.255.97 10.8.255.69"
for node in $NODES; do
scp InstallSWIG.sh root#$node:/root/InstallSWIG.sh
ssh root#$node sh InstallSWIG.sh
done
This way it's automated, except for the password request that occur for both the scp and ssh commands.
Is there a way to enter the passwords programmatically?
Security is not an issue. I’m looking for solutions that don’t involve SSH keys.
Here’s an expect example that sshs in to Stripe’s Capture The Flag server and enters the password automatically.
expect <<< 'spawn ssh level01#ctf.stri.pe; expect "password:"; send "e9gx26YEb2\r";'
With SSH the right way to do it is to use keys instead.
# ssh-keygen
and then copy the *~/.ssh/id_rsa.pub* file to the remote machine (root#$node) into the remote user's .ssh/authorized_keys file.
You can perform the task using empty, a small utility from sourceforge. It's similar to expect but probably more convenient in this case. Once you have installed it, your first scp will be accomplished by following two commands:
./empty -f scp InstallSWIG.sh root#$node:/root/InstallSWIG.sh
echo YOUR_SECRET_PASSWORD | ./empty -s -c
The first one starts your command in the background, tricking it into thinking it's running in interactive mode on a terminal. The other one sends it data from stdin. Of course, putting your password anywhere on command line is risky due to shell history being preserved, users being able to see it in ps results etc. Not secure either, but a bit better thing would be to store the password in a file and redirect the second command's input from that file instead of using echo and a pipe.
After copying to the server, you can run the script in a similar manner:
./empty -f ssh root#$node sh InstallSWIG.sh
echo YOUR_SECRET_PASSWORD | ./empty -s -c
You could look into setting up passwordless ssh keys for that. Establishing Batch Mode Connections between OpenSSH and SSH2 is a starting point, you'll find lots of information on this topic on the web.
Wes' answer is the correct one but if you're keen on something dirty and slow, you can use expect to automate this.

Specify password to sftp in a Bash script [duplicate]

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.

Resources