Adding Complexity to the Example
The preceding example session provided a quick introduction to the most often-used client programs --ssh
and scp
-- in a format to follow while sitting at your computer. Now that you have the basics, let's continue the example but include situations and complications glossed over the first time. These include the "known hosts" security feature and the SSH escape character.
TIP: If you're following at the computer as you read, your SSH clients might behave unexpectedly or differently from ours. As you will see throughout the tutorial, SSH implementations are highly customizable, by both yourself and the system administrator, on either side of the secure connection. Although this chapter describes common behaviors of SSH programs based on their installation defaults, your system might be set up differently.If commands don't work as you expect, try adding the -v ("verbose") command-line option, for example:
$ ssh -v shell.isp.com
This causes the client to print lots of information about its progress, often revealing the source of the discrepancy.
Known Hosts
The first time an SSH client encounters a new remote machine, it does some extra work and prints a message like the following:$ ssh -l pat shell.isp.com Host key not found from the list of known hosts. Are you sure you want to continue connecting (yes/no)?
Assuming you respond
yes
(the most common response), the client continues:
Host 'shell.isp.com' added to the list of known hosts.
This message appears only the first time you contact a particular remote host. The message is a security feature related to SSH's concept of known hosts.Suppose an adversary wants to obtain your password. He knows you are using SSH, and so he can't monitor your connection by eavesdropping on the network. Instead, he subverts the naming service used by your local host so that the name of your intended remote host, shell.isp.com, translates falsely to the IP address of a computer run by him! He then installs an altered SSH server on the phony remote host and waits. When you log in via your trusty SSH client, the altered SSH server records your password for the adversary's later use (or misuse, more likely). The bogus server can then disconnect with a preplanned error message such as "System down for maintenance -- please try again after 4:00 p.m." Even worse, it can fool you completely by using your password to log into the real shell.isp.com and transparently pass information back and forth between you and the server, monitoring your entire session. This hostile strategy is called a man-in-the-middle attack. ["Man-in-the-Middle Attacks"] Unless you think to check the originating IP address of your session on the server, you might never notice the deception.The SSH known-host mechanism prevents such attacks. When an SSH client and server make a connection, each of them proves its identity to the other. Yes, not only does the server authenticate the client, as we saw earlier when the server checked pat's password, but the client also authenticates the server by public-key cryptography. ["Establishing the Secure Connection"] In short, each SSH server has a secret, unique ID, called a host key, to identify itself to clients. The first time you connect to a remote host, a public counterpart of the host key gets copied and stored in your local account (assuming you responded "yes" to the client's prompt about host keys, earlier). Each time you reconnect to that remote host, the SSH client checks the remote host's identity using this public key.Of course, it's better to have recorded the server's public host key before connecting to it the first time, since otherwise you are technically open to a man-in-the-middle attack that first time. Administrators can maintain system-wide known-hosts lists for given sets of hosts, but this doesn't do much good for connecting to random new hosts around the world. Until a reliable, widely deployed method of retrieving such keys securely exists (such as secure DNS, or X.509-based public-key infrastructure), this record-on-first-use mechanism is an acceptable compromise.If authentication of the server fails, various things may happen depending on the reason for failure and the SSH configuration. Typically a warning appears on the screen, ranging from a repeat of the known-hosts message:
Host key not found from the list of known hosts. Are you sure you want to continue connecting (yes/no)?
to more dire words:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that the host key has just been changed. Please contact your system administrator. Add correct host key in <path>/known_hosts to get rid of this message. Agent forwarding is disabled to avoid attacks by corrupted servers. X11 forwarding is disabled to avoid attacks by corrupted servers. Are you sure you want to continue connecting (yes/no)
If you answer
yes
, ssh
allows the connection, but disables various features as a security precaution and doesn't update your personal known-hosts database with the new key; you must do that yourself to make this message go away.As the text of the message says, if you see this warning, you aren't necessarily being hacked: for example, the remote host may have legitimately changed its host key for some reason. In some cases, even after reading this tutorial, you won't know the cause of these messages. Contact your system administrator if you need assistance, rather than take a chance and possibly compromise your password. We'll cover these issues further when we discuss personal known hosts databases and how to alter the behavior of SSH clients with respect to host keys. ["Host Keys and Known-Hosts Databases"]
The Escape Character
Let us return to the shell.isp.com example, just after you'd discovered the attachment in your remote email message and saved it to the remote file print-me. In our original example, you then logged out of shell.isp.com and ranscp
to transfer the file. But what if you don't want to log out? If you're using a workstation running a window system, you can open a new window and run scp
. But if you're using a lowly text terminal, or you're not familiar with the window system running on your friend's computer, there is an alternative. You can temporarily interrupt the SSH connection, transfer the file (and run any other local commands you desire), and then resume the connection.ssh
supports an escape character, a designated character that gets the attention of the SSH client. Normally, ssh
sends every character you type to the server, but the escape character is caught by the client, alerting it that special commands may follow. By default, the escape character is the tilde (~), but you can change it. To reduce the chances of sending the escape character unintentionally, that character must be the first character on the command line, i.e., following a newline (Control-J
) or return (Control-M
) character. If not, the client treats it literally, not as an escape character.After the escape character gets the client's attention, the next character entered determines the effect of the escape. For example, the escape character followed by a Control-Z
suspends ssh
like any other shell job, returning control to the local shell. Such a pair of characters is called an escape sequence. Table 2-1 summarizes the supported escape sequences. It's followed by a list that describes each sequence's meaning.
Table 2-1. ssh Escape Sequences
Sequence | Example with <ESC> = ~ | Meaning |
---|---|---|
<ESC> ^Z |
~ ^Z | Suspend the connection (^Z means Control-Z )
|
<ESC> . |
~ . | Terminate the connection |
<ESC> # |
~ # | List all forwarded connections [6] |
<ESC> & |
~ & | Send ssh into the background (when waiting for connections to terminate)
|
<ESC> r | ~ r | Request rekeying immediately (SSH2 only) |
<ESC><ESC> |
~ ~ | Send the escape character (by typing it twice) |
<ESC> ? |
~ ? | Print a help message |
<ESC> - |
~ - | Disable the escape character (SSH2 only) |
<ESC> V |
~ V | Print version information (SSH2 only) |
<ESC> s |
~ s | Print statistics about this session (SSH2 only) |
[6]For SSH2, this option is documented but not implemented as of Version 2.3.0.
- "Suspend the connection" puts
ssh
into the background, suspended, returning control of the terminal to the local shell. To return tossh
, use the appropriate job control command of your shell, typicallyfg
. While suspended,ssh
doesn't run, and if left suspended long enough, the connection may terminate since the client isn't responding to the server. Also, any forwarded connections are similarly blocked whilessh
is suspended. ["Termination"] - "Terminate the connection" ends the SSH session immediately. This is most useful if you have lost control of the session: for instance, if a shell command on the remote host has hung and become unkillable. Any X or TCP port forwardings are terminated immediately as well. ["Termination"]
- "List all forwarded connections" prints a list of each X forwarding or TCP port forwarding connection currently established. This lists only active instances of forwarding; if forwarding services are available but not currently in use, nothing is listed here.
- "Send ssh into the background," like the "suspend connection" command, reconnects your terminal to the shell that started
ssh
, but it doesn't suspend thessh
process. Instead,ssh
continues to run. This isn't ordinarily useful, since the backgroundedssh
process immediately encounters an error.[7] This escape sequence becomes useful if yourssh
session has active, forwarded connections when you log out. Normally in this situation, the client prints a message:[7]The error occurs as
ssh
attempts to read input from the now disconnected pseudo-terminal.
Waiting for forwarded connections to terminate... The following connections are open: X11 connection from shell.isp.com port 1996
as it waits for the forwarded connections to close before it exits. While the client is in this state, this escape sequence returns you to the local shell prompt. - "Request rekeying immediately" causes the SSH2 client and server to generate and use some new internal keys for encryption and integrity.
- "Send the escape character" tells the client to send a real tilde (or whatever the escape character is) to the SSH server as plaintext, not to interpret it as an escape. "Disable the escape character" prevents further escape sequences from having any effect. The rest of the escape sequences are self-explanatory.
ssh
escape character, use the -e command-line option. For example, type the following to make the percent sign (%) the escape character when connecting to shell.isp.com as user pat:
$ ssh -e "%" -l pat shell.isp.com