Standard Linux distributions come with OpenSSH (e.g. OpenSSH_4.3p2 ), a bash shell (e.g., GNU bash, version 3.2.25), and X11 server (e.g., X.Org version: 1.4.2 ). Linux users should set up their home directory to enable remote connection services. To set up for SSH, use the UNIX ssh key generation command. This will set up up your hidden SSH directory populated with your private/public key files. Watch for any output messages contining the hidden directory name. For example, the message:
Created directory '/home/train7/.ssh'gives the name of your SSH hidden directory. You will need to know this directory name to set up secure connections to remote hosts using SSH. It is normally the .ssh directory in your home directory.
The SSH agent and agent forwarding are important parts of OpenSSH, which lets you use your private/public key pair to increase productivity. It is possible that your Linux desktop is already setup with an SSH agent. To test your agent, type the command ssh-add -l. If you get a message like The agent has no identities, then you have an SSH agent running. See the tutorial Linux Desktop configuration using SSH agent for step by step instuctions to use your desktop agent.
If however, you get a message like Could not open a connection to your authentication agent, then you do not have an agent to connect to. This tutorial will address this situation and give step-by-step instructions to use bash aliases and SSH configuration files to create an environment for working on your local laptop with trusted connections to remote hosts.
This setup includes adding shortcuts (aliases) to your .bashrc file and putting files in your hidden SSH directory.
This step is only needed if you have never used SSH from this account. You may already have a hidden SSH directory. If you do not have the directory, or you do not know the name then continue with step one.
Start with a window open in your home directory.
[jdoe@centos ~]$ ssh-keygen -C "laptop Aug25" Generating public/private rsa key pair. Enter file in which to save the key (/home/jdoe/.ssh/id_rsa): Created directory '/home/jdoe/.ssh'. Enter passphrase (empty for no passphrase): -- new secret -- Enter same passphrase again: -- repeat secret -- Your identification has been saved in /home/jdoe/.ssh/id_rsa. Your public key has been saved in /home/jdoe/.ssh/id_rsa.pub. The key fingerprint is: 8f:ce:9a:19:fd:3e:05:ff:2e:90:1a:2e:37:d3:b4:63 laptop Aug25 [jdoe@centos ~]$
Some installations may require you to specify a key type or length. The options -b 2048 -t rsa are a good choice (for now).
Take note of your hidden SSH directory /home/jdoe/.ssh. It is normally the .ssh directory in your home directory.
These steps will add a new identity for use in your bash shell and give you an alias to use to start a secure bash shell. With slight modifications, these instructions could be used for csh/tcsh or ksh. You will create an identity (public/private key pair) just for Bash.
Start with a window open in your home directory.
[jdoe@centos ~]$ ssh-keygen -f .bash_identity Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): -- new secret -- Enter same passphrase again: -- repeat secret -- Your identification has been saved in .bash_identity. Your public key has been saved in .bash_identity.pub. The key fingerprint is: 41:ab:0b:c3:c7:6b:23:1f:5b:d0:31:78:11:d7:2e:cf jdoe@centos.css.udel.edu [jdoe@centos ~]$
Note: If you get command not found, then the OpenSSH tools are not in your path. Contact you system administrator.
alias sbash="env PSS_='laptop sbash' ssh-agent bash" if [ "$PSS_" ]; then idFile=~/.bash_identity ssh-add "$idFile" || exit; PS1="$PSS_\$ " && unset PSS_; fi
Start with a new window open in your home directory. If you are continuing from the last section, this will start a new shell using your modified .bashrc file. This means you will have the sbash alias available to you.
[jdoe@centos ~]$ sbash Enter passphrase for /home/jdoe/.bash_identity: Identity added: /home/jdoe/.bash_identity (/home/jdoe/.bash_identity) laptop sbash$
Host train User train7 Hostname centos2.udel.edu ForwardX11 yes ForwardX11Trusted yes ForwardAgent yes
The name after the Host key word is the SSH service name. You may name it anything you want, e.g., train for a training service and compute for a computing service.
laptop sbash$ ssh train
The authenticity of host 'centos2.udel.edu (127.0.0.1)' can't be established.
RSA key fingerprint is d2:f9:58:79:08:d6:18:22:3f:23:ac:4b:f4:a7:b9:3b.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'centos2.udel.edu' (RSA) to the list of known hosts.
train7@centos2.udel.edu's password: -- known secret --
Last login: Tue Aug 23 10:04:05 2011 from roaming-215-36.nss.udel.edu
[train7@centos2 ~]$
If this account does not have an SSH directory, continue at the bash prompt with the command ssh-keygen. This repeats the key generation step of the last section on the remote host. This time, accept the default comment but still put a passphrase on this identity.
[train7@centos2 ~]$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/train7/.ssh/id_rsa): Created directory '/home/train7/.ssh'. Enter passphrase (empty for no passphrase): -- new secret -- Enter same passphrase again: -- repeat secret -- Your identification has been saved in /home/train7/.ssh/id_rsa. Your public key has been saved in /home/train7/.ssh/id_rsa.pub. The key fingerprint is: d4:4d:09:b4:7f:1c:ea:50:d2:d8:5b:7e:ec:fe:10:01 train7@centos2.udel.edu [train7@centos2 ~]$
Assuming your SSH directory is .ssh, continue at the bash prompt with the two commands ssh-add -L >> .ssh/authorized_keys and exit. The first command should have no output, and the second will exit your remote shell and close the connection to the centos2.udel.edu host.
[train7@centos2 ~]$ ssh-add -L >> .ssh/authorized_keys [train7@centos2 ~]$ exit logout Connection to centos2.udel.edu closed.
laptop sbash$ exit exit [jdoe@centos ~]$
Type the
sbashcommand and you should get the sbash$ prompt after you enter your passphrase.
Note: If you do not supply the correct passphrase, you will not get the sbash$ prompt. Test this by typing CTRL-C at the passphrase prompt. You must type sbash again to continue with this test.
At the sbash prompt, use the command ssh -f train to fork na X11 application on the train service. For example, to display a green xclock type:
ssh -f train xclock -bg green
Log on to the compute service using the X11 terminal emulator with:
ssh -f compute xterm
Close all the X11 windows by clicking the X in the title bar (the red bullet on a Mac) and then stop your secure session with the command:
exit
Here is an example session testing xclock on your train service and xterm on your compute service.
[jdoe@centos ~]$ sbash Enter passphrase for /home/jdoe/.bash_identity: Identity added: /home/jdoe/.bash_identity (/home/jdoe/.bash_identity) laptop sbash$ ssh -f train xclock -bg green laptop sbash$ ssh -f compute xterm laptop sbash$ exit exit [jdoe@centos ~]$
Start a new window and type the sbash command to start a shell with the sbash$ prompt after you supply your bash identity passphrase. Here is a list of commands you can type at the sbash prompt:
laptop sbash$ ssh train Last login: Fri Sep 2 16:26:21 2011 from centos.css.udel.edu [train7@centos2 ~]$
The session on the remote host continues in the same window.
laptop sbash$ xterm -e ssh train & [2] 29879 laptop sbash$
The Last login: line and the prompt on the remote host will appear in a new window. The xterm will be running on your local machine with process id 29879. You may use any X11 terminal emulator which works on your local deskop. For example, use gnome-terminal -x in place of xterm -e.
laptop sbash$ ssh -f train xterm laptop sbash$
The Last login: line and the prompt on the remote host will appear in a new window. The xterm will be running on the remote machine. You may use any X11 terminal emulator that is installed on the remote host. For example, use gnome-terminal in place of xterm.
laptop sbash$ ssh -f train xterm -e screen -R laptop sbash$
If you do not have a detached screen session on the remote host, this will open a new window with just your remote host prompt. If you have a detached session, it will reattach the old session.
To copy and paste from one xterm to another xterm with a three-button mouse:
For example, to copy several words from one window and paste them to another, left-double-click on the first word, right-double-click on the last word, and then middle-click in the destination window.
Note: The right mouse may bring up a popup menu, in which case you will not be able to adjust the selection.
laptop sbash$ ssh compute 'ps -fu $USER' UID PID PPID C STIME TTY TIME CMD joedoe 29496 29494 0 08:55:42 pts/195 0:00 -bash joedoe 8199 8198 0 12:57:04 ? 0:00 xclock joedoe 9191 9190 0 13:17:03 ? 0:00 ps -fu joedoe
This will display all processes you have running on the compute service. Enclose the entire remote command in single quotes so shell characters, such as, $, *, ~ and | are interpreted on the remote host. In this case you want $USER to expanded to your username on the remote host. If you want a single quote contained in the remote command use the three characters '"'.
laptop sbash$ for h in train compute; do > echo $h && ssh $h uptime > done train 16:23:57 up 145 days, 5:11, 2 users, load average: 0.00, 0.00, 0.00 compute 4:34pm up 173 day(s), 1:35, 30 users, load average: 1.10, 1.12, 1.12 sbash$
This will echo the SSH services train and compute and then output from the uptime command on the host.
Loops and other flow-of-control bash features are best done in a script.
Write a bash script for more complicated tasks, which may involve executing commands on your remote hosts. To add the script to your path, copy it to a directory in your path and make it executable. Scripts that are started from an interactive shell will have all exported functions that are defined in the .bashrc file.
Install this script in your ~/bin/rmkey file and make it executable:
#!/bin/bash # # usage: rmkey [file] # file - private key file to be removed, along with the corresponding # public key file, and all the keys stored in the authorized key # files on the remote hosts explicitly contained in the config file. configFile="$HOME/.ssh/config" ## Get $idFile and $idFile.pub as the private/public key files. idFile=${1:-$HOME/.ssh/id_rsa} ## Do we need to remove the public key from the remote hosts? if [ -r "$idFile.pub" -a -r "$configFile" ]; then save_key='^$' ## Extract the public key (without options or comment) save_key=$(sed -n 's/.*\(ssh-[a-z]* [A-Za-z0-9+/]*=*\).*/\1/p' "$idFile.pub") ## For each host, edit the authorized keys file for host in $(awk '/^Host [^*?]*$/ {print $2}' "$configFile"); do printf "e .ssh/authorized_keys\ng#$save_key#d\nw\n" | ssh $host 'ed -s' done ## remove the files rm "$idFile" "$idFile.pub"
Note: The old key is extracted from the public key file using sed, a stream editor. Any public key options will run before the ssh- and the comment is after the optional key padding characters (=) .
Use Bash functions to enhance your enviroment. Bash functions are short scripts, which can be defined and exported in your .bashrc file. To add a function to extract hosts from your configuation file, add these lines to your .bashrc file
function config-hosts { awk '/^Host [^*?]*$/ {print $2}' ~/.ssh/config } export -f config-hosts
Note: This function will use awk to extract the service names from your configuration file. These are the second fields of lines beginning with "Host". This command will extract only services which are not patterns, which contain * or ? characters.
Now the last example could be done using the config-hosts function.sbash$ for h in $(config-hosts); do > echo $h && ssh $h uptime > done train 16:23:57 up 145 days, 5:11, 2 users, load average: 0.00, 0.00, 0.00 compute 4:34pm up 173 day(s), 1:35, 30 users, load average: 1.10, 1.12, 1.12 sbash$
Write a bash script for more complicated tasks, which may involve executing commands on your remote hosts. To add the script to your path, copy it to a directory in your path and make it executable. Scripts that are started from an interactive shell will have all exported functions that are defined in the .bashrc file.
Install this script in your ~/bin/bash-keygen file and make it executable.
#!/bin/bash # # Usage: bash-keygen # Generates new private/public key pair for use with the sbash alias # The old keys are removed, and the new key is added on # all hosts in the config file and ##### $idFile/$idFile.pub are the private/public key files. idFile=$HOME/.bash_identity idComment="${PSS-sbash} $(date +%b-%d)" ##### Extract the public key (without options or comment) old_key='_na_' if [ -r "$idFile.pub" ]; then old_key=$(sed 's/.*\(ssh-[^=]*\)=.*/\1/' "$idFile.pub") fi ##### Generate new keys (overwriting old) ssh-keygen -b 2048 -t rsa -f "$idFile" -C "$idComment" || exit 1 ##### For each host edit the authorized keys file for h in $(config-hosts); do ssh $h 'ed -s' <<end_edscript e .ssh/authorized_keys g#$old_key#d \$a $(cat "$idFile.pub") . w end_edscript done
Note: The old key is extracted from the public key file using sed, a stream editor. Any public key options will run before the ssh- and the comment is after the = key terminating character.
Note: The .ssh/authorized_keys file is modified on all remote hosts using ed, a scriptable command-line editor. The multiple-line ed script has the following commands:
Here is an example session which starts an sbash shell and checks the fingerprint of the old key before generating the new key. The authorized keys file is updated on all the hosts with no passwords since the old key is still handled by the agent.
[jdoe@centos ~]$ sbash Enter passphrase for /home/jdoe/.bash_identity: -- known secret -- Identity added: /home/jdoe/.bash_identity (/home/jdoe/.bash_identity) sbash$ ssh-add -l 2048 44:6e:d3:56:3d:4e:36:6b:a3:84:15:20:97:9d:57:22 /home/jdoe/.bash_identity (RSA) sbash$ bash-keygen Generating public/private rsa key pair. /home/jdoe/.bash_identity already exists. Overwrite (y/n)? y Enter passphrase (empty for no passphrase): -- new secret -- Enter same passphrase again: -- repeat secret -- Your identification has been saved in /home/jdoe/.bash_identity. Your public key has been saved in /home/jdoe/.bash_identity.pub. The key fingerprint is: 5e:c6:00:20:f2:fd:7e:03:a7:ce:f9:a4:8a:0e:9d:97 sbash Sep-16 sbash$ exit exit [jdoe@centos ~]$
All files and directories must not be writable by either group or others. This includes the directories containing the files. In addition, all private key files must not be readable by anybody but you. In this tutorial we use ssh-keygen to create the key files and the hidden SSH directory, if needed. If you do not get any error message from ssh-keygen, then all the permissions are correct, and you should not change them by explicitly using the chmod command.
There are two files in the SSH directory that need to be created without using SSH commands - the configuration file .ssh/config and the authorized keys file on the remote host .ssh/authorized_keys. These must not be writable by the group or others. We have assumed in this tutorial that your account is set up to not extend write access to anybody but yourself. We have used the default umask of 022, which masks out write access for both group and others.
If the permission mods are incorrect, you will get warnings or error messages, and things may not work properly. Sometimes, the problem is not obvious from the error message.
The ssh-keygen command may give an error such as
Saving key failed: ~/.bash_identityif it can not set things properly. This is usually caused by incorrect permission mods on the containing directory (home directory, in this case). To fix this type of error, type:
chmod u+w,go-w ~
You will get a warning and your private key is ignored.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0640 for '/Users/jdoe/.ssh/id_rsa' are too open. It is recommended that your private key files are NOT accessible by others. This private key will be ignored.You could fix this by fixing the premission mods on the file in question. To be safe, you should remove the key file and generate a new key with the ssh-keygen program. This may find more errors which you should fix. Once the new keys are generated, you will need to send the public keys to to all your remote hosts. again.
The configuration file and the configation file must not be writeable. In the following session the .ssh directory and the .ssh/config file are both group writable.
wifi-roaming-128-4-203-31:~ jdoe$ ssh train Bad owner or permissions on /Users/jdoe/.ssh/config wifi-roaming-128-4-203-31:~ jdoe$ chmod g-w .ssh/config wifi-roaming-128-4-203-31:~ jdoe$ ssh train ssh: Could not resolve hostname centos.css.udel.edu: nodename nor servname provided, or not known wifi-roaming-128-4-203-31:~ jdoe$ chmod g-w .ssh wifi-roaming-128-4-203-31:~ jdoe$ssh train Warning: No xauth data; using fake authentication data for X11 forwarding. Last login: Thu Sep 8 11:50:23 2011 from wifi-roaming-128-4-203-31.nss.udel.edu [train7@centos ~]$
After seeing the bad permissions on the configuration file, you should check to make sure nobody in your group changed your file, and before closing the directory you should make sure you don't see any new files, renamed files or removed files.
I .ssh/authorized_keys on the remote server does not have the correct permissions, it will not be used, and you will be ask for the account password. There is no error message.
If your home directory on the remote host is encrypted, then isshd service cannot read your authorized keys, and you will have to supply the account password. There is a solution, which involves the system administrator. The system administrator can configure the sshda service to look for authorized keys in a location outside of the user's home directory. See SSH/OpenSSH/Keys - Community Ubuntu Documentaion.
Step three in the above section "Configure SSH for a specific remote host connection" consists of connecting to the new host and executing three commands: ssh-keygen, ssh-add -L, and exit. The key generation command is not necessary if your home directory on the remote host is already configured for OpenSSH.
To transfer the public key file to the remote host with a .ssh directory, use a local cat command connected to a remote cat command.
[jdoe@centos ~]$ cat .bash_idenity.pub | ssh jdoe@compute.udel.edu "
> cat >> .ssh/authorized_keys"
jdoe@compute.udel.edu's password: -- known secret --
[jdoe@centos ~]$
Note: The host compute.udel.edu is assumed be running OpenSSH, and the jdoe home directory is set up to use .ssh as the SSH hidden directory.
Most Linux servers will be using OpenSSH, but there are other versions of SSH that use the same public/private key standards but store the public keys in a different format. To allow the use of the keys on different versions, the ssy-keygen -e command will export the public key in a standard transfer format.
The commercial SSH v2 server stores each public key in the standard transfer format, and the file names stored in the .ssh2/authorization file are used as the authorized keys. Thus, two file operations are needed to transfer a public key to a commercial SSH v2 server. Use a remote cat command and a remote echo command.
[jdoe@centos ~]$ ssh-keygen -e -f .bash_identity | ssh jdoe@commercial.udel.edu "
> cat >! .ssh2/centos.css.udel.edu_bash.pub;
> echo centos.css.udel.edu_bash.pub >> .ssh2/authorization"
jdoe@commercial.udel.edu's password: -- known secret --
[jdoe@centos ~]$
Note: The host commercial.udel.edu is assumed be running commercial SSH v2, and the jdoe home directory is set up to use .ssh2 as the hidden SSH directory.