As anyone who has opened a mailbox full of spam knows, some long-lived Internet tools are unsuited to today's hostile Internet. SSH is a modern toolkit, which replaces several no-longer-suitable tools with a modern and secure suite to help protect from eavesdropping, impersonation, and system break-ins -- whether by amateur vandals, professional criminals, or governments. OpenSSH is a popular and free implementation of SSH, 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 various support programs. OpenSSH is now standard on most UNIX-based systems, including Mac OS X and Linux.
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 may be the only traffic, or all the 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 relize 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 key 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. The recipient uses the same key to decrypt the received transmission, restoring the original data ("the plaintext"). The original the Data Encryption Standard (DES), developed in 1975, used a symmetric 56-bit key. Due to computational advances, DES is no longer highly secure, and has been largely replaced by Triple DES, which effectively provides 112-bit keys by repeating the original DES algorithm. The current Advanced Encryption Standard (AES) 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 begs the question: how can the sender and receiver agree on the key(s) for communication? 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 with the other party, keep it on file, and keep it secret from everybody else. It's not a practical scenario, so we're fortunate that public key encryption is available to address key distribution and management.
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 DSA and RSA, 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 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 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 is started. 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, in the process confirming that they were encrypted with my private key. In addition to privacy, this also provides authentication -- if my private key successfully decrypts a message, the encryptor must have had my private key (and thus must have been me).
Public-key cryptography underlies SSH, SSL/TLS, PGP, and various VPN systems. SSL/TLS (Secure Sockets Layer, later renamed to Transport Layer Security) is mostly used for website encryption, as HTTPS (and signified by a lock icon in web browsers), but is also used to provide encryption for other protocols, such as IMAP, POP3, SMTP, and LDAP. Unfortunately, public-key cryptography is substantially slower than conventional (symmetric) encryption. To accomodate this, public-key cryptography is normally used for authentication (identification), and after that 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. 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.
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. Initial computer identification is generally 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). After the initial communication, each SSH client keeps a digital "fingerprint" of the server, so it can authenticate it for future connections. In this way, all future communications have a cryptographic guarantee that the server SSH programs connect to is the same one as before (subject to the normal caveats about stealing keys to impersonate the server, of course). 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
The OpenSSH suite directly replaces a whole host of standard Unix tools, including telnet
, rlogin
, rsh
, rcp
, and ftp
. In addition, OpenSSH can provide point-to-point encryption for other TCP connections, used 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 (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. rlogin
, rsh
, and rexec
are similar, but (in addition to telnet
's username/password authentication) add the option to login without authentication from trusted IP addresses. On today's Internet, this is no longer appropriate. SSH trumps them all, by encrypting all communications and offering public keys authentication of identities, 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 tool, based on an underlying ssh
connection, and sftp
offers a secure replacement for old-style FTP, which was both insecure and extremely difficult to support through modern firewalls.
Unfortunately, it's simply no longer feasible to trust IP addresses, so SSH uses public-key cryptography to authenticate identities. 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 than 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 only be decrypted by the public key, and vice-versa.
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.
As described earlier, private keys are much more secure than passwords, but fundamentally they're really just large numbers which can be 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
) are as security sensitive as passwords. They must be protected by UNIX permissions -- private keys must not be readable by anyone else. Additionally, it's important to consider backups, since anyone with access to the backup system can restore the key files.
On the server side, public keys authenticate you to the SSH server. If someone can manipulate your ~/.ssh/authorized_keys
file, they can insert their own key, and you impersonate you. To protect against this, the sshd
server ignores authorized_keys
files are not protected from other accounts. Unfortunately, it 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 others (no group or world write permission).
Unfortunately, it is almost impossible to protect computers or files from administrators, or from anyone with physical access to the computer, so private keys should never be kept on computers that are not physically secure, or with untrusted administrators. Encrypting private keys can help, but cannot be a guarantee.
To get started with public key authentication, first generate a new DSA key in Terminal with "ssh-keygen -t dsa
". Let ssh-keygen
create ~/.ssh/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) and ~/.ssh/id_dsa.pub
(your new public key).
pepperbook:~ sample$ 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: 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_dsa -rw-r--r-- 1 sample sample 618 Apr 6 00:22 id_dsa.pub pepperbook:~ sample$
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 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 they may both use the same passphrase). Finally, you will get a UNIX shell prompt on the remote system (which is actually the local system in this example) once the ssh
session is established.
pepperbook:~ sample$ cp ~/.ssh/id_dsa.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_dsa': 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_dsa -rw-r--r-- 1 sample sample 618 Apr 6 00:22 id_dsa.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, then 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_dsa': Welcome to Darwin! www:~ sample$ exit logout Connection to www closed. pepperbook:~ sample$
You're ready to copy your authorized_keys
file to more computers. 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.
Remember that you can use multiple private and public keys per account. The id_dsa
and id_dsa.pub
defaults are just that -- keys don't need to have any special name, although agents tend to assume that the public key filename is the same as the private key filename, plus ".pub
" -- agents can get confused if the names don't correspond this way.
So far you've replaced password authentication with public key authentication. This is valuable, because it means someone who controls a sshd
server which 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 sending 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 use 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 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. 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. About the only time unencrypted private keys are appropriate is for automated tasks, run when nobody is available, if for some reason an agent is not suitable. 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 usage 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), making it immediately accessible without further decryption or password prompting. 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 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 unsuitable for public machines. Fortunately, agent forwarding can provide access to one's private agent and key, even when connecting through a less-trusted intermediate host.
On the Mac, SSHKeychain is an excellent SSH agent. It can automatically load keys when needed, forgetting them when the system sleeps. SSHKeychain is easily accessible through the Dock or the SSHKeychain 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.
ssh
into systems without entering a password. If you check Add passphrase to the Apple keychain, SSHKeychain will no longer prompt you for the passphrase.The SSHKeychain menu has 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.
As of this writing, there is a bug in Mac OS X 10.4.x "Tiger". In theory, unlocking the screensaver should unlock the Apple Keychain (assuming the Keychain uses the account's login password, which is the default). Unlocking the Keychain should avoid further Keychain authentication dialogs while it remains unlocked.
In reality, if the system is running with the Keychain locked, applications tend to bring up their own Keychain dialogs behind the screensaver. Unfortunately, unlocking the screensaver or the Keychain doesn't dismiss such dialogs. The upshot is that, with SSHKeychain set to lock the Apple Keychain on screen activation (its default behavior), unlocking the screensaver can reveal multiple Keychain dialog boxes, which must each be addressed individually. With .Mac synching set to Auto, I often saw 3 authentication dialogs when I unlocked the screensaver.
As a 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/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 yet 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 command 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 commmands, see the "AUTHORIZED_KEYS FILE FORMAT
" section in 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 accounts or root
accounts should be avoided as much as possible.
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.
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 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_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 break in unexpected ways, as the source host 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, while using a much simpler ssh
-based network design. Notably, sftp
does not use Active or Passive mode, instead running through a ssh
connection. As a result, sftp
is much easier for administrators to support. Additionally, the server does not implement ASCII mode transfers (line break transformations), although clients may provide this feature. 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 much 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.
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 variety of alternatives.
http://www.interarchy.com/
http://winscp.net/
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 all remote systems with the local username (pepper
). There are a couple ways to handle discrepancies on an SSH command line. "ssh user@host
" logs into host as user, and "ssh -l user host
" is equivalent. This syntax, like most options, also applies to both scp
and sftp
.
For frequently accessed servers, this can be set permanently by creating ~/.ssh/config
and adding a couple lines to it. OpenSSH programs automatically use the username specified here 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
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's 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, use "diff -u
", drag the two files into the Terminal
window to enter their paths on the command line, and hit Return.
known_hosts
OpenSSH uses ~/.ssh/known_hosts
and ~/.ssh/known_hosts2
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 these keys are used as the basis for crytographic identification, they're critical to security of the whole SSH system. The known_hosts
files hold only private 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 will be 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 this warning. 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 the ~/.ssh/known_hosts
file and remove the offending key, convenienlty identified by line number -- "/Users/sample/.ssh/known_hosts:2
", above, means line 2 (with wrapping off -- SSH keys are long enough to wrap several times each).
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.
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 a high-latency cable modem), 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.
bbedit
BBEdit has good SSH support, starting with its built-in 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).
One of the simplest ssh
tricks is remote command execution. Rather than ssh
ing 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. dsh
is 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.
The X Window System, used for displaying graphics on UNIX/Linux systems (including Mac OS X, via Apple's optional X11 package), 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, add the X11 directives to sshd_config, 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.
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 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.
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. This is common with X11, POP, SMTP, VNC, etc.
Despite being less complete, SSH tunnels offer an important advantage over regular VPNs. With 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, they normally avoid exposing unprotected traffic over any network connection, such as between the VPN server and target host.
Note: UNIX systems (including Mac OS X) require root
-level access to listen for incoming connections on ports 0-1023. As a result, some tunnels require sudo
to create. 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 ssh
will use ~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_dsa': Welcome to Darwin! www:~ sample$ logout Connection to www closed. pepperbook:~ sample$
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. 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
/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, 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.
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 the screensaver, using sudo
, or authorizing programs such as Server Admin and Workgroup Manager, provide opportunities for crackers to record 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 (127.0.0.1
/localhost
) interface. This means attackers scanning the Internet for VNC servers won't even see it, and further protects VNC access with SSH authentication.
http://www.cl.cam.ac.uk/Research/DTG/attarchive/vnc/sshvnc.html
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 fully functional. On the other hand, ARD2's one-to-many features use UDP ports, and cannot currently be tunneled by OpenSSH. Additionally, ARD's other functions (reporting, remote commands, etc.) do not use port 5900/tcp.
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 possible to take a screenshot and download it onto your client fairly easily. 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 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.
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
). There are can be 3 separate encryption/decryption cycles in this scenario, so things could bog down somewhat.
dad
in this case), 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 tunnel will be accessible for at least an hour -- it will stay open automatically when 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 case), 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
in Remote Desktop (or port 6900/display #1000 in a VNC client), and 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. OpenSSH can be restricted with TCP Wrapper; ARD2 cannot.
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 127.0.0.1
, but really communicating with dad
's sshd, the host key would mismatch if I'd ever ssh
ed 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.
The "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
" alert is shown above, in the known_hosts
section. To disable this behavior for 127.0.0.1
(localhost
), add these lines to ~/.ssh/config
:
Host 127.0.0.1 localhost StrictHostKeyChecking no
With "StrictHostKeyChecking no
", when OpenSSH receives a mismatched host key, it will allow the connection, but disable various unsafe features.
If you have a single computer, directly plugged into your cable or DSL modem (or an Ethernet LAN with DHCP), without NAT or any 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 without stable IP addresses, using a DDNS software agent which notifies the DDNS servers of the new IP address, each time the computer moves to a new IP address. The DDNS servers then change their records to reflect the new IP. This works very well for reaching personal systems, including via SSH or AppleShare-over-IP (AFP). DynDNS is a popular system, offering both free and paid options.
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 -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 stw="sudo ssh -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. 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, 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.
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. 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 manipulated to load a different configuration into 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 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 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 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: 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 will be appended to /var/log/system.log
:
Jun 6 18:00:00 pepperbook /usr/sbin/sshd: refused connect from 211.218.145.153
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 "outside". In order to run publicly accessible services (including sshd
) on a computer behind such a router/firewall, some configuration is required first. 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. There are two problems with enabling direct SSH access through a router/firewall: first, it makes the sshd
server easier to find and attack from any computer on the Internet, and second it requires control of the router/firewall and DHCP server (which may be the same device). In many cases, such control may not be available, although there are network administrators, reverse tunneling should not be attempted without notifying them, in case reverse tunneling constitutes a violation of 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. With a hardware access point, it may need to be enabled there as well. In the Linksys WRT54G's administrative web interface, for instance, 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.
In both cases, forwarding requires the SSH server to have a "static" IP, so it's consistently at the configured address. The easiest way to ensure this is to set the computer to Configure IPv4: Manually, but this caused trouble when I moved my PowerBook to another network where 10.10.10.21
wasn't a valid IP address. The 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 AirPorts, or in the WRT54G as shipped by Linksys. Static DHCP is available in Mac OS X Server, though.
Another limitation of this forwarding is that typically port 22 can only be forwarded to one machine. This can be worked around by running SSH on a nonstandard port, or SSHing into the forwarded computer, and then SSHing again to another private machine.
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. In some cases, there are different files for the SSH version 1.x protocol, and another for the SSH version 2.x protocol. On other systems, the global files may be in different locations, such as inside /etc/ssh/
/usr/local/etc/
on locally compiled installations. 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
, and 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 as easy as modifying normal documents. I normally use BBEdit to access these files, typically starting from a Terminal window, like "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 the Finder's 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 editing, 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_dsa_key |
~/.ssh/id_dsa |
SSH v 2.x DSA keys, private and public. Private keys are equivalent to passwords, and must be protected with filesystem permissions, and preferably encryption for user private keys. Host private keys cannot be encrypted, because sshd must be able to start without user intervention (to enter a decryption passphrase). SSH v 1.x keys, are deprecated because the SSH v 1.x protocol has been broken. |
/etc/ssh_host_rsa_key |
~/.ssh/id_rsa |
SSH v 2.x RSA keys |
/etc/ssh_known_hosts |
~/.ssh/known_hosts |
List of public keys for hosts. |
/etc/hosts.allow |
-- | TCP Wrapper configuration files, used to limit access to sshd , generally by client IP. |
There are several additions to these files which can make SSH use easier and safer.
File | Suggested addition | Notes |
---|---|---|
/etc/sshd_config |
Protocol 2 X11Forwarding yes |
The SSH v 1.x protocol has been broken, and should no longer be used; this forces SSH v 2.x protocol only. X11Forwarding permits the client to request tunneling of X11 connections; by default it's disabled on Mac OS X. |
/etc/ssh_config |
Protocol 2 ForwardAgent yes ForwardX11 yes ForwardX11Trusted yes NoHostAuthenticationForLocalhost yes |
The SSH v 1.x protocol has been broken, and should no longer be used; this forces SSH v 2.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 with forwarded ports. |
~/.ssh/id_dsa ~/.ssh/id_dsa.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 feasible, 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. |
Hopefully you've learned something useful here. The most helpful SSH "tricks" for me are public keys and agents, forward and reverse tunneling (reverse so I can help other people with their computers), and integration with bbedit
and rsync
. 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.