securely passing password through bash - bash

I am building a bash script for my work to make initial setup and windows-domain join for our Ubuntu machines easy enough for someone who knows nothing about Linux can do it. I have found a lot of people that say that you shouldn't pass passwords through a script but to be efficient, I have to. The script prompts for info and credentials in the beginning and it needs to be able to be left to do it's job without interaction. I can't have it visible through ps when I pass it and I can't have it stored as an unsecured variable. Any suggestions?

If you really must do this, you can read the credentials into variables with read -s early in the script and then pass those values to the prompts. For example:
read -p "Enter your username: " username
read -sp "Enter your password: " password
echo
I included the blank echo because the -s option for read prevents the user's typing from appearing in the terminal, including the new line usually created after a user presses Enter when answering a prompt.
You can then use the $username and $password variables for the rest of your script and the credentials will not have to be stored outside of memory, meaning they will be lost/destroyed after the script completes.
However, note that any programs or utilities which take the credentials as command-line arguments will display those to other users on the machine running the script. For example, if I were to run a MySQL query using this method, I could do:
mysql -u "${username}" -p"${password}" -e "SHOW DATABASES;"
Other users on the machine could see the credentials while that was running with something like ps:
ps -ef | grep mysql
...
watrudoin 29512 29443 0 12:57 pts/4 00:00:00 mysql -u MyUserName -phunter2 -e SHOW DATABASES
You just need to be aware that what you are doing is not necessarily secure, but it seems that you already are.

Related

Stop script from prompting for my password over and over

We have a script I use at work, that I did not write, that when its doing it thing prompts for same password about 5-6 times. I'd like to write something into it that when it asks for the password the first time, it stores the pw and autocompletes it each time thereafter. Is it possible to do this is a bash script? My understanding us the script is doing an ssh to another server and running an update on a file to make sure it has the most current version and if you are entering more than one user into the file it need to ask every time it updates.
First off, remember this is TERRIBLE SECURITY PRACTICE!!! With that in mind, what is the reason for the password prompt? When using sudo, you can always do this:
#!/bin/bash
read -s PASSWORD
echo $PASSWORD | sudo -S <whatever you want to do that prompts for password>
Explanation:
sudo -S reads password from stdin
Source: https://superuser.com/questions/67765/sudo-with-password-in-one-command-line
So in conclusion, you can use sudo along with password from stdin to whatever you want to do.
I hope this helps!

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..

Set up TightVNC programmatically with BASH

I'm writing a script to set up VNC (amongst other things) on many debian based devices. I want to include VNC in this setup (specifically, tightVNC if possible) and have it set a given password (randomly generated by the script). The problem is, every guide I find seems to assume that a human is doing this, and is ready to sit and type in the password and press enter. I can't seem to get Bash to echo a password to VNC (it always says 'password too short') nor can I get 'expect' to work properly.
An example guide I found looks like this:
http://www.penguintutor.com/linux/tightvnc
I'm looking for something similar to this:
#!/bin/bash
echo "Going to configure VNC"
#turn on vnc server
tightvncserver
#spit out password to vnc server for first run only
echo $password
#confirm the pw
echo $password
But, on every virginal run of tightvncserver it always asks for a password to be inputted by hand:
Going to configure VNC
You will require a password to access your desktops.
Password: Password too short
How can I #1 get around this, or #2 use bash / expect to GIVE it a password to make it happy?
# Configure VNC password
umask 0077 # use safe default permissions
mkdir -p "$HOME/.vnc" # create config directory
chmod go-rwx "$HOME/.vnc" # enforce safe permissions
vncpasswd -f <<<"$password" >"$HOME/.vnc/passwd" # generate and write a password
Modify to taste, if your packaging for tightvnc uses a location other than ~/.vnc/ for the passwd file.
If you have separate view-only and full-control passwords, then:
vncpasswd -f <<<"$full_password"$'\n'"$view_password" >"$HOME/.vnc/passwd"
If you needed compatibility with /bin/sh (or otherwise weren't using #!/bin/bash shebangs), this would instead be:
vncpasswd -f >"$HOME/.vnc/passwd" <<EOF
$full_password
$view_password
EOF

How to input automatically when running a shell over SSH?

In my shell script I am running a command which is asking me for input.
How can I give the command the input it needs automatically?
For example:
$cat test.sh
ssh-copy-id tester#10.1.2.3
When running test.sh:
First, it will ask:
Are you sure you want to continue connecting (yes/no)?
Then, it will ask me to input the password:
tester#10.1.2.3's password:
Is there a way to input this automatically?
For simple input, like two prompts and two corresponding fixed responses, you could also use a "here document", the syntax of which looks like this:
test.sh <<!
y
pasword
!
The << prefixes a pattern, in this case '!'. Everything up to a line beginning with that pattern is interpreted as standard input. This approach is similar to the suggestion to pipe a multi-line echo into ssh, except that it saves the fork/exec of the echo command and I find it a bit more readable. The other advantage is that it uses built-in shell functionality so it doesn't depend on expect.
For general command-line automation, Expect is the classic tool. Or try pexpect if you're more comfortable with Python.
Here's a similar question that suggests using Expect: Use expect in bash script to provide password to SSH command
There definitely is... Use the spawn, expect, and send commands:
spawn test.sh
expect "Are you sure you want to continue connecting (yes/no)?"
send "yes"
There are more examples all over Stack Overflow, see:
Help with Expect within a bash script
You may need to install these commands first, depending on your system.
Also you can pipe the answers to the script:
printf "y\npassword\n" | sh test.sh
where \n is escape-sequence
ssh-key with passphrase, with keychain
keychain is a small utility which manages ssh-agent on your behalf and allows the ssh-agent to remain running when the login session ends. On subsequent logins, keychain will connect to the existing ssh-agent instance. In practice, this means that the passphrase must be be entered only during the first login after a reboot. On subsequent logins, the unencrypted key from the existing ssh-agent instance is used. This can also be useful for allowing passwordless RSA/DSA authentication in cron jobs without passwordless ssh-keys.
To enable keychain, install it and add something like the following to ~/.bash_profile:
eval keychain --agents ssh --eval id_rsa
From a security point of view, ssh-ident and keychain are worse than ssh-agent instances limited to the lifetime of a particular session, but they offer a high level of convenience. To improve the security of keychain, some people add the --clear option to their ~/.bash_profile keychain invocation. By doing this passphrases must be re-entered on login as above, but cron jobs will still have access to the unencrypted keys after the user logs out. The keychain wiki page has more information and examples.
Got this info from;
https://unix.stackexchange.com/questions/90853/how-can-i-run-ssh-add-automatically-without-password-prompt
Hope this helps
I have personally been able to automatically enter my passphrase upon terminal launch by doing this: (you can, of course, modify the script and fit it to your needs)
edit the bashrc file to add this script;
Check if the SSH agent is awake
if [ -z "$SSH_AUTH_SOCK" ] ; then
exec ssh-agent bash -c "ssh-add ; $0"
echo "The SSH agent was awakened"
exit
fi
Above line will start the expect script upon terminal launch.
./ssh.exp
here's the content of this expect script
#!/usr/bin/expect
set timeout 20
set passphrase "test"
spawn "./keyadding.sh"
expect "Enter passphrase for /the/path/of/yourkey_id_rsa:"
send "$passphrase\r";
interact
Here's the content of my keyadding.sh script (you must put both scripts in your home folder, usually /home/user)
#!/bin/bash
ssh-add /the/path/of/yourkey_id_rsa
exit 0
I would HIGHLY suggest encrypting the password on the .exp script as well as renaming this .exp file to something like term_boot.exp or whatever else for security purposes. Don't forget to create the files directly from the terminal using nano or vim (ex: nano ~/.bashrc | nano term_boot.exp) and also a chmod +x script.sh to make it executable. A chmod +r term_boot.exp would be also useful but you'll have to add sudo before ./ssh.exp in your bashrc file. So you'll have to enter your sudo password each time you launch your terminal. For me, it's more convenient than the passphrase cause I remember my admin (sudo) password by the hearth.
Also, here's another way to do it I think;
https://www.cyberciti.biz/faq/noninteractive-shell-script-ssh-password-provider/
Will certainly change my method for this one when I'll have the time.
You can write the expect script as follow:
$ vi login.exp
#!/usr/bin/expect -f
spawn ssh username#machine.IP
expect "*assword: "
send -- "PASSWORD\r"
interact
And run it as:
$ expect login.exp

ruby script to enter prompt command from a system command

I'm trying to write a simple script to mysqldump some dbs. I'm getting stuck on the password prompt though.
I'd like to just have a config file that contains all the db creds, then the script can use those to connect to the db.
Problem is a command such as:
system('mysqldump -u username -p')
then prompts for
Enter password:
even when I do something like:
system('mysqldump -u username -p some_password')
I still get prompted for the password...
I don't do a whole lot of scripting in Ruby so I'm at a loss as to how my script can automatically enter this info so the user running the script doesn't have to.
If you already know the password why aren't you passing it to the command?
system('mysqldump -u username --password=mypassword')
you need to delete space after -p
system('mysqldump -uusername -psome_password')
or without password just
system('mysqldump -uusername')
or
system('mysqldump -uusername --password=')
you could always check the application that uses the database for the password, check the config file file for the connection string. Failing that change the password in the database.

Resources