OpenSSH

Part I: What Is OpenSSH?

As anyone who has opened a mailbox full of spam knows, some successful Internet technologies show serious shortcomings in the current hostile Internet environment. SSH is a modern tool set intended to help protect from eavesdropping, impersonation, and system break-ins; by amateur vandals, professional criminals, governments, etc. OpenSSH is a popular and free implementation of the SSH suite, including ssh (the main multi-purpose program), sftp (for interactive file transfers), scp (for non-interactive file transfers), ssh-keygen (for creating and managing SSH keys), sshd (the SSH server), and various other tools. OpenSSH is now standard on most UNIX-based systems, including Mac OS X and Linux.

http://www.openssh.org/

Privacy

Due to the Internet's basic packet-switching architecture, data traveling between two computers normally flows through several others en route. The consequence of this is that there are many computers (mostly owned by ISPs) which "see" our Internet communications. To get a feel for this, you can use the traceroute command. "traceroute www.tidbits.com", for example, shows (at least part of) a path information can travel to www.tidbits.com, including systems belonging your own ISP and several other computers between you and TidBITS. Any of these computers can be configured to record the computers you communicate with, or even to make a copy of all your communications. If this concerns you, the options are either not to use the Internet (increasingly impractical) or to use encryption.

Since interception of communications is basically unavoidable on the Internet, privacy is gained by encrypting communications, so unauthorized parties are unable to decipher them. Aside from special-purpose encryption techniques, there are three types of encryption that are used in multiple different roles: SSL, SSH, and VPN. SSL works by encrypting an end-to-end connection, such as a web surfer to a web server. This is indicated by the prefix "https" in web URLs. VPNs are comprehensive; as described in "For Your Eyes Only: Virtual Private Networks" they encrypt all traffic from the protected computer(s) to the VPN server. SSH, however, is a bit more complicated [[...]]

In conventional single-key encryption, a data transmission is protected (encrypted) with a key (a number, often derived from a password), which is used to modify the data so it's not readable; the recipient can use the same key to easily decrypt the received transmission, restoring the original data (the "plaintext"). All encryption can be broken, but the key to making it useful is to ensure that decryption is much easier (faster) with the key than without it. If it takes you 2 seconds to encrypt an email message, and your recipient 2 seconds to decrypt it, and it would take the NSA 50 years to decipher the message, it's probably never going to be decrypted -- if it's a financial transaction, the account numbers (and parties!) might even be defunct by the time it's decrypted. This trade-off (time and effort with the key vs. without the key) is a critical factor in all encryption systems. As the state of the art in both hardware and software advances, the time to break a particular encryption decreases, but the feasibility of using stronger encryption tends to keep pace. For example, the Data Encryption Standard (DES) developed in 1975 used 56-bit keys. DES is no longer sufficient for normal use, and was superseded by Triple DES, which provides effectively 112-bit keys. The Advanced Encryption Standard (AES) is in turn the Triple DES successor, and uses 128, 192, or 256 bit keys.

http://en.wikipedia.org/wiki/Data_Encryption_Standard
http://en.wikipedia.org/wiki/Triple_DES
http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
http://www.bytereef.org/m4_project.html

Symmetric encryption is very effective, but raises a major question: how can the sender and receiver agree to the key(s) for communication? In conventional encryption, establishing the key must be done before encryption can provide any privacy.

http://www.ladlass.com/intel/archives/010256.html

Public Key Encryption

Cryptographers addressed the key-exchange problem with public key encryption, also called "asymmetric cryptography". In public-key cryptography systems such as DSA and RSA, a pair of linked keys is created. If key #1 is used to encrypt a message, it can only efficiently be decrypted with key #2 (instead of key #1, as in symmetric encryption); if key #2 is used to encrypt, then key #1 is used to decrypt. It's then possible to keep one key secret (the "private key") and distribute the other (the "public key").

http://en.wikipedia.org/wiki/Digital_Signature_Algorithm
http://en.wikipedia.org/wiki/RSA

If I create both keys and publish my public key, three useful things can happen. First, I can make the public key freely available, since it's not a problem if bad people get it. Second, people can safely encrypt messages to me with my public key (nobody else can decrypt them without my private key). And third, people can decrypt messages from me with my public key, in the process confirming that they were encrypted with my private key (me). In addition to privacy, this can also provide authentication -- if my private key successfully decrypts a message, the encryptor must have had my private key.

Public-key cryptography underlies SSH, SSL/TLS (mostly used for website encryption, as HTTPS, but also used to decrypt various other protocols, such as IMAP, POP3, SMTP, LDAP, etc.), PGP, and various VPN systems. Unfortunately, public-key cryptography is substantially slower than conventional cryptography. To accomodate this, public-key cryptography is normally used for initial authorization, and after that to transmit randomly-generated encryption keys for fast symmetric encryption systems. These symmetric keys never outlast a single communications session, so they are called "session keys".

[[This is what the lock in a web browser means. For instance, when I go to https://www.amazon.com/ and click on Safari's padlock, I see that RSA Data Security, Inc. confirms that the SSL certificate I'm using belongs to Amazon.com Inc. PGP uses a personal "web of trust" to tie PGP keys to identities. With SSH, the identity of the server is normally taken on faith, a]]

Aside from performance, there are other advantages to this layered encryption strategy. With email, for example, the message itself only needs to be encrypted once. With email, for example, by encrypting the (small) symmetric key multiple times with a public key for each recipient, each recipient get his or her own private copy of the single session key. Each recipient decrypts one block of ciphertext with his or her own private key; the rest of the ciphertext (containing the session key re-encrypted for the other recipients) is indecipherable and ignored. Because session keys never outlast a single session, breaking them is both more difficult and less worthwhile than breaking encryption keys which are used longer. Most importantly, there is no need to generate, exchange, and securely retain encryption keys for every pair correspondents.

Public Key Authentication (Theory)

A disadvantage to public-key cryptography is that it cannot guarantee that the possessor of a given key is actually the person or entity it claims to be. There are several ways to handle this. One is to have a trusted party ("Certification Authority") vouch that the key belongs to the claimed identity; this is common with web sites, and can be checked by clicking on the browser's lock icon, which shows the CA and who they claim owns the certificate.

Because SSH is normally used between a human (running the ssh command) and a computer, rather than between two humans (as with email), the authentication is asymmetric too. Computer identification is mostly delegated to the Domain Name System (DNS). If I ssh to emperor.tidbits.com, I can generally trust the DNS (at least so far -- as the DNS comes under attack by phishers, this may become less true) to assure that I'm connecting to a machine under the control of TidBITS (Adam Engst, according to the whois database). Humans may be identified by encrypting/decrypting with their public keys, installed by the user or an administrator
rw


http://en.wikipedia.org/wiki/Public-key_cryptography

http://db.tidbits.com/getbits.acgi?tbart=08209

What Does OpenSSH Do?

The OpenSSH suite directly replaces a whole host of standard Unix tools, including telnet, rlogin, rsh, rcp, and ftp. In addition, OpenSSH can be used to provided a point-to-point encrypted tunnel (effectively a partial VPN) for TCP connections. This is typically used to protect communications when SSL is not available, and VPN is either not available, or too much trouble.

[[clarify: interactive, file transfer, tunnel, possibly auth]]

The classic telnet program is fairly simple and very important -- it connects to another computer, running a telnet server (also called a "daemon"), and allows the telnet user to log in; the telnet program then transfers characters back and forth, as if the user was using a physical terminal attached to the remote computer. SSH goes this one better, by encrypting all the characters before transmitting them over the Internet. The rlogin and rsh programs are similar, but were typically used with a concept of trust. The destination computer has an idea of trusted users and computers, and allows them to connect without logging in.

Similarly, the scp program replaces the rcp remote copy tool with an encrypted version, based on an underlying ssh connection, and the sftp program replaces old-style FTP.

Additionally, SSH offers tunnels: encrypted connections between two machines, which can be used to convey various different types of traffic securely; tunnels are typically used to secure protocols which don't include sufficient built-in security, such as X11 and VNC. Tunnels are useful in many different scenarios.

In the current hostile Internet environment, it's not feasible to trust users or computers based on who or what they claim to be, so SSH adds public-key (also called Diffie-Hellman cryptographic credentials. In the super-abbreviated version, public-key cryptography works by generating two linked pieces of information, called keys, which are basically large numbers (1024 bits is typical, encompassing 2^1024 possibilities, more a google cubed). One of these numbers is kept secret (the "private key"), and the other is not (the "public key"). Information encrypted using the private key can be decrypted using the public key; information encrypted with the public key can only be decrypted by the private key.

There's a lot more to it, of course. In particular, public-key cryptography is much slower than conventional (single-key) cryptography, so public keys are typically used to exchange disposable "session" keys [[rep]] for single-key encryption. But that's enough to get by on for this discussion.


Part II: Public Key Authentication (Practice)

As described earlier, private keys are much more secure than passwords, but fundamentally they're large numbers which are used as password equivalents. This means that anyone who has your private key can use it to ssh as you. Files containing private keys (such as ~/.ssh/id_dsa) must be protected just like passwords. First, they are protected by UNIX permissions -- private keys must not be readable by anyone else. Second, it's important to consider backups, since anyone with access to the backup system can extract the key files from the backups.

On the other side of the fence, public keys identify your authorization to the ssh server. If someone could replace your ~/.ssh/authorized_keys file with their own, they could log in as you, using their own private key. To protect against this, the sshd server will ignore authorized_keys files which could be modified by other accounts. Unfortunately, it doesn't complain about this insecurity in a visible way, so it's a common problem with public-key authentication. The rule is that the ~./ssh/authorized_keys file and all the directories that contain it, up to the root of the filesystem, must not be writable by others (no group or world write permission).

Create a Private/Public Keypair

To get started with public key authentication, first generate a new DSA key with "ssh-keygen -t dsa". Let ssh-keygen create id_dsa, and provide a good password you will remember (keys cannot be recovered if you forget your password). ssh-keygen will create ~.ssh (if it doesn't already exist), as well as ~/.ssh/id_dsa (your new private key, encrypted with the provided passphrase) & ~/.ssh/id_dsa (your new public key).

$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/Users/sample/.ssh/id_dsa): 
Created directory '/Users/sample/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /Users/sample/.ssh/id_dsa.
Your public key has been saved in /Users/sample/.ssh/id_dsa.pub.
The key fingerprint is:
f6:3d:0e:f6:ab:d4:4f:6b:8b:45:5b:b6:30:18:ff:e4 sample@pepperbook.reppep.com
$ ls -la .ssh
total 16
drwx------    4 sample  sample  136 Mar 19 00:29 .
drwxr-xr-x   12 sample  sample  408 Mar 19 00:28 ..
-rw-------    1 sample  sample  736 Mar 19 00:29 id_dsa
-rw-r--r--    1 sample  sample  618 Mar 19 00:29 id_dsa.pub

To use the new public key for login to this account on this machine, just copy id_dsa.pub to authorized_keys: "cp ~/.ssh/id_dsa.pub ~/.ssh/authorized_keys". Test it with "ssh localhost". First, you will be asked to accept the public key for localhost (recall that keys are used to identify servers, as well as users); it's automatically copied into ~/.ssh/known_hosts. Second, you will be asked for the passphrase for your private key, instead of the account password for the remote system (note that they may both use the same passphrase). Third, you will get a shell prompt on the remote system (which is actually the local system in this example) once the ssh session is established.

$ cp ~/.ssh/id_dsa.pub ~/.ssh/authorized_keys
$ ssh localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
RSA key fingerprint is ba:3d:d0:7d:d9:c2:4d:21:7c:af:e9:69:23:c0:f2:6f.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
Enter passphrase for key '/Users/sample/.ssh/id_dsa': 
Welcome to Darwin!
$ ls .ssh
authorized_keys id_dsa          id_dsa.pub      known_hosts
$ exit
logout
Connection to localhost closed.
$ 

Now that you've confirmed your public and private keys work, it's time to copy authorized_keys to some other systems you log into. First, make sure there's a suitable ~/.ssh directory, then send the file, and then login using the key to confirm it works.

$ ssh www "mkdir -p .ssh ; chmod 700 .ssh"
The authenticity of host 'www (66.92.104.200)' can't be established.
RSA key fingerprint is 53:66:e9:b5:92:e1:5f:d9:71:fa:87:7b:35:99:f2:d3.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'www,66.92.104.200' (RSA) to the list of known hosts.
Password:
$ scp ~/.ssh/authorized_keys www:.ssh/
Password:
authorized_keys                               100%  618     0.6KB/s   00:00    
$ ssh www
Enter passphrase for key '/Users/sample/.ssh/id_dsa': 
Welcome to Darwin!
www:~ sample$ 

You're ready to distribute your authorized_keys file to other machines you use. You can also put the id_dsa file on other machines, but please be careful with this file! Don't put it on any machines you don't completely trust.

SSH Authentication Agents

So far you've replaced password authentication with public key authentication. This is valuable, because it means someone who controls a sshd server you log into doesn't get a chance to steal your password. The way SSH handles plain password authentication (against the built-in UNIX or Windows account system) is by taking the password typed in and sends it through the ssh connection; at the other end the username & password are decrypted and checked against the remote system's account database. Both the local ssh program you run and the remote sshd program you communicate with get the plaintext of your password (before encryption and after decryption, respectively). There have been major incidents in the past where a popular site (such as SourceForge.net) was broken into, and the crackers grabbed all the passwords used to ssh into SourceForge until people noticed something was wrong. The crackers grabbed a large number of username/password pairs that got them into other sites. It was a colossal mess.

Public keys avoid this risk, because the remote system only gets the public key. It doesn't need the private key, and cannot determine it from the public key. If you copy the private key to another system, then it is vulnerable to root-level users on the remote system, of course. To address this, OpenSSH offers Triple DES encryption for private key files.

Warning: It is possible to use unencrypted private keys, but this is generally a very bad idea, because anyone who gains access to the private key file (trivial, with physical access to the computer) then controls that identity, and can impersonate the owner.

Key agents make usage of SSH much more efficient, at the cost of a small reduction in security. Agents manage encrypted key files; the agent decrypts the key and stores the plaintext key in memory (never on disk), making it immediately accessible without further decryptions or password prompts. This makes use of many SSH connections convenient. Without an agent, connecting to 5 systems, 3 times each, would require typing one's password (correctly) 15 times; with an agent, all the connections are automatic without any password entries (aside from the initial one to load the key into the agent). As an example, consider checking a file accesible only to root, across several machines. An SSH agent can automatically provides the private key for each connection, making large-scale operations quick and convenient.

The risk in using an agent is that anyone who can control the agent or other forwarding socket (such as a root user with access to the agent's socket file) can impersonate the agent's owner. This makes agents more suitable for private workstations than public machines. Fortunately, agent forwarding can provide access to one's private agent and key, even when connecting through a less-trusted intermediate host.

SSHKeychain

On the Mac, SSHKeychain is an excellent SSH agent. It can automatically load keys when needed, forgetting them when the system sleeps or the screensaver activates. It's easily accessible through its Dock icon or its own menu. SSHKeychain integrates with Apple's Keychain, optionally automatically loading and unloading ssh keys as the Apple Keychain unlocks and locks, and it works with other SSH-supporting programs such as BBEdit.

Once you've created and tested your private/public keypair, there are several simple steps to activate SSHKeychain.

  1. Open SSHKeychain.dmg to mount it.
  2. Install SSHKeychain (I just dragged SSHKeychain.app into /Applications).
  3. Launch SSHKeychain.
  4. Configure SSHKeychain's preferences (accessible from the new SSHKeychain menu); the key is to enable Manage (and modifiy) global environment variables.
  5. Use Agent:Add All Keys from SSHKeychain's menu to confirm it can load your encrypted keys, and that now you can ssh into systems without your password. If you check Add passphrase to the Apple keychain, SSHKeychain will no longer prompt you for the passphrase.
  6. Set SSHKeychain to run automatically (I Control-clicked on its Dock icon and set Open at Login).
  7. Log out and back in; from now on, whenever you log into Mac OS X, programs will use SSHKeychain for key management.

The SSHKeychain menu has two modes. When it has one or more keys loaded, it shows a keyring with three keys. When it doesn't hold any keys, the ring is missing, but the keys are still shown.

As of this writing, there is a bug in Mac OS X 10.4.x "Tiger". In theory, unlocking the Apple Keychain should prevent further Keychain authentication dialogs while it remains unlocked, and unlocking the screensaver should unlock the Keychain. In reality, if the system is running with the Keychain locked, applications tend to bring up their own Keychain dialogs, hidden by the screensaver. Additionally, unlocking the screensaver should logically unlock the Keychain, just as logging in does (assuming the Keychain uses the account's login password, which is the default). In reality, unlocking one Keychain dialog or the screensaver doesn't dismiss any further Keychain dialogs which may be underneath it. The effect of these issues is that, with SSHKeychain set to lock the Apple Keychain on screensaver lock, which is its logical default behavior, unlocking the screensaver may reveal multiple Keychain dialog boxes. With .Mac synching set to Auto, I often see 3 authentication dialogs when I unlock the Keychain after being away for a while.

As a workaround, open Keychain Access, create a new keychain (I called mine "lowsec"), and select the new keychain, and use Edit:Change Settings for Keychain "lowsec" to disable locking entirely for this keychain. Then go back to your main (login) keychain, and move the ".Mac password" item (its name will your .Mac username) from the main login keychain into the new one. Additionally, enable Use custom security settings in SSHKeychain, and set On screensaver: to No action. With this configuraiton, the lowsec keychain will be unlocked once at login time and always available. For higher security, I set my main login keychain to automatically lock at sleep and after 60 minutes of inactivity. Ideally, both Keychain Access and SSHKeychain would allow locking certain keychains when the screen locks, leaving other keychains unlocked, but this is not yet supported.


Part III: Basic Usage

In everyday use, OpenSSH has three main programs: ssh, scp, and sftp. Aside from these three, OpenSSH includes a variety of other programs, but none see as much direct use.

sftp ports better than ftp

OpenSSH uses a directory named .ssh in the user's home directory (written as ~/.ssh) for personal SSH files. System files either reside in /etc/ (under Mac OS X) or /etc/ssh/ (on most other systems).

To enable logging into a Mac via SSH, open System Preferences, click on Sharing, and check the Remote Login item. This activates sshd (the ssh server, or "daemon").

ssh

ssh is the main (and most flexible) program in the OpenSSH suite. It establishes interactive connections to remote systems, creates tunnels, and provides encrypted communications for other programs to leverage, replacing telnet, rsh, rlogin, and rexec.

ssh reppep@myserver (equivalent to ssh -l reppep myserver): Log into myserver as user reppep.

scp

scp is the non-interactive file transfer program; it replaces rcp, which is itself modeled upon the basic cp (copy) command. In scp and rcp, a colon is used to separate the host and file path.

For example, "scp ~/.ssh/id_dsa.pub myserver:.ssh/authorized_keys" copies my public key to myserver, and install it as the authorized key. Once it's installed, I can login without using the UNIX password on myserver. This command replaces the existing authorized_keys file on myserver, replacing any public keys previously in the file. Adding keys to an existing file is better done with copy and paste.

scp also supports copying files from one remote host to another. In this case, the local scp command actually sends an scp command to the source host, telling it to copy from itself to the destination host. This may have impose unexpected requirements on the source host, as it checks the host key of the destination host, and the destination host checks the source host against its own IP restrictions (see TCP Wrapper, below). In case of trouble, simply scp the file from the source host to the local system, and then scp it to the destination system with a separate command. scp remote remote

sftp

sftp is the interactive file transfer program, offering a replacement for the venerable ftp.

"sftp myserver:/etc": Start an sftp session to myserver. If no directory is specified, it starts in the home directory. If a relative path (not starting with a slash) follows the colon, the path is relative to the home directory.

"sftp www:.ssh/authorized_keys keys": Copy authorized_keys from www into a file named keys in the current directory on the local system. Note that this only works to get files, not to put them onto remote machines -- use scp or interactive sftp to transfer files to a remote system.

There are a couple basic OpenSSH tricks you should know about.

Use a Different Account

On my own systems, I use the username pepper. On some other systems, I use a different username. By default, SSH attempts to log use the same username on the remote (server) system as on the client, but if usernames don't match between systems, this doesn't work. There are a couple ways to handle this on an SSH command line. ssh user@host logs into host as user. ssh -l user host is equivalent.

For frequently used systems, this can be fixed permanently by creating ~/.ssh/config and adding a couple lines to it. OpenSSH programs automatically use the specified username her if it exits. The asterisk is a wildcard, so it matches tidbits.com, www.tidbits.com, emperor.tidbits.com, etc.

$ cat ~/.ssh/config 
Host *tidbits.com
  User reppep

Get More Information

When having trouble with OpenSSH, it's often helpful to see diagnostic information. Adding a -v to the SSH command shows much more information about connection progress. Most of it's unintelligible, but some is quite useful. I particularly like to make two connections (perhaps one which fails and another to another machine, which succeeds), and compare the two (I paste them into BBEdit windows and use Search:Compare Two Front Documents) to highlight differences.

Part IV: Advanced Tricks

Speed up Connections

There are several factors which control the speed of SSH connections:

If either computer is slow or overloaded, compression will slow things down as it will require that computer to work even harder to (de-)compress the data for transfer. In this case, using a simpler encryption algorithm may speed things up significantly. By default, OpenSSH uses Triple DES to encrypt all the data transferred between client and server. Blowfish is a newer and faster (simpler) algorithm, which is believed to be secure, but doesn't have as much history to confirm this belief. If you are willing to take the chance on an attacker knowing about a secret weakness in the Blowfish encryption algorithm, you can use it to reduce CPU load compared to 3DES. To use Blowfish, add "-c blowfish" to the ssh command line.

If any part of the network connection between the two computers is slow (perhaps due to a long wireless link, or a low-speed ADSL circuit, or a high-latency cable modem), using compression can reduce the amount of traffic going through the slow link, and make SSH faster. Note that compression adds CPU load. To use compression, add -C (capital 'C') to the ssh command line.

Debug SSH

ssh -v myserver: Log into myserver, and show lots of progress messages along the way -- this is extremely useful for figuring out why a SSH command fails. The verbose output is highly technical, so when troubleshooting with "ssh -v", I generally do something like the following:

  1. In Terminal: Type Command-K (clear the window and scrollback buffer).
  2. In Terminal: Run a SSH command that works, as similar as possible to the one that fails, adding -v.
  3. In Terminal: Select All, then Copy
  4. In BBEdit: Paste
  5. In Terminal: Type Command-K (clear the window and scrollback buffer).
  6. In Terminal: Run the SSH command that fails, adding -v.
  7. In Terminal: Select All, then Copy
  8. In BBEdit: Paste
  9. In BBEdit: Select Search:Compare Two Front Documents

This technique is very useful for figuring out where an SSH tool is going astray (scp and sftp both support -v, as well as ssh itself). If you don't have BBEdit, just paste into another text editor. You can compare two files in Terminal by typing "diff -u", then dragging the two files into the Terminal window, and hitting Return.

Use BBEdit and bbedit

BBEdit has good SSH support, starting with the sftp client (File:Open File from FTP/SFTP Server...) which Bare Bones built into BBEdit. Alternatively, the included bbedit command-line tool can be used to edit files via sftp, or to receive files piped in from other programs, including ssh. BBEdit works well with SSHKeychain (described in Part II).

Remote Commands

One of the simplest ssh tricks is remote command execution. Rather than sshing into a computer, starting an interactive session, issuing a single command, and then logging out, it's also possible to include a command on the ssh command line. ssh will then execute this command on the remote machine, and return the results. For example, to see if the server www has rebooted recently, use "ssh www uptime". To see www's hostconfig file, use "ssh www cat /etc/hostconfig". To find out if www normally runs an AppleShare server, use "ssh www grep AFPSERVER /etc/hostconfig".

I'm fond of reviewing long files such as logs in BBEdit this way, to review remote files and manual pages (when I need to see the Linux or Solaris syntax, for example): "ssh www man shutdown | col -b | bbedit --clean". I use this technique instead of BBEdit's built-in SFTP support when I don't want to modify the file, just review it.

Remote commands work best with public keys, so entering a password doesn't bog the process down. Further, it becomes feasible to execute the same command across a set of remote machines. The dsh perl script streamlines this process. It's intended for use in Beowulf clusters -- groups of Linux of machines all sharing computation workloads -- but dsh is also extremely useful for general system administration across multiple systems.

Tunnel X11

The X Window System, used for graphical display on UNIX/Linux systems, is network-aware, but does not include encryption itself, so passwords and other keystrokes can be sniffed. OpenSSH can automatically tunnel X11 sessions alongside ssh login sessions. X11 uses the DISPLAY variable to identify the X11 display to use; if it is set before an ssh session is established, ssh can automatically create a virtual DISPLAY on the remote system, and connect it through an ssh tunnel to the local DISPLAY. This means X11 "just works" automatically over ssh, as long as "X11Forwarding yes" is set in sshd_config on the server, and "ForwardX11 yes" is set in ssh_config on the client ("ForwardX11Trusted yes" may also be required for use of certain X11 applications, such as Red Hat's administration tools).

To set this all up on a Mac, issue the following commands in Terminal, then go to System Preferences:Sharing:Services, turn off Remote Login (which is what Apple calls SSH) if it was previously on, and turn it back on to restart sshd with the new settings.

sudo sh -c 'echo ""                      >> /etc/sshd_config'
sudo sh -c 'echo "X11Forwarding yes"     >> /etc/sshd_config'
sudo sh -c 'echo ""                      >> /etc/sshd_config'
sudo sh -c 'echo "ForwardX11 yes"        >> /etc/ssh_config'
sudo sh -c 'echo "ForwardX11Trusted yes" >> /etc/ssh_config'

A common problem with ssh tunneling of X11 is explicitly setting the DISPLAY variable on the remote machine, which disconnects X11 from the ssh tunnel. People often set DISPLAY in their shell initialization files, and later forget it's there.

Authentication Agent Forwarding

It may not be possible to ssh directly into the desired computer. If it's necessary to go through an intermediate system before reaching the intended destination, it's very useful to still have access to encrypted keys on the original client for connecting to the eventual destination, even though the client with the keys cannot directly contact the final destination. ssh supports this with authentication agent forwarding.

For example, I might be at home, using a machine named client with SSHKeychain running, and need to reach destination at work, but prevented from connectiong directly from client by a corporate firewall. If I can ssh into another machine (gateway) from client, I can then ssh from gateway to destination. It may not be a good idea to keep my private keys or run an authentication agent on gateway, and password authentication is less secure (if it is even allowed on destination). By setting "ForwardAgent yes" in the ssh_config file on client (or using "ssh -a gateway", to enable forwarding for a single connection), I can instruct client to accept indirect authentication requests, passed back along the ssh chain from destination through gateway. For most people this will never be necessary, but when using public key authentication across partitioned networks, agent forwarding improves both security and convenience.

Tunnel (VPN Lite)

A VPN works by passing all or most Internet traffic through an encrypted tunnel, to protect otherwise-insecure traffic while it travels across the Internet. OpenSSH offers several types of tunnels. "ssh -L" securely connects a local port to a remote port. This works well for a variety of protocols which lack sufficient security themselves. For example: "ssh -c blowfish -C -L 5901:127.0.0.1:5900 www" opens a new listener (fake server) on the client's port 5901 (VNC display #1). Everything sent to this port is encrypted and redirected to port 5900 on the ssh server www (5900 is VNC port 0, used by Apple Remote Desktop 2.x). Once this is done, a normal VNC client can be configured to connect to 127.0.0.1, port 5901 (VNC display #1 on the client), but the client actually communicates with the server's VNC/ARD2 server. This offers several advantages. First, it encrypts the VNC traffic. Second, ssh is now a prerequisite for VNC access, providing stronger security. Third, direct VNC access can be blocked in the firewall, so crackers scanning the Internet for VNC servers won't find this VNC server.

Unfortunately, Remote Desktop has doesn't work as well with tunneling as plain VNC. First, ARD2 uses both TCP and UDP ports, so requires a VPN connection for complete functionality ("ssh -L" can only tunnel TCP ports, not UDP ports). ARD2's one-to-one remote control uses the VNC protocol, and can be tunneled, but one-to-many control and various other features use UDP and cannot. Second, Remote Desktop gets confused if only some ports are tunneled (such as via "ssh -L"); specifically, the main Remote Desktop status panel mis-identifies Remote Desktop systems available through a tunnel as running plain VNC (not Remote Desktop).

http://docs.info.apple.com/article.html?artnum=106439

To use Remote Desktop through a tunnel, first establish an ssh tunnel (ssh -c blowfish -C -L 5901:127.0.0.1:5900 server). Then in the main Remote Desktop window, use Add by Address (under the "+" button-menu) and enter "127.0.0.1:5901" in the Address field for the new computer entry.

http://docs.info.apple.com/article.html?artnum=300838

There is an advantage to SSH tunneling over regular VPNs, though. In a VPN, everything is encrypted between the endpoints, typically a laptop and the corporate VPN gateway device. This means that traffic from the VPN device to the actual server near it is not encrypted by the VPN. Since ssh connections are point-to-point (the gateway is on the machine to be accessed itself), they generally avoid unencrypted traffic for the last hop.

Note: UNIX systems (including Mac OS X) require root-level access to listen on ports 0-1023. As a result, some tunnels require sudo to create. Additionally, ssh with sudo is a bit odd, because the root account actually runs the ssh command; as a result, ssh will try to log into the remote root account unless otherwise specified, and ssh will use ~root/.ssh/known_hosts instead of the regular user's known_hosts.

$ ssh -L 1023:localhost:1025 www
Privileged ports can only be forwarded by root.
$ ssh -L 1024:localhost:1025 www
Last login: Wed Mar 22 23:50:17 2006 from pb.reppep.com
Welcome to Darwin!
pepper@www:~$ logout
Connection to www closed.
$ sudo ssh -L 1023:localhost:1025 pepper@www
Last login: Wed Mar 22 23:50:27 2006 from pb.reppep.com
Welcome to Darwin!
pepper@www:~$ exit
logout
Connection to www closed.
$ 

Because the ssh connection is carrying tunnelled traffic, if a tunnel is still in use after exiting from the main remote shell, ssh will remain connected to support the tunnel. Once the tunnel is no longer in use, ssh will exit and return to the local shell prompt.

Full VPN (not yet available on Mac OS X)

OpenSSH 4.3 introduces an experimental full VPN feature, which should offer comparable functionality to IPsec VPN (although it may never be quite as fast). It should be extremely useful when it becomes available on Mac OS X. As of the OpenSSH 4.3 release, however, full VPN is not supported on Mac OS X.

Reverse Tunnel (Meet in the Middle)

This is a somewhat strange but very powerful feature. One of the problems with modern-day networking is that most computers are protected behind firewalls and/or Network Address Translation (NAT), meaning it may not be possible to connect directly to the computer you want to reach, or even find it. For example, I sometimes want to remote control my father's PowerBook to help with a problem, but he has a private dynamic address, behind an AirPort Extreme which itself has another dynamic address and provides NAT. Even if my father told me his IP address and his base station's address, I wouldn't be able to reach his PowerBook. Reverse tunneling addresses this by allowing him to "project" a tunnel to another computer. If I can reach the computer he projects the tunnel to, I can use it to get back to his computer. Because he establishes the reverse tunnel from his computer as a client, he doesn't have trouble with NAT, and he doesn't even have to know his IP (or the base station's). For reverse tunneling to work, my father needs access to a computer running sshd (the SSH server), and I have to be able to reach it as well. In this example, my PowerBook is called pb, his is called dad, and the server is www.reppep.com.

To use Remote Desktop through a reverse tunnel and an intermediate system, there are several steps (this can be simplified if the client is directly on the Internet and accessible via ssh). The "-c blowfish" is not required, but will make the connections faster (there are can be 3 separate encryption/decryption cycles in this scenario, so things could bog down somewhat).

  1. On the computer to be controlled (dad in this case), make sure Apple Remote Desktop is enabled in System Preferences:Sharing:Services.
  2. On the computer to be controlled (dad), open a couple ports on the server and point them at the ssh and VNC servers on dad, by typing the following into a Terminal window: ssh -R 6900:127.0.0.1:5900 -R 6922:127.0.0.1:22 -c blowfish www.reppep.com
  3. On my client (pb in this case), set up tunnels to those ports on the server: ssh -c blowfish -C -L 6900:127.0.0.1:6900 -L 6922:127.0.0.1:6922 -o HostKeyAlias=dad www.reppep.com
  4. At this point, I can ssh -p 6922 -c blowfish www.reppep.com, and log into dad.
  5. At this point, I can connect to 127.0.0.1:6900 in Remote Desktop, and remote control dad.

Note that if you enable any service shown in System Preferences:Sharing:Services, the appropriate ports are automatically allowed through the firewall in Mac OS X (non-server), from the entire Internet. This is more permissive than ideal.

To make this easier for my father, I have ensured he uses the same login name on www.reppep.com as on dad. I will probably create a private/public key pair on his computer, install the public key for his account on www.reppep.com, and give him a double-clickable file (ssh-tunnel.command, perhaps copied to the right side of his Dock) to establish the ssh tunnel. Files ending with .command are automatically executed by Terminal when opened in Mac OS X.

To see what ports are accepting connections, use "netstat -an | grep LIST". Step #2 above adds 6900 & 6922 on the server (tunneled to dad), and step #3 above the same port numbers on the client (pb), tunneled to the server.

Normally, SSH keeps track of every machine it connects to (by DNS hostname and IP), and warns you if you ever connect to a different machine (or the sshd host key changes). Since ssh is connecting to localhost, but really communicating with dad's sshd, the host key would mismatch if I'd ever sshed to localhost before. The "-o HostKeyAlias=dad" bit avoids this problem by telling ssh (for this connection) that I'm really connecting to dad. Otherwise you might get an error, have to remove the troublesome entry for localhost from ~/.ssh/known_hosts, and then be able to connect.

Here's an example of the scary error (without HostKeyAlias). This happens whenever you connect to a machine whose host key has changed since you last connected to it, or if someone's attacking you by subverting DNS (statistically, much less common than host keys changing).

$ ssh -p 6922 localhost
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE 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 RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
eb:8c:1e:f4:d4:b5:34:27:40:77:9e:c0:d7:73:ce:a3.
Please contact your system administrator.
Add correct host key in /Users/pepper/.ssh/known_hosts to get rid of this message.
Offending key in /Users/pepper/.ssh/known_hosts:33
RSA host key for localhost has changed and you have requested strict checking.
Host key verification failed.

Create aliases for common actions

One of the most useful SSH tricks is actually a simple shell trick. Aliases for common actions can take some of the typing out of using SSH. The problem with aliases is that there are many different ways to configure them, depending on the shell, the login method, and which shell customizatoins have previously been done. First decide what you'd like to alias, then figure out which file alias customizations should go in for your shell and configuration. Here are some examples, for bash; they normally go in ~/.bashrc, ~/.profile, ~/.bash_login. For tcsh, remove the equals sign, and put the commands in ~/.login, ~/.cshrc, or ~/.tcshrc. Note that most of these examples work with any server -- type the hostname after the alias on the command line.

alias  sw="ssh www.tidbits.com"
alias  sv="ssh -v"
alias  sp="ssh -l pepper"
alias  sf="sftp pepper@www.tidbits.com"
alias stard="ssh -c blowfish -C -L 5901:127.0.0.1:5900"
# Create compressed tunnel to ARD2
alias  rj='time rsync -v --archive --delete --rsh="ssh -c blowfish" \
--exclude=.DS_Store --exclude=Podcasts /juke/ othermac:/juke/'
# rsync a directory to another machine via ssh
alias stw="sudo ssh -c blowfish -C -L 25:127.0.0.1:25 pepper@www.tidbits.com"
# Create compressed tunnel to www.tidbits.com for SMTP

With the SMTP tunnel established, a mail client can be configured to use 127.0.0.1 as its SMTP server, and the mail will flow through the ssh tunnel. This is useful when roaming with ISPs that block outbound port 25, although using port 587 for SMTP is generally preferable.

rsync

In addition to TCP tunneling, ssh can be used as a transport for other programs. For example, rsync can run over a ssh connection between two machines, to synchronize files or directories. This enables rsync to run securely without building encryption and authentication into the rsync program itself -- it simply leverages ssh. For more information, see the rsync manual page ("man rsync"), particularly the discussion of its --rsh/-e option, which can also be controlled with the RSYNC_RSH environment variable. For large backups, consider "ssh -c blowfish" for improved performance. Do not use "ssh -C"; rsync can achieve better compression with its own --compress/-z option.

Restrict Access to sshd (Firewall & TCP Wrapper)

Hunting for vulnerable SSH servers (sshd) is a popular pastime on the Internet. Many computer break-ins are accomplished by trying simple or random username/password combinations until a weak password is found. This type of attack can be blocked with a firewall that only allows ssh connections from trusted IP addresses, but there are complications .

In Mac OS X, enabling any service in System Preferences:Sharing:Services (including SSH, which Apple calls Remote Login), automatically opens the corresponding port(s) to the entire Internet in the system firewall (ipfw). This wide-open configuration is often too permissive. For tunnelled services (such as VNC, called Apple Remote Desktop), the port need not be open in the firewall at all, since the data flow is entirely through the SSH port (22). Reverse-tunneled SSH doesn't even require port 22 be opened in the initiator's firewall, because it is automatically allowed as a client-initiated connection. It's not necessary to worry about this, but fine-tuning can provide much better protection for users with SSH and/or Remote Desktop enabled.

  1. Most computers have dynamic IP addresses. Even a large block of possible addresses is a small fraction of the Internet's IPv4 address space, though.
  2. Computers on cable or DSL connections may have very large ranges of possible addresses, and ISPs do not normally publicize the address ranges assigned to their customers. Support representatives may not have this information available (or even know what it is), although whois IP-address should provide a useful hint (particularly the CIDR entry, if present).
  3. Mac OS X (except for the Server versions) does not provide any configuration for enabled services -- they're automatically wide open in the system firewall.
  4. Foresight is required. When travelling, or using a new IP address, the address must be allowed in advance, since it's not possible to ssh in and make changes from a disallowed address.
  5. It's important to be careful when changing access restrictions on remote machines, since mistakes which block access may not be fixable remotely. One trick for TCP Wrapper is to open one connection, make the change, and then test with a new connection. Even if TCP Wrapper accidentally blocks new connections, it won't affect the established session.

There are several ways to implement IP-based access restrictions for SSH, but none of them are trivial:

TCP Wrapper configuration changes automatically apply to all new connections, so there is no need to restart sshd. TCP Wrapper is relatively old code, and it is somewhat finicky. If a configuration file doesn't end with a line feed, Wrapper ignores the contents of the last line. Comments must start with a hashmark ("#") as the first character on the line. Network masks must be entered in the older /255.255.255.0 syntax, rather than the more modern /24 format. Full details and more options for hosts.allow and hosts.deny are in the manual page ("man -S5 hosts_access").

ftp://ftp.porcupine.org/pub/security/index.html#software

To configure TCP Wrapper, first block all access and confirm the change has worked. Unfortunately, sudo doesn't work in the obvious way with file redirection, so some indirection is required to append text to a file using sudo.

$ sudo sh -c 'echo "ALL: ALL" >> /etc/hosts.deny'
Password:
$ ssh localhost
ssh_exchange_identification: Connection closed by remote host

Next, decide what hosts to allow. Visiting http://www.whatismyip.com/ is a convenient way to find the public IP of a given computer. whois IP-address identifies netblocks, which is helpful for finding cable or DSL address ranges:

$ host emperor.tidbits.com
emperor.tidbits.com has address 216.168.61.78

Finally, configure /etc/hosts.allow to allow trusted hosts.

$ sudo sh -c 'echo "ALL: localhost" >> /etc/hosts.allow'
$ sudo sh -c 'echo "sshd: 216.168.61.78 24.193.0.0/255.255.0.0" >> /etc/hosts.allow'

The additions above allow emperor.tidbits.com and a block of over 65,000 RoadRunner IP addresses to ssh in; all other IPs (aside from localhost) will be rejected.


ssh-keygen
batch (crontab)
http://www.dyndns.com/
ipping.reppep.com
Ask an ssh porter to review.
ssh stays open 4 tunnels.
sshd: Protocol 2