The Internet was originally developed as a US research project, restricted to academics and the military. As it has become hugely popular and evolved into a critical resource for banking and electronic shopping, the original Internet communications protocols underwent severe strains. The three core "application-level" protocols before the world wide web were 1) telnet
(for using remote computers), 2) FTP (file transfer protocol, for moving files between computers), and 3) SMTP (for sending mail -- receiving mail has always used a variety of different protocols).
For the past several years SMTP has been undergoing forced evolution as ground zero in the war between spammers on one side; and ISPs, anti-spam developers, and users on the other. Similarly, the original telnet
and FTP protocols are no longer appropriate for today's hostile Internet, because they don't provide any protection against eavesdropping (called "packet sniffing"), particularly of identification credentials used to log into remote computers. Instead of undergoing the kind of metamorphosis SMTP has experienced to grow up into the often-malevolent Interent, telnet
has instead been largely replaced by SSH, which offers the same features but blends in security features. Similarly, FTP is being gradually phased out by sftp
, a secure FTP alternative included in the SSH suite.
Just as people demand SSL encryption (indicated by the lock icon in web browsers) from web sites to protect their credit card and banking details from identity fraudsters, SSH offers similar protection for logging into and moving files to and from remote computers, as well as flexible tunneling to protect other Internet communications.
http://www.isoc.org/internet/history/brief.shtml
Security is always a trade-off, usually giving up some convenience to have better security. Alternatively, you might trade money (pay) for more secure equipment, or spend more time to accomplish a task. It's a truism that the most secure computer is not only not connected to the Internet, but actually switched off. It's also mostly useless, although there are a few high-security applications which actually justify a computer which spend most of its time shut down or disconnected from the outside world.
When devising a security strategy, it's necessary to be secure enough, but also to recognize the point of diminishing returns. If the more secure way to do something takes twice as long, but reduces the chance of a successful attack by 10%, is it worth taking the more secure route? That depends on how long the action takes otherwise, how frequently it occurs, and the initial likelihood of compromise (before shaving away that 10% chance) -- it also depends on how bad a compromise would be. Missile codes and medical research demand stronger protection than everyday email. With encryption it's easy to go overboard, using too much encryption, too many keys/passwords, and too many hoops to jump through. Such problems are often "self-correcting" -- people faced with systems they consider unrealistically complicated tend to ignore them, reverting back to simpler (and less secure) systems, such as personal email accounts, telephones and faxes for communication, or posting passwords on monitors or under keyboards.
With SSH, keep in mind a) what you are protecting, b) who you are protecting it from, and c) how it's legitimately used. Infrequently accessed systems may use long and esoteric passwords, so long as you have confidence in remembering or retrieving the passwords when needed. Systems used on a weekly basis should be reasonably convenient. Daily access should be as quick and unobtrusive as you can safely manage, to avoid wasting time on security. Spend some time considering your requirements and planning how to satisfy them.
The Internet hosts a great many bad actors. The most numerous attacks are automated and indiscriminate; caused by viruses, worms, and trojan horses. They can be quite destructive, but are not personal. To date, such attacks are purely within the domain of the Internet, but as the Internet becomes more all-encompassing, it begins to encompass telephone calls (Skype, Vonage, 802.11-based voice calling), electronic faxing, electronic bank statements, etc. Calling a friend to exchange passwords, or even leaving one on voice-mail, is normally much safer than emailing it, but this line is gradually fading.
At the other extreme, the FBI uses "sneak and peek" warrants to investigate the homes and workplaces of suspects, which could easily include copying hard drives for later analysis. Similarly, several firms have recently lost laptop computers containing large amounts of customer financial data, which would provide a goldmine for identity thieves.
Once again, the key is to pick an appropriate balance point for security versus convenience. Lost or stolen computers are sufficiently common, and enough good encryption tools are available, that it's almost never a good idea to save an unencrypted password. Likewise, modern computers are sufficiently fast (especially compared to the speed of broadband Internet connectivity) that encryption rarely slows down data transfers or interactive responsiveness. For the subtleties, though, you must make your own determination.
Throughout this ebook, I explain the trade-offs, so you can decide whether they are acceptable. As a point of reference, I consider SSH Keychains indispensable, but I'm concerned enough that I put substantial effort into protecting them, including aggressively locking the screen and locking keychains (both automatically and manually), double-encrypting or destroying keys out of my physical possession (such as a laptop in an airport), and restricting my public keys as much as feasible.
OpenSSH is a modern toolkit which replaces several now-inadequate tools with a modern and secure suite. The SSH tools use public key encryption to protect against sniffing, impersonation of both humans and computers, and system break-ins -- whether by amateur vandals, professional criminals, or governments. OpenSSH is a popular and free implementation of the SSH protocols, including ssh
(the main program), sftp
(for interactive file transfers), scp
(for non-interactive file transfers), ssh-keygen
(for managing SSH keys), sshd
(the SSH server), and several additional supporting programs. OpenSSH is now standard on most UNIX-based systems, including Mac OS X and Linux.
SSH was originally developed by a Finn named Tatu Ylonen, in response to a password sniffing attack on systems he managed at Helsinki University of Technology (quite near where Linux was born). Ylonen published his SSH ("Secure Shell") software with source code and a non-restrictive license. The software became popular, and gradually changed into a commercial product as it developed. A group of people who wanted an open version started the OpenSSH project, keeping pace with advances in the commercial version, but retaining an open license. A variety of other SSH products are available, most based on one or the other of the two main projects (commercial products are typically based on the commercial ancestor, while free products tend to be derived from OpenSSH). As people used and evaluated SSH, they found serious flaws which inspired a new version (called SSH version 2, or SSH2) to address them. SSH1 remained popular for several years while SSH2 gradually grew in popularity (and availability).
There has been considerable friction over the years between SSH Communications Security (founded by Ylonen to develop and sell his original SSH software) and the OpenSSH project, but compatibility between the two is very good. The major limitation is that OpenSSH's scp
is based on the SSH1 specification of scp, which makes it compatible with commercial scp1
(even when OpenSSH is running in SSH2 mode) but not commercial scp2
. It's all very obscure, but the impact is that it may be necessary to use sftp
instead of scp
when communicating between commercial SSH and OpenSSH.
Over time, OpenSSH has become more popular; it's now included as part of Mac OS X, most Linux distributions, and Solaris; SSH Tectia (as commercial SSH is now called) has become correspondingly less common. On Windows, PuTTY and WinSCP (which also does sftp
) are both capable and popular. On Mac OS X, Interarchy offers a good GUI with sftp
support.
As a result of the Internet's fundamental 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, privacy is maintained by encrypting communications so unauthorized parties are unable to decipher them. There are currently three main tools which are used to provide encryption in multiple different roles: SSL/TLS, SSH, and VPN. SSL/TLS works by encrypting a single client-server connection, such as a web surfer communicating with a web server, indicated by the prefix "https" (for HyperText Transfer Protocol, Secure) in a URL. On the other hand, as described in "For Your Eyes Only: Virtual Private Networks", VPNs encrypt all traffic between a pair of VPN endpoints. In a corporate scenario this is typically all traffic, or at least all important traffic. SSH falls between these two extremes. It's often used to encrypt particular connections, roughly comparable to telnet
+ SSL/TLS or FTP + SSL/TLS, but SSH's tunneling capability enables it to function as a VPN alternative in many situations.
It's important to realize that no encryption system is perfect. Most modern encryption systems can be "broken" (decrypted by an unauthorized party) by applying sufficient computational power. Even the one-time pad, a so-called "perfect" encryption system, is useless if the attacker can discover the data used as the pad. In more mundane cases, encryption systems are vulnerable to the attacker somehow discovering the key (by finding the sticky note it's written on, subpoena, or discovering either party's key in some other way. The trick is to balance the difficulty of the system appropriately. An unbreakable system that took 5 years to encrypt a message and 5 more to decrypt would be useless. Similarly, a system that took a second to encrypt and decrypt with the password, but only 5 minutes for an attacker to decrypt -- perhaps by trying all of a small set of possible encryption keys -- would have little value.
A good encryption system must be quick and easy for authorized users with the key(s), yet very difficult and time-consuming to break for an attacker lacking the key. As computers get faster and researchers advance the state of the art in software, everything gets faster for both sides. As a result, encryption systems get more demanding over time, and more expensive systems gradually become practical.
In conventional symmetric encryption, information is protected (encrypted) with a "key" (a number, often derived from a password), which is used to obscure the information so it is not readable without the key. The recipient uses the same key to decrypt the received transmission, restoring the original data ("the plaintext"). The original Data Encryption Standard (DES), developed in 1975, used a symmetric 56-bit key. Due to computational advances, DES is no longer sufficient to stop a determined attacker, who could apply sufficient computing resources to defeat the encryption. In many cases, DES has been replaced by Triple DES, which repeats the DES algorithm to effectively provide 112-bit encryption. The current Advanced Encryption Standard (AES) uses 128, 192, or 256 bit keys.
Symmetric encryption is very effective, but begs the question: how can the sender and receiver agree on the key(s)? In conventional encryption, establishing the key must be done before encryption can provide privacy. Imagine if your address book contained an encryption key for each person you might want to communicate with privately. Further, imagine you had to generate this key, share it exclusively with the other party, keep it on file, and keep it secret from everybody else. It's not a practical scenario. Fortunately public key cryptography has been developed to provide a workable alternative.
http://www.ladlass.com/intel/archives/010256.html
Cryptographers addressed the key exchange problem with public key encryption. In public key cryptography systems such as RSA and DSA (Diffie-Hellman), a pair of linked keys is created. If key #1 is used to encrypt a message, key #2 is required to decrypt it (instead of the original encryption key, as in symmetric encryption); if key #2 is used to encrypt, then key #1 is used to decrypt. One key is kept secret (the "private key") and the other (the "public key") may be distributed without restriction.
[[Sidebar:]]Burt Kaliski has written a succinct explanation of how the RSA public-key algorithm works, but it's not simple. RSA is based on the fact that exponentiation is much easier (faster) than finding factors of large numbers, just as multiplication is easier than long division, but more extreme. Encryption with the private key is mostly exponentiation, while decryption is mostly root extraction (the reverse of exponentiation), and difficult if you know the key, but very difficult to guess at for someone who does not have the key. rsa, the other public-key algorithm used by SSH, uses discrete logarithms rather than exponentiation.
If I create such a keypair, three useful things can happen. First, I can make my public key freely available, since I don't have to worry who has it -- I can even transmit it as part of protocol establishment, before encryption has begun. Second, people can encrypt messages to me with my public key, knowing that others (even with my public key) cannot read them. And third, people can decrypt messages from me with my public key. Instead of privacy, decrypting a message with a public key provides authentication -- if my public key successfully decrypts a message, the encryptor must have had my private key.
public key cryptography underlies SSH, PGP, all VPN systems, and, SSL/TLS (used, in HTTPS, to secure web sites). Unfortunately, public key cryptography is substantially slower than conventional (symmetric) encryption. To accommodate this, public key cryptography is normally used for initial authentication (identification), and thenceforth to exchange randomly generated symmetric encryption keys. These symmetric keys never outlast a single communications session, so they are called "session keys".
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 (symmetrically). By encrypting the small symmetric key once with each recipient's public key, large messages can be efficiently sent to multiple recipients. This is also how "key escrow" works. Whenever a system with key escrow encrypts something, it always encrypts the symmetric key one extra time, using the escrow public key. This means the government or corporate administrator can use the escrow private key to access encrypted content, just like any other authorized recipient (or the owner, in a "private" system such as PGP Disk). 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 are short-lived, breaking them is both more difficult (due to less "cyphertext" to analyze) and less worthwhile than breaking encryption keys which are valid for a longer period. Most importantly, there is no need to generate, exchange, and securely retain encryption keys for every pair of correspondents.
A disadvantage to any cryptosystem is that it cannot guarantee that the a key is (only) in the possession of the intended parties. If I lose my symmetric passphrase and you get it, you can read all my messages. This is worse in public key systems, because they are so useful for authentication. There are several ways to handle this. One is to have a trusted party ("Certification Authority") vouch that the key belongs to the claimed party; this is common with web sites, and can be checked by clicking on the browser's lock icon, which shows the CA and who it claims possesses the certificate. PGP uses a web of trust, which requires PGP users to personally vouch for each other, and trust their "vouchees" to vouch for others down the line. It's awkward, but effective in the right circumstances.
Because SSH is normally used between a human (running the ssh
command) and a computer (running the sshd
server), client-to-server authentication (of a human by a computer) is much different than server-to-client authentication (of a computer by a human). Humans may be identified by encrypting/decrypting with their personal public keys, installed by the user or an administrator (in ~/.ssh/authorized_keys
) as part of account management. As a bonus, public keys help administrators avoid this all-too-common exchange:
Admin: I'm setting up a temporary password. Please change it to something I don't know, right away.
User: Sure, I will.
Admin: Now. Did you change it?
User: Uh, sure I did.
Admin: I mean it. Did you use thepasswd
command?
User: What command?password
?
Admin: No,passwd
. No "O" or "R". Do it now!
User: Um, okay. Drat. It rejected my password.
Admin: Please come up with a better one!
User: Stupid security policy! It doesn't like that one either!
Since users may connect to many computers without each computer having an individual "account" with the user, initial computer authentication is generally delegated to the Domain Name System (DNS). If I ssh
to emperor.tidbits.com
, I can generally trust the DNS to ensure that I'm connecting to a machine under the control of TidBITS (Adam Engst, according to the whois
database). The DNS is not as secure as SSH, but it's the best we can do in many cases. After the initial communication, each SSH client retains a digital "fingerprint" of each server it's communicated with, so it can authenticate the server for future connections. In this way, all communications after the first have a cryptographic guarantee that the server connected to is at least the same as before (assuming, of course, that the keys weren't stolen). Some people pre-populate the known_hosts
files with server keys, or check key fingerprints when connecting to new machines, but this is unusual.
In addition to privacy and authentication, encryption also provides tamper protection. If someone modifies the encrypted message (or it's accidentally distorted in transit), decryption will fail.
The OpenSSH suite directly replaces a whole host of standard Unix tools, including telnet
, rlogin
, rsh
, rcp
, and ftp
. In addition, OpenSSH can tunnel unencrypted TCP protocols (such as telnet
, IMAP, POP, SMTP, HTTP, etc.) inside SSH encryption, to protect otherwise insecure communications when SSL/TLS is not available and VPN is either not available or too much trouble.
The classic telnet
program is fairly simple -- it connects to another computer, running a telnet
server (normally called telnetd
, for "telnet
daemon"), and allows the telnet
user to log in by typing her username and password; the telnet
program then transfers characters back and forth, as if the user was using a physical terminal attached to the remote computer; this can be eavesdropped on by anyone controlling a the client or server, or any computer (router) in between). rlogin
, rsh
, and rexec
are similar, but add an option to login without authentication from trusted IP addresses. On today's Internet, unverified trust is no longer realistic. ssh
offers a superior alternative to them all, by encrypting all communications and offering public key authentication, instead of the simple IP-based trust used in the "r-programs".
In addition, scp
provides a cryptographic alternative to the old rcp
"remote copy" program, based on an encrypted ssh
connection, and sftp
offers a secure replacement for the old FTP protocol, which is both insecure and difficult to manage through modern firewalls. Like scp
, sftp
relies on an ssh
connection for transport and security.
Private keys are much more secure than passwords (which must be short enough for people to remember and easy to type), but fundamentally they're still large numbers which function as password equivalents. This means that anyone who has your private key can use it to authenticate as you to an SSH server. Files containing private keys (such as ~/.ssh/id_rsa
) are therefore as security sensitive as passwords.
On the server side, public keys identify users. If someone can manipulate your ~/.ssh/authorized_keys
file, they can insert their own key and impersonate you. To protect against this, sshd
ignores authorized_keys
files with insecure permissions. Unfortunately, sshd
doesn't complain about this in a visible way, so mysterious failures of public key authentication are often traced back to inadequate permissions. 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 any account except the owner. File system permissions cannot stop a system administrator from accessing the key files (both private and public, although the private keys should be encrypted), of course. Similarly, anyone with access to the machine or unencrypted backups could copy the key files.
To get started with public key authentication, first generate a new RSA key in Terminal with "ssh-keygen -t rsa
". Let ssh-keygen
create ~/.ssh/id_rsa
, and provide a good password you will remember, because 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_rsa
(your new private key, encrypted with the provided passphrase) and ~/.ssh/id_rsa.pub
(your new public key).
pepperbook:~ sample$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/Users/sample/.ssh/id_rsa): 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_rsa. Your public key has been saved in /Users/sample/.ssh/id_rsa.pub. The key fingerprint is: ba:d1:0c:43:93:a8:d5:5a:b8:a2:4b:29:ae:34:ee:3f sample@pepperbook.reppep.com pepperbook:~ sample$ ls -ld .ssh drwx------ 4 sample sample 136 Apr 6 00:22 .ssh pepperbook:~ sample$ ls -l .ssh total 16 -rw------- 1 sample sample 736 Apr 6 00:22 id_rsa -rw-r--r-- 1 sample sample 618 Apr 6 00:22 id_rsa.pub pepperbook:~ sample$
To use the new public key for logging into this account on this machine, copy id_rsa.pub
to authorized_keys
: "cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
". Test it with "ssh 127.0.0.1
". First, you will be asked to accept the public key for 127.0.0.1
(recall that keys are used to identify servers, as well as users); it's then 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 the passphrase might be the same same as the account password). Finally, you will get a UNIX shell dmg
pt on the "remote" system once the ssh
session is established. Log out to terminate the ssh
session.
Warning: Some Mac OS X versions suffer confusion between the current IPv4 Internet Protocol and the newer IPv6 protocol; IPv6 enables more computers to connect to the Internet but is not yet in wide use. To avoid these issues, use 127.0.0.1
in commands instead of localhost
. They should be equivalent, but are not (at least in early versions of Mac OS X 10.4 "Tiger", and I believe in "Panther" as well). Fortunately, Apple fixed this by 10.4.8, but it caused a lot of confusion before that, and still does for people using older versions.
pepperbook:~ sample$ cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys pepperbook:~ sample$ ssh 127.0.0.1 The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established. RSA key fingerprint is 8a:d3:22:82:f5:2b:88:f0:20:1b:72:bd:aa:30:e0:e2. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '127.0.0.1' (RSA) to the list of known hosts. Enter passphrase for key '/Users/sample/.ssh/id_rsa': Welcome to Darwin! pepperbook:~ sample$ ls -l .ssh total 32 -rw-r--r-- 1 sample sample 618 Apr 6 00:23 authorized_keys -rw------- 1 sample sample 736 Apr 6 00:22 id_rsa -rw-r--r-- 1 sample sample 618 Apr 6 00:22 id_rsa.pub -rw-r--r-- 1 sample sample 219 Apr 6 00:23 known_hosts pepperbook:~ sample$ exit logout Connection to 127.0.0.1 closed. pepperbook:~ sample$
Now that you've confirmed your public and private keys work, it's time to copy authorized_keys
to some other SSH servers. First, make sure there's a suitable ~/.ssh
directory, next send the file, and then login using the key to confirm it works.
pepperbook:~ sample$ 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: pepperbook:~ sample$ scp ~/.ssh/authorized_keys www:.ssh/ Password: authorized_keys 100% 618 0.6KB/s 00:00 pepperbook:~ sample$ ssh www Enter passphrase for key '/Users/sample/.ssh/id_rsa': Welcome to Darwin! www:~ sample$ exit logout Connection to www closed. pepperbook:~ sample$
Once that's tested, you're ready to copy authorized_keys
to more computers. You can also put the id_rsa
file on other machines, but be careful with this file! Don't put it on any machines you don't completely trust.
Remember that you can use multiple private and public keys. The id_rsa
and id_rsa.pub
filenames are just defaults -- keys don't need to have any special names, although agents tend to assume that the public key filename is the private key filename plus ".pub
", and may get confused otherwise.
So far you've replaced password authentication with public key authentication. This is valuable, because it means someone who controls an sshd
server which you log into will not get a chance to steal your password. The way SSH handles plain password authentication (against the built-in UNIX or Windows account databases) is by taking the password typed in and sending it through the ssh
connection; at the other end the username and password are decrypted and checked against the remote account's password on file. Both the local ssh
program you run and the remote sshd
program work with the unencrypted password. There have been major incidents in the past where a popular site (such as SourceForge.net) was broken into, and the crackers recorded all the usernames and passwords used to ssh
into SourceForge until people noticed something was wrong. The crackers then used those username/password pairs to log 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.
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 or eavesdrop on the owner. About the only time unencrypted private keys are appropriate is for automated tasks, run when nobody is available, if using an agent is not feasible. Such keys should be restricted as much as possible in authorized_keys, and the accounts they access should be restricted as much as possible as well.
Key agents make use of SSH much more efficient, at the cost of a small reduction in security. Agents read encrypted key files; the agent keeps the unencrypted key in memory (never in a file on disk), making it immediately accessible without further decryption or password entry. This makes use SSH dramatically more efficient. Without an agent, connecting to 5 systems 3 times each would require typing one's password correctly 15 times; with a loaded agent, all the connections are automatic. As an example, consider checking a file on several machines. An SSH agent 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 its socket (such as a root
user) can use it to authenticate, although the private keys themselves are not available directly from the agent. This makes agents (and agent forwarding) unsuitable for use on untrusted machines.
On the Mac, SSHKeychain is an excellent SSH agent. It can automatically load keys when needed, forgetting them when the system sleeps. SSHKeychain is accessible through the Dock or the SSHKeychain menu, and 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.
/Applications
)./Applications/SSHKeychain.app
.ssh
into systems without entering a password. If you check "Add passphrase to the Apple keychain", SSHKeychain will no longer prompt you for the key's passphrase, although it may prompt to unlock your keychain to retrieve the key's passphrase.The SSHKeychain menu shows either of two icons. 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.
There are a couple bugs in Mac OS X 10.4.x's authentication and the Apple Keychain. In theory, unlocking the screensaver should unlock the user's default keychain (if it uses the account's login password, which is Apple's default configuration), but this doesn't work properly. Additionally, while a keychain is unlocked, the system does not need to prompt the user to "unlock" that keychain again until it's re-locked, but this is also broken -- Mac OS X prompts to "unlock" keychains that are already unlocked.
In reality, if the system is running with the screensaver and Keychain locked, applications tend to bring up their own Keychain dialogs behind it. Unlocking the screensaver or the Keychain does not dismiss these dialogs. The upshot is that, with SSHKeychain set to lock the Apple Keychain on screen activation (its default behavior), unlocking the screensaver may reveal multiple Keychain dialog boxes which must each be addressed individually. With .Mac synching set to Auto, I often saw three authentication dialogs when I unlocked the screensaver.
As a partial workaround, open Keychain Access, create a new keychain (I called mine "lowsec"), 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 be 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 configuration, the lowsec keychain will be unlocked once at login time and then available until logout or reboot. For higher security I set my main login keychain to automatically lock after 30 minutes of inactivity. Ideally, both Keychain Access and SSHKeychain would allow locking specific keychains when the screen locks, leaving other keychains unlocked, but this is not currently implemented.
It can be very useful to provide restricted access to an account. In SSH, this is possible by adding restrictions to specific keys in authorized_keys
. Some of the possible restrictions include disabling interactive login; restricting agent, X11, or port forwarding (tunneling); and specifying a "forced command", which is always run when the associated key is used, regardless of what is requested by the ssh
client. These restrictions are particularly useful for non-interactive tasks such as backup scripts. Such tasks may require SSH connectivity with unencrypted private keys, which should not provide unrestricted ssh
access.
Note that multiple keys may provide access to the same account. This is handy for people sharing single accounts, or for using special-purpose keys with different forced commands. For more information on key restrictions and forced commands, see the "AUTHORIZED_KEYS FILE FORMAT
" section of the sshd
manual page.
Public keys can be further restricted by allowing access to carefully circumscribed accounts; unencrypted public keys which give access to "real" user or root
accounts should be avoided as much as possible.
There are several ways to protect a server against ssh
-based attacks, including firewalls, TCP Wrapper, not creating or distributing UNIX passwords (forcing ssh
public key authentication), and disabling password access for all accounts or the root
account. To read about using firewalls and TCP Wrapper with ssh, please vote for Take Control of SSH on the Take Control suggestions page.
UNIX passwords present several problems for administrators. What legitimate users can remember and type (generally considered to be 8 letters and numbers) is a small enough range of possibilities for attackers to try all possibilities. "Account lockout" is a feature of some systems (including Mac OS X Server) to disable accounts after several failed guesses -- which often identifies an attack. Unfortunately, this means legitimate users get blocked when their accounts are attacked, and locking legitimate users out of their own accounts is a successful attack (although not as serious as gaining illicit access). System administrators would often prefer to avoid this by not allowing password access at all. On Mac OS X, it is difficult to set up an account without a password; it's easier to create a long random password (12+ characters -- Keychain Access can do this for you), and never write it down or give it to the account user, requiring public key authentication or some other high security authentication (such as smart cards) instead. On other systems, it's easy to simply not set UNIX passwords for accounts (although there are complications).
OpenSSH has its own features to help force users to use public keys, blocking password guessing over the Internet. If you have enabled the root
account (which is technically accomplished by setting a password for it), you should definitely set "PermitRootLogin without-password
" in /etc/sshd_config
; this will prevent people from breaking into the root
account by guessing its password -- an amazingly common and disturbingly successful Internet attack. Even better, set "PasswordAuthentication no
" to prevent sshd
from accepting passwords for any account -- thus requiring keys for ssh
access.
OpenSSH has three main programs: ssh
, scp
, and sftp
. OpenSSH uses a directory named .ssh
in the user's home directory (~/.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, issues remote commands, creates tunnels, and provides encrypted communications for other programs to leverage, replacing telnet
, rsh
, rlogin
, and rexec
.
"ssh myserver
": log into myserver via SSH.
scp
scp
is SSH's 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_rsa.pub myserver:.ssh/authorized_keys
" copies my public key to myserver, and installs 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, or by appending to a file with ">>
".
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 the source to the destination host. This may break in unexpected ways, as the source 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, the workaround is to simply scp
the file from the source host to the local system, and then scp
it to the destination system with a separate command.
Note: OpenSSH's scp
implementation is incompatible with scp2
from ssh.com
. If you run into this problem, the workaround is easy: just use sftp
instead.
sftp
sftp
is the suite's interactive file transfer program, offering a replacement for the venerable ftp
. It is designed to emulate the ftp
command-line interface, using ssh
to provide secure client-server communication. Notably, sftp
does not use active or passive mode, instead running entirely through port 22. As a result, sftp
is much easier for network administrators to support. Additionally, the server does not provide ASCII mode transfers (line break transformations), although clients may. And of course, sftp
is much safer because it does not transmit passwords or data unencrypted. Unfortunately, there are a wide variety of attempts to make ftp
secure, all using similar names, and confusion as a result. In particular, sftp
is totally incompatible with ftp
, ftp
-in-ssh
(provided by some versions of Interarchy), FTP/SSL, and all "FTPS" programs.
OpenSSH's sftp
is very flexible. To begin an sftp
session, try "sftp myserver
". This will log into myserver, starting in the remote home directory. If you'd like to start in another directory, use a command such as "sftp myserver:/etc
", which instead starts in the /etc
directory on myserver. If you specify a relative path (without leading slash), such as "sftp myserver:.ssh
", it is relative to your home directory. This syntax is copied from scp
and rcp
.
Once logged into the remote host, standard ftp
-style commands are available, including help
, get
, put
, exit
/quit
, ls
/lls
, pwd
/lpwd
, and cd
/lcd
. On the other hand, many people prefer to use graphical
sftp
clients. Fortunately (and partially because sftp
deliberately mimics ftp
), a wide variety of clients is available. On the Mac, Interarchy is very good; on Windows, WinSCP is good. VersionTracker offers a wealth of alternatives.
On my own systems, I use the username pepper
(Apple calls this a "short name"). On some other systems, I have a different username. By default, SSH attempts to log into remote systems with the username used on the local system. There are a couple ways to handle discrepancies between local and remote usernames on an SSH command line. "ssh user@host
" logs into host as user, as does "ssh -l user host
". This syntax, like most options, also applies to both scp
and sftp
.
For frequently accessed servers, the username can be set permanently by creating the file ~/.ssh/config
and adding a couple lines to it. OpenSSH programs automatically use the username specified here if it exists. The example's asterisk is a wildcard, so it matches tidbits.com
, www.tidbits.com
, emperor.tidbits.com
, etc.
$ cat ~/.ssh/config Host *tidbits.com User reppep
When you are having trouble with an SSH program, it's helpful to see diagnostic information. Adding a -v
to most SSH
commands (including ssh
, scp
, and sftp
) shows a great deal more information about the command's progress. Most of it is unintelligible, but some bits are very useful. I tend to make two connections, one which succeeds and another that fails, so I can compare them.
For example, "ssh -v myserver
" logs into myserver with progress messages. -vv
and -vvv
provide even more verbosity. I often do something like the following:
-v
.-v
.BBEdit
will then highlight the differences between the successful and failing commands. If you don't have BBEdit, just paste into another text editor, or use two shell windows lined up alongside each other. To compare two files in Terminal, type "diff -u
", drag the two files into the Terminal window to enter their paths on the command line, and hit Return.
The SSH server (sshd
) can also run verbosely. The simplest way to accomplish this is to add "LogLevel VERBOSE
" to /etc/sshd_config
, and then restart sshd
(Remote Login) from System Preferences:Sharing:Services. When done testing, remove or comment out LogLevel
and restart sshd
again. Several other server logging levels are available; for details, see LogLevel
in the sshd_config
manual page.
known_hosts
OpenSSH uses the file ~/.ssh/known_hosts
to keep track of all the servers it has contacted (OpenSSH also uses /etc/ssh_known_hosts
, if it exists). Each sshd
server needs one or more pairs of private/public keys to identify it; these are called host keys, and they serve a similar role to user private/public key pairs. Because private keys are used as the basis for cryptographic identification, they must be protected with appropriate permissions. The known_hosts
files hold only public keys, so they don't need to be kept secret.
By default, OpenSSH warns whenever it encounters a host key that does not match an existing known host key. When contacting a new server for the first time, the message looks like this:
pepper@pepperbook:~$ ssh www.openssh.org The authenticity of host 'www.openssh.org (129.128.5.196)' can't be established. RSA key fingerprint is 20:ad:fa:70:cf:85:54:9d:ee:7f:6c:a3:98:77:94:4e. Are you sure you want to continue connecting (yes/no)? no Host key verification failed. pepper@pepperbook:~$
If you answer yes
, the key is added to known_hosts
, and that future connections will silently accept that key from that host. If ssh
ever receives a new key from a host, which doesn't match a key already on file, it displays a much more alarming warning:
pepperbook:~ sample$ ssh www @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ 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 53:66:e9:b5:92:e1:5f:d9:71:fa:87:7b:35:99:f2:d3. Please contact your system administrator. Add correct host key in /Users/sample/.ssh/known_hosts to get rid of this message. Offending key in /Users/sample/.ssh/known_hosts:2 RSA host key for www has changed and you have requested strict checking. Host key verification failed. pepperbook:~ sample$
There are two explanations for the mismatch. Most likely something was upgraded or reinstalled, and the SSH host keys were regenerated. If this is so, a quick check with the system administrator will confirm that it's safe to edit ~/.ssh/known_hosts
and remove the offending key, conveniently identified by line number -- "/Users/sample/.ssh/known_hosts:2
", above, means line 2 (with wrapping off).
The other possibility is the reason for the warning. It could appear if the ssh
server was subverted -- either replaced by another machine to record submitted passwords and other information, or modified for the same purpose. This is less common than upgrades, but quite possible (I've seen it once, and the people who ignored the warning felt pretty stupid afterwards. ssh-keygen
can display the fingerprint of a key file -- fingerprints are a quicker way to compare keys than comparing the full keys, which are several hundred characters each.
bbedit
BBEdit has good SSH support, starting with the sftp
client Bare Bones built into BBEdit (File:Open File from FTP/SFTP Server). 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.
One of the simplest ssh
tricks is remote command execution. Rather than logging into a computer, 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). I use something like "ssh www man shutdown | col -b | bbedit
".
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. dsh
is intended for use in Beowulf clusters -- groups of Linux machines all sharing computation workloads -- but it is also extremely useful for general system administration across multiple systems.
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 requires that computer to work even harder to (de-)compress the data. On the other hand, 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 cable or DSL service with low upstream bandwidth), using compression can reduce the amount of traffic going through the slow link, and make SSH faster. To use compression, add -C
(capital 'C') to the ssh
command line.
The X Window System, used for displaying graphics on UNIX/Linux systems (including Mac OS X, via Apple's optional X11 package), includes (unencrypted) network support, meaning passwords and other data can be intercepted. To address this, OpenSSH can automatically tunnel X11 sessions alongside ssh
login sessions. X11 defines 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, configure sshd_config
& sshd_config
, then go to System Preferences:Sharing:Services, turn off Remote Login if it was on, and turn it back on to restart sshd
with the new settings.
A common problem with X11 tunneling 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.
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 connecting directly from client
by a corporate firewall. If I can ssh
into another machine (call it 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 handle 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.
ssh
, scp
, and sftp
all work by communicating with sshd
, the SSH server. Normally, sshd
listens on TCP port 22, and all SSH communication goes through that port. It's fairly simple to run SSH on a nonstandard port, should that prove necessary (most likely to co-exist with another sshd
already using on port 22, or perhaps through an ssh
tunnel.
To move sshd
onto a different port, set the Port
directive in /etc/sshd_config
and restart sshd
. To access sshd
on a different port, use ssh -p port
, scp -P 2222
, or sftp -oPort=2222
, as needed.
A VPN (Virtual Private Network) works by passing most or all Internet traffic through an encrypted tunnel, to protect traffic in transit. OpenSSH offers several types of tunnels. "ssh -L
" securely connects a local port (on the client) to a remote port (accessible from the server). This is useful in a wide variety of scenarios, when a network connection doesn't inherently provide sufficient security, such as X11, POP, SMTP, VNC, etc.
Despite VPNs' greater simplicity and coverage, SSH tunnels offer one important advantage. With a VPN, everything between the endpoints (typically a laptop or home desktop, and the VPN gateway) is encrypted. This means that traffic from the VPN gateway to the actual server is typically unencrypted. Since sshd
typically runs on the server itself, unencrypted traffic between the VPN gateway and the server is avoided.
Note: UNIX systems (including Mac OS X) require root
-level access to listen for incoming connections on low ports (below 1024). As a result, some tunnels require administrative access (managed by sudo
in Mac OS X) to establish. Additionally, ssh
with sudo
is a bit odd, because sudo
uses the root
account to actually run the ssh
command. As a result, ssh
attempts to log into the remote root
account unless otherwise specified, and uses ~root/.ssh/known_hosts
instead of the regular user's known_hosts
.
pepperbook:~ sample$ ssh -L 1023:127.0.0.1:110 www Privileged ports can only be forwarded by root. pepperbook:~ sample$ ssh -L 1024:127.0.0.1:110 www Enter passphrase for key '/Users/sample/.ssh/id_rsa': Welcome to Darwin! www:~ sample$ logout Connection to www closed. pepperbook:~ sample$
Because the ssh
connection is carrying tunneled traffic, if a tunnel is still in use after exiting from the main remote shell, ssh
will remain connected to maintain the tunnel. Once the tunnel is no longer in use, ssh
exits and returns to the local shell. It's also possible to create a tunnel without establishing an interactive login session; in this case, the options "-aNTx
" may be appropriate; see the ssh
manual page for details.
If you SSH through an existing tunnel, ssh
may complain because the sshd
on the other side of the tunnel has a different host key than is found in ~/.ssh/known_hosts
. The short-term fix is to edit ~/.ssh/known_hosts
and remove the entry for 127.0.0.1
or localhost
, but a better option is to add NoHostAuthenticationForLocalhost yes
to /etc/ssh_config
, so the host key will always be ignored when connecting to 127.0.0.1
.
Note that Mac OS X has some confusion between IPv4 and IPv6. To avoid problems, use 127.0.0.1
with SSH, instead of localhost
, which should be equivalent, but is sometimes interpreted as an IPv6 address instead.
VNC servers normally listen on a TCP port in the 5900-5999 range. Apple Remote Desktop 2 is VNC-compatible, and listens on 5900 when enabled (make sure System Preferences:Sharing:Services:Apple Remote Desktop is checked). Assuming ARD2 is running on both the client and server, the client side of the tunnel must run on another port, since 5900 on the client is already in use by the local copy of ARD2. I use something like "ssh -C -L 5901:127.0.0.1:5900 www
" to open a new listener (fake server) on client port 5901. Everything sent to this port is encrypted and redirected to port 5900 on the ssh
server (www
). Once this is established, I use Add by Address, under the "+" button-menu in the main Remote Desktop window, and enter "127.0.0.1:5901
" in the Address field for the new computer entry. When using this entry, ARD2 will actually communicate with the server's ARD2 agent through the tunnel.
http://docs.info.apple.com/article.html?artnum=106439
Tunneling VNC (including ARD2) offers several advantages. First, it protects all VNC traffic across the network. The VNC protocol only encrypts the initial login, not the actual keyboard/display/mouse traffic. This means authenticating to programs through the server, including unlocking a screensaver, using sudo
, or authorizing programs such as Server Admin and Workgroup Manager, provides opportunity for crackers to steal passwords. Second, it is possible to not expose the raw VNC port to the Internet, using a custom firewall configuration or OSXvnc's option to listen only on the loopback interface (127.0.0.1
/localhost
). This means attackers scanning the Internet for VNC servers won't even see it, and further protects VNC access with SSH authentication.
Unfortunately, Remote Desktop doesn't offer complete functionality through an ssh
tunnel (although plain VNC through a tunnel is completely functional). Fortunately, ARD2's one-to-one remote control is TCP-based and tunnels well. On the other hand, its one-to-many features use UDP ports, and cannot currently be tunneled.
http://docs.info.apple.com/article.html?artnum=300838
screencapture
(VNC Alternative)Mac OS X includes screencapture
, a handy command-line utility for recording the contents of the screen. If you're connected via ssh
, and want to see what's going on in the graphical environment without running a full VNC session, it's fairly easy to take a screenshot and download it to your client. After logging into server ("ssh server
"), use something like "screencapture capture.png
" to take a screenshot on server. Then from the client, use something like "scp server:capture.png ~
" to download the screenshot to the local home directory, and perhaps "open ~/capture.png
" to view the file.
OpenSSH 4.3 introduces an experimental full VPN feature, which should offer comparable functionality to IPsec VPN (although it may never be as fast). This 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.
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. For example, I sometimes want to remotely control my father's PowerBook to help with a problem, but he has a private dynamic address, behind an AirPort Extreme base station 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 works around this by allowing him to "project" a tunnel to another computer. If I can reach that computer, the tunnel connects back to his computer. Because he establishes the reverse tunnel from his computer as a client, he doesn't have trouble with (Network Address Translation) NAT, and he doesn't even have to know his own IP address. For reverse tunneling to work, my father and I both need access to a computer running sshd
. In this example, my PowerBook is called pb
, his is called dad
, and the server is www.reppep.com
.
Note that reverse tunneling provides access to the tunneling computer, and so could be a violation of network security policies. The tunnel is restricted (only accessible from the gateway computer, or other systems with access to it), but it is important to check with the network administrators before implementing a reverse tunnel. In addition, reverse tunneling is fairly complicated. A simpler option is to make SSH directly accessible, but unfortunately this often cannot be arranged. See below for more on configuring dynamic DNS and firewalls for direct SSH access.
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
). There might be as many as 3 separate encryption/decryption cycles in this scenario, but performance is generally decent.
These instructions were originally written for Apple Remote Desktop 2, but apply equally to Remote Desktop 3. Generally, I strongly suggest connecting with Remote Desktop 3's "Encrypt all network data (more secure)" option, but in this case it doesn't do quite what is needed, and would only add a redundant extra layer of encryption.
dad
in this example), make sure Apple Remote Desktop is enabled in System Preferences:Sharing:Services.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. The sleep command ensures the tunnels will be accessible for at least an hour -- they stay open automatically while in use:
ssh -R 6900:127.0.0.1:5900 -R 6922:127.0.0.1:22 www.reppep.com sleep 3600
pb
in this example), set up tunnels to those ports on the server:
ssh -C -L 6900:127.0.0.1:6900 -L 6922:127.0.0.1:6922 -o HostKeyAlias=dad www.reppep.com
dad
with:
ssh -p 6922 www.reppep.com
127.0.0.1:6900
with Remote Desktop (or port 6900/display 1000 in a VNC client), and control dad
.Note that if the firewall in Mac OS X (non-Server) is on, and any services are enabled in System Preferences:Sharing:Services, the appropriate network ports are automatically opened in the firewall, accessible to the entire Internet; this is overly exposed. OpenSSH can be restricted with TCP Wrapper; the Apple Remote Desktop agent (which is a VNC server at its core) cannot; VineServer has an option to only listen on the loopback address, so external hosts cannot connect -- or even detect the presence of a VNC server -- without first establishing an ssh
tunnel.
To make this easier for my father, I made sure he uses the same login name on www.reppep.com
as on dad
, and I gave him a double-clickable file (ssh-tunnel.command) to run step #2 (the part he has to do each time I'm going to help him), in 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 TCP ports are accepting connections, use "netstat -an | grep LIST
". Step #2 creates tunnels on the server's ports 6900 & 6922 (connected back to dad
), and step #3 opens the same port numbers on the client (pb
), tunneled to the server.
When tunneling ssh
connections through ssh
, the ssh
program tends to show a "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
" alert, because ssh
gets confused about which ssh
server it's connecting to. The cause was addressed earlier, in the known_hosts
section. The short-term fix is to edit ~/.ssh/known_hosts
and remove the entry for 127.0.0.1
or localhost
, but a better solution is to add NoHostAuthenticationForLocalhost yes
to /etc/ssh_config
, so the host key will always be ignored when ssh
ing to tunnels on localhost
. If you do not want to edit either file, the warning can be avoided for a single connection by adding "-o HostKeyAlias=realhost
to the ssh
/sftp
/scp
command line, where realhost is the remote ssh
server, which is providing the host key for the tunneled ssh
connection. It's all somewhat obscure.
If you have a single computer, directly plugged into your cable or DSL modem with DHCP, without NAT or an intervening firewall, reverse tunneling may be unnecessary. If the Mac is directly accessible, but does not have a static IP address, dynamic DNS is a much simpler option. Dynamic DNS servers provide stable DNS hostnames for computers with variable IP addresses, using a DDNS software agent which notifies the DDNS servers of the new IP address each time the computer acquires a new address. The DDNS servers then change their records to reflect the new IP, so a certain domain name (such as stevejobs.dyndns.org
) always points to the computer's current address. This works very well for accessing home systems, including via SSH and AFP-over-TCP (AppleShare). DynDNS is one popular DDNS provider, offering both free and paid services.
Most home routers/firewalls, such as Apple's AirPort base stations and the popular Linksys WRT54G, are configured by default to allow connected computers full access to the Internet (including web browsing and email), but to block all "inbound" access to these computers from the rest of the Internet. In order to run Internet-accessible services (including sshd
) on a computer behind such a router/firewall, some configuration is required. Note that this is a simpler alternative to the reverse tunneling described above, and doesn't require manual establishment of the reverse tunnel before use. Unfortunately, there are two issues with direct SSH access through a router/firewall. First, it makes the sshd
server easier to find and attack from the Internet. Second, it requires control of the router/firewall and DHCP server (often the same device). On a managed network, such control is typically unavailable, and direct SSH access (or a reverse tunnel) might violate the security policy.
SSH normally runs on port 22, and if Remote Login is enabled in System Preferences:Sharing:Services, port 22 is automatically allowed through the Mac OS X (client) firewall. Most home access points (routers) use NAT to provide security; on these SSH must be enabled on the router as well. For example, in the Linksys WRT54G's administrative web interface, under Applications & Gaming is a Port Range Forward tab. On mine, Application ssh
, range 22 to 22, Protocol TCP, is forwarded to IP Address 10.10.10.21
, and Enabled. When I used an AirPort Express as my router, I mapped Public Port 22 to Private IP Address 10.10.10.21
and Private Port 22.
Note that the computer running sshd
must use the IP configured above; it cannot use a random DHCP address, or the port forward may not point anywhere. The easiest way to accomplish this is to set the Mac to Configure IPv4: Manually, but this causes trouble when traveling, because 10.10.10.21
may not be available or even valid on foreign networks. My solution was to configure static DHCP, so when the PowerBook is at home, it always gets the 10.10.10.21
IP. Unfortunately, this isn't available on any AirPort base stations, or in the WRT54G as shipped by Linksys; I had to load third-party firmware to gain static DHCP capability. Static DHCP is available in Mac OS X Server.
Another limitation of this NAT port forwarding is that typically port 22 can only be forwarded to one machine. The common workarounds are a) , or ssh
into the single forwarded computer, and then ssh
again to other private machines, or b) to run sshd
on a nonstandard port on all computers but one, so they don't conflict and all the SSH ports can be mapped through to the appropriate machines. In Mac OS X 10.4.x (Tiger), the sshd
port can be overridden in /System/Library/LaunchDaemons/ssh.plist
.
One of the most useful SSH tricks is actually a simple shell feature called aliasing. Aliases are abbreviations or shortcuts for commonly-used commands and actions, which avoid repetitive typing (and typos). 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 what shell customizations have previously been done. First decide what you'd like to alias, then figure out which file alias customizations should reside for your shell and configuration. Here are some examples for the bash
shell; they normally go in ~/.bashrc
, ~/.profile
, or ~/.bash_login
. For tcsh
, remove the equals sign in the alias command, and put the commands in ~/.login
, ~/.cshrc
, or ~/.tcshrc
instead. The first three examples are partial command lines -- type the alias and then the desired host (e.g., "stard www.reppep.com
"). The server name is embedded in the last five examples.
alias sv="ssh -v" alias sp="ssh -l pepper" alias stard="ssh -C -L 5901:127.0.0.1:5900" # Create compressed tunnel to ARD2 alias rj='time rsync -v --archive --delete --exclude=.DS_Store /juke/ othermac:/juke/' # rsync /juke to another machine via ssh alias sw="ssh www.tidbits.com" alias stw="sudo ssh -C -L 25:127.0.0.1:25 pepper@www.tidbits.com" # Create compressed tunnel to www.tidbits.com for SMTP alias stwh="ssh -C -L 1025:127.0.0.1:25 pepper@www.tidbits.com" # Create compressed tunnel to www.tidbits.com for SMTP alias sf="sftp pepper@www.tidbits.com"
With the SMTP tunnel established by stw
, 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. Alternatively, stwh
skips the sudo
, and requires the mail client to use port 1025 on 127.0.0.1 instead of port 25 (the default).
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 work 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. Do not use "ssh -C
"; rsync
can achieve better compression with its own --compress
/-z
option.
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 (non-Server) with the firewall active, enabling any service in System Preferences:Sharing:Services (including Remote Login), automatically opens the corresponding port(s) in the firewall to the entire Internet. This wide-open configuration may be too permissive. For tunneled services (such as VNC, which Apple calls Apple Remote Desktop), the port need not be open in the firewall at all, since the data flow is entirely through an SSH connection. It's not necessary to worry about this, but TCP Wrapper can substantially improve security for users with sshd
(Remote Login) enabled.
Tips for locking down Mac OS X services with TCP Wrapper and/or the firewall:
whois IP-address
should provide a useful hint (particularly the CIDR entry, if present).ssh
in and make changes from a disallowed address.There are several ways to implement IP-based access restrictions for SSH, but none of them are trivial:
ipfw
, the system firewall on Mac OS X Server systems. Unfortunately, Mac OS X Server costs considerably more than the non-Server version.ipfw
under Mac OS X (non-server)./Library/Preferences/com.apple.sharing.firewall.plist
, which can be modified to reconfigure ipfw
.sshd
with TCP Wrapper.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 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
's behavior with file redirection is odd, so a workaround is required to append text to a file using sudo
.
$ sudo sh -c 'echo "ALL: ALL" >> /etc/hosts.deny' Password: $ ssh 127.0.0.1 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 identifying cable and 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: 127.0.0.1" >> /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 127.0.0.1
) will be rejected.
When an ssh
connection is rejected due to Wrapper, an entry resembling the following is appended to /var/log/system.log
:
Jun 6 18:00:00 pepperbook /usr/sbin/sshd: refused connect from 211.218.145.153
OpenSSH uses several files to store configuration and authentication information. Generally speaking, for each type of file, there is a global configuration file shared by everybody, and an optional private version for each user. On other systems, the global files may be in different locations, such as /etc/ssh/
or /usr/local/etc/
. Several of these files are security sensitive (notably authorized_keys
), and will not be effective if permissions are incorrect. The most important files are listed below. For further details and additional files, see the manual pages for sshd_config
, ssh_config
, sshd
, and ssh
. Note that for security reasons, per-user configuration files generally do not allow globally configured restrictions to be relaxed, although security can be tightened.
Unfortunately, Mac OS X normally hides the /etc
directory, so changing the global OpenSSH configuration files isn't quite as easy as modifying normal documents. I normally use BBEdit to access these files, typically starting from a Terminal window, with "bbedit /etc/ssh_config /etc/sshd_config
". Another option is to edit the files with a character-mode text editor, such as "sudo nano /etc/ssh_config /etc/sshd_config
". To see the files in the Finder, use its Go:Go to Folder command, and type /etc
in the dialog box that comes up. Then just drag files onto your favorite text editor. Be sure to save as plain text when done, rather than RTF or Microsoft Word format.
Global File | Per-User File | Notes |
---|---|---|
/etc/sshd_config |
~/.ssh/authorized_keys |
Configures sshd , the SSH server. authorized_keys allows users to enable public key authentication, and to place restrictions on users logging in with public keys. |
/etc/ssh_config |
~/.ssh/config |
Configures ssh , scp , and sftp client behavior. |
/etc/ssh_host_rsa_key |
~/.ssh/id_rsa |
SSH v2.x RSA keys, private and public. Private keys are equivalent to passwords; they must be protected with filesystem permissions, and should be encrypted. Host private keys cannot be encrypted, because sshd must be able to start without user intervention (to enter a decryption passphrase). SSH v1.x keys are deprecated because the SSH v1.x protocol is flawed. |
/etc/ssh_host_rsa_key |
~/.ssh/id_rsa |
SSH v2.x RSA keys |
/etc/ssh_known_hosts |
~/.ssh/known_hosts |
List of public keys for hosts. |
/etc/hosts.allow |
-- | TCP Wrapper configuration files, which may be used to limit access to sshd by client IP. |
There are several additions to these files which can make using SSH easier and safer.
File | Suggested addition | Notes |
---|---|---|
/etc/sshd_config |
Protocol 2 X11Forwarding yes |
The SSH v1.x protocol is flawed, and should no longer be used; this forces SSH v2.x protocol only. X11Forwarding permits the client to request tunneling of X11 connections; by default it's disabled on Mac OS X. To confirm the validity of sshd_config , use sudo sshd -td . |
/etc/ssh_config |
Protocol 2 ForwardAgent yes ForwardX11 yes ForwardX11Trusted yes NoHostAuthenticationForLocalhost yes |
The SSH v1.x protocol is flawed, and should no longer be used; this forces SSH v2.x protocol only. ForwardAgent tells this client to set up agent forwarding when connecting to a remote machine via OpenSSH. ForwardX11 tells the client to request X11 tunneling, and ForwardX11Trusted enables compatibility with X11 applications which don't support X11 security (such as many of Red Hat's administrative tools). NoHostAuthenticationForLocalhost disables checking the host key for 127.0.0.1 (localhost ), which will otherwise tend to vary and cause problems when forwarding ports. |
~/.ssh/id_rsa ~/.ssh/id_rsa.pub ~/.ssh/id_rsa ~/.ssh/id_rsa.pub |
Create at least one key pair with ssh-keygen . Note that the private key(s) should only be on private trusted machines -- not multi-user systems, or those controlled by other people. |
It's fine to use multiple keypairs; just give them identifiable names. |
~/.ssh/authorized_keys |
Put trusted public keys here on every SSH server. As much as practical, restrict use of these keys. | This file may contain one or more public keys which provide SSH access to this account -- each optionally with restrictions on its use. |
/etc/hosts.allow /etc/hosts.deny |
Restrict access to the sshd server with TCP Wrapper if feasible. |
TCP Wrapper is the easiest way to limit which Internet hosts (IP addresses) may connect to sshd (the SSH server) on Mac OS X. |
~/.ssh/config |
Add per-user SSH client customizations, such as usernames for particular servers, here. | Many of the configuration options from ssh_config can be set here per-user; for one, multiple, or all SSH servers. |
You should now have a good sense of what you can do with SSH, both the basic stuff and the most useful advanced tricks. Hopefully you also have a sense of the security issues, so you can make informed trade-offs between convenience and capability versus security. Personally, I find SSHKeychain invaluable, and use forward and reverse tunneling so I work through firewalls, and help other people with their computers. I also use bbedit
and rsync
with SSH frequently. If you'd like to learn more about SSH internals and history, check out SSH, The Secure Shell: The Definitive Guide - 2nd edition, from O'Reilly.
I'm not going to explain the loopback address here. It's important, but way out of scope. I'm also not going to explain TCP/UDP ports. Needs a link to KvH's VPN article, and perhaps my ancient firewall article. I want to get an OpenSSH porter to review, but haven't contacted one of them yet. I'm also not explaining sudo
.
This page was last modified Friday, 14-Nov-2008 21:11:08 EST.