Public / Private Key Management
If you need to generate an SSH key with a passphrase in order to connect to another FTP server, it can be a tricky thing to automate scripts that push and pull files to that server since each time you connect, it will ask for the passphrase.
I've seen some recommend to avoid passphrases when scripting or include the passphrase in the script. Either of these methods reduces the security by not having the key protected or by exposing the passphrase by having it on the file system.
My preferred solution is to use the passphrase but also not store it on the server anywhere so if the keys are ever compromised, the passphrases do not go with them.
An SSH agent is used to load the keys in memory and as long as the agent is loaded, the scripts will be able to work automatically in the background.
This still requires manually typing in the passphrase(s) but only after the server reboots.
Here is how it works:
ssh-add is used to load the various private keys you have into memory. This loads a program called "ssh-agent" in memory. In order for SSH programs to access these keys, two variables have to be set. SSH_AUTH_SOCK and SSH_AGENT_PID and they have to be pointed to the lock file and process ID respectfully.
Let's assume you have two passphrase-protected private keys stored here:
Code:
/root/.ssh/ssh2rsa-company1-private.rsa
/root/.ssh/ssh2rsa-company2-private.rsa
When you reboot your server, you will need to manually run a script like the following which will initially load the ssh-agent and the keys:
/var/scripts/prod/load-ssh-keys.sh
Code:
#!/bin/bash
#############################################
## Name : load-ssk-keys.sh
## Version : 1.0
## Date : 2017-02-16
## Author : LHammonds
## Compatibility : Ubuntu Server 16.04 LTS - 18.04.3 LTS
## Requirements : Run as root
## Purpose : Load SSH keys into memory which will
## allow FTP login without prompts.
## Run Frequency : As needed
## Exit Codes : None
################ CHANGE LOG #################
## DATE WHO WHAT WAS CHANGED
## ---------- ---- ----------------------------
## 2017-02-16 LTH Created script.
#############################################
## Requirement Check: Script must run as root user.
if [ "$(id -u)" != "0" ]; then
## FATAL ERROR DETECTED: Document problem and terminate script.
echo -e "\nERROR: Root user required to run this script.\n"
echo -e "Type 'sudo su' to temporarily become root user.\n"
exit
fi
clear
ssh-add -l >/dev/null
if [ "$?" == 2 ]; then
## Agent not loaded, load it up.
eval `ssh-agent -s`
fi
echo "Purging any existing keys from memory..."
ssh-add -D
echo "Enter the Company #1 SSH passphrase..."
ssh-add /root/.ssh/ssh2rsa-company1-private.rsa
echo "Enter the Company #2 SSH passphrase..."
ssh-add /root/.ssh/ssh2rsa-company1-private.rsa
echo "Listing all keys in memory..."
ssh-add -l
echo "Complete. Keys will remain in memory until the next reboot."
echo ""
read -p "Press [Enter] key to continue..."
If you logout or if a script runs in a different session (which will likely be the case), it will not be able to "see" the keys loaded in memory because the SSH_AUTH_SOCK and SSH_AGENT_PID variables will not be set in a new session.
To fix this, your scripts need to "find" the currently loaded SSH agent and set the variables correctly.
Example:
Code:
## Point the required variables to the loaded ssh-agent
export SSH_AUTH_SOCK=`find /tmp/ -type s -name agent.\* 2> /dev/null | grep '/tmp/ssh-.*/agent.*'`
export SSH_AGENT_PID=`ps aux | grep ssh-agent | grep -v "grep" | awk '{print $2}'`
if [ ${#SSH_AUTH_SOCK} -lt 1 ]; then
## Variable still empty. Houston, we have a problem.
echo "ERROR - ssh-agent not pre-loaded with authentication key." | tee -a ${LogFile}
echo "You must load the SSH keys before running this script."
exit 0
fi
Here is an example of a loaded ssh-agent:
Code:
root@srv-ftps:/# pgrep -u root ssh-agent
4421
root@srv-ftps:/# ls -l /tmp/ssh-jDCLupzf4420/
total 0
srw------- 1 root root 0 Apr 6 18:24 agent.4420
With the above information, the variables will need to be set as follows:
Code:
SSH_AGENT_PID=4421
SSH_AUTH_SOCK=/tmp/ssh-jDCLupzf4420/agent.4420
It might also be a good idea to remind anyone at the console that runs the reboot process to remind them that once the server comes back up, the keys must be loaded in memory.
Example:
/var/scripts/prod/reboot.sh
Code:
#!/bin/bash
#############################################
## Name : reboot.sh
## Version : 1.0
## Date : 2013-01-08
## Author : LHammonds
## Compatibility : Ubuntu Server 12.04.1 LTS - 18.04.3 LTS
## Requirements : Run as root
## Purpose : Stop services and reboot server.
## Run Frequency : As needed
## Exit Codes : None
################ CHANGE LOG #################
## DATE WHO WHAT WAS CHANGED
## ---------- ---- ----------------------------
## 2013-01-07 LTH Created script.
#############################################
## Requirement Check: Script must run as root user.
if [ "$(id -u)" != "0" ]; then
## FATAL ERROR DETECTED: Document problem and terminate script.
echo -e "\nERROR: Root user required to run this script.\n"
echo -e "Type 'sudo su' to temporarily become root user.\n"
exit
fi
clear
echo ""
echo "WARNING: Be sure to Load SSH Keys after reboot or scripts will fail"
echo ""
sleep 5
echo "Stopping FTP service..."
service vsftpd stop
echo "Rebooting..."
echo "3"
sleep 1
echo "2"
sleep 1
echo "1"
sleep 1
shutdown -r now
If you also want the variables set into the root profile, type the following (while as root):
Add the following:
Code:
## Point the required variables to the loaded ssh-agent
export SSH_AUTH_SOCK=`find /tmp/ -type s -name agent.\* 2> /dev/null | grep '/tmp/ssh-.*/agent.*'`
export SSH_AGENT_PID=`ps aux | grep ssh-agent | grep -v "grep" | awk '{print $2}'`
echo "Loaded SSH Keys..."
ssh-add -l
Now when you are in your low-rights account and need to sudo into the root account, type the following:
The "--login" is important so it executes the code in .profile. Once you are logged in as root, you should be able to list the keys loaded in memory with:
Bookmarks