If you are forced to use a Linux script to connect to a password-protected resource, you are likely to feel uncomfortable typing that password into the script. OpenSSL solves this problem for you.
Passwords and Scripts
It is not a good idea to write passwords in shell scripts. In fact, it’s a really bad idea. If the script falls into the wrong hands, anyone reading it can see the password. But when you are forced to use a script, what else can you do?
You can enter the password manually when the process reaches this point, but it will not work if the script is run unattended. Fortunately, there is an alternative to hard-coding the passwords into the script. Counterintuitively, it uses a different password to achieve this along with strong encryption.
In our example We need to remotely connect to a scenario Fedora Linux computer from our Ubuntu computer. We’re using a bash shell script to SSH connection to the Fedora Computer. The script needs to run unattended and we don’t want the remote account password to be included in the script. We can’t use SSH keys in this case because we’re pretending to have no control or admin Rights over the Fedora Computer.
We use the known OpenSSL toolkit to handle the encryption and a utility called
sshpass to enter the password in the SSH command.
How to create and install SSH keys from the Linux shell
Install OpenSSL and sshpass
Since many other encryption and security tools use OpenSSL, it may already be installed on your computer. However, if this is not the case, the installation will only take a moment.
On Ubuntu, enter this command:
sudo apt get openssl
sshpass, use this command:
sudo apt install sshpass
on Fedora, you have to enter:
sudo dnf install openssl
The command to install
sudo dnf install sshpass
On Manjaro Linux we can install OpenSSL with:
sudo pacman -Sy openssl
Install at last
sshpass, use this command:
sudo pacman -Sy sshpass
Encryption on the command line
Before we start using it
openssl Command with scripts, let’s get familiar with it by using it on the command line. Let’s say the password for the account is on the remote computer
rusty!herring.pitshaft. We will encrypt this password using
We need to provide an encryption password when we do this. The encryption password is used in the encryption and decryption processes. There are many parameters and options in the
openssl Command. We’ll look at each of them in a moment.
echo 'rusty!herring.pitshaft' | openssl enc -aes-256-cbc -md sha512 -a -pbkdf2 -iter 100000 -salt -pass pass:'pick.your.password'
echo to get the password of the remote account through a pipe and into the
openssl Parameters are:
- enc -aes-256-cbc: The coding type. We use the Advanced Encryption Standard 256-bit cipher with cipher block chaining.
- -md sha512: The message digest (hash) type. We use the SHA512 cryptographic algorithm.
- -a: That says
opensslto apply Base-64 encoding after the encryption phase and before the decryption phase.
- -pbkdf2: Using the password-based key derivation function 2 (PBKDF2) makes it much more difficult for a brute force attack to guess your password. PBKDF2 requires a lot of computation to do the encryption. An attacker would have to replicate all of these calculations.
- -Iter 100000: Specifies the number of calculations that PBKDF2 will use.
- -Salt: Using a randomly applied salt value makes the encrypted output different every time, even if the plaintext is the same.
- -pass pass: ‘choose.your.password’: The password we need to use to decrypt the encrypted remote password. substitute
pick.your.passwordwith a robust password of your choice.
The encrypted version of our
rusty!herring.pitshaft Password is written in the terminal window.
To decrypt this we need to pass this encrypted string to
openssl with the same parameters we used to encrypt, but adding
-d (decrypt) option.
echo U2FsdGVkX19iiiRNhEsG+wm/uKjtZJwnYOpjzPhyrDKYZH5lVZrpIgo1S0goZU46 | openssl enc -aes-256-cbc -md sha512 -a -d -pbkdf2 -iter 100000 -salt -pass pass:'pick.your.password'
The string is decrypted and our original text – the password for the remote user account – is written in the terminal window.
This proves that we can securely encrypt our password for the remote user account. We can also decrypt it when we need it using the password we provided during the encryption phase.
But does that actually improve our situation? If we need the encryption password to decrypt the remote account password, do we need to have the decryption password in the script after all? Well it does. However, the encrypted password of the remote user account is stored in a different, hidden file. The permissions on the file prevent anyone but you – and of course the system root user – from accessing it.
To send the output of the encryption command to a file, we can use redirection. The file is called “.secret_vault.txt”. We changed the encryption password to something more robust.
echo 'rusty!herring.pitshaft' | openssl enc -aes-256-cbc -md sha512 -a -pbkdf2 -iter 100000 -salt -pass pass:'secret#vault!password' > .secret_vault.txt
Nothing visible happens, but the password is encrypted and sent to the “.secret_vault.txt” file.
We can test if it worked by decrypting the password in the hidden file. Notice that we are using
cat not here
cat .secret_vault.txt | openssl enc -aes-256-cbc -md sha512 -a -d -pbkdf2 -iter 100000 -salt -pass pass:'secret#vault!password'
The password was successfully decrypted from the data in the file. We use
chmod to change the permissions on this file so that no one else can access it.
chmod 600 .secret_vault.txt
ls -l .secret_vault.txt
Using an authorization mask of 600 removes all access for anyone other than the file owner. We can now proceed to writing our script.
How to use the chmod command on Linux
Using OpenSSL in a Script
Our script is pretty simple:
#!/bin/bash # name of the remote account REMOTE_USER=geek # password for the remote account REMOTE_PASSWD=$(cat .secret_vault.txt | openssl enc -aes-256-cbc -md sha512 -a -d -pbkdf2 -iter 100000 -salt -pass pass:'secret#vault!password') # remote computer REMOTE_LINUX=fedora-34.local # connect to the remote computer and put a timestamp in a file called script.log sshpass -p $REMOTE_PASSWD ssh -T [email protected]$REMOTE_LINUX << _remote_commands echo $USER "-" $(date) >> /home/$REMOTE_USER/script.log _remote_commands
- We set a variable called
- We then set a variable called
REMOTE_PASSWDto the value of the decrypted password that was pulled from the “.secret_vault.txt” file with the same command as before.
- The location of the remote computer is stored in a variable called. saved
With this information we can use the
ssh Command to connect to the remote computer.
sshpassCommand is the first command in the connection line. We use it with the
-p(Password) option. This allows us to provide the password that will be sent to the. should be sent
- We take that
-T(Deactivate pseudo-terminal assignment) Option with
sshbecause we don’t need to be assigned a pseudo-TTY on the remote computer.
We’ll use a short here document to pass a command to the remote computer. Everything between the two
_remote_commands strings is sent as instructions to the user session on the remote computer – in this case, it is a single line of bash script.
The command sent to the remote computer simply logs the name of the user account and a timestamp in a file called “script.log”.
Copy the script, paste it into an editor, and save it in a file called go-remote.sh. Remember to change the details to reflect your own remote computer address, remote user account, and remote account password.
chmod to make the script executable.
chmod +x go-remote.sh
All that remains is to try it out. Let’s start our script.
Since our script is a minimalist template for an unattended script, there is no output to the terminal. But if we have the “script.log” file on the Fedora Computers we can see that remote connections have been made successfully and that the script.log file has been updated with timestamps.
Your password is private
Your remote account password will not be recorded in the script.
And even though the decryption password is included in the script, no one else can access your .secret_vault.txt file to decrypt it and get the remote account password.