Published on MacDevCenter (
 See this if you're having trouble printing code examples

Inside SSH, Part 3

by FJ de Kermadec

Editor's note--In Part 2 of this multipart series delving into the Secure Shell on Mac OS X, François Joseph de Kermadec showed you how to securely fire up the Secure Shell and start communicating. Now, in Part 3, he digs deeper, showing you more advanced techniques.

Editing the Files

Editing configuration files is actually extremely simple once you know how to work with them. These files are simply text documents containing a list of settings and their associated values--one setting and its corresponding value are usually on the same line.

To change the value, simply erase the text and replace it with the new one. In some cases, the line will be preceded by a hash sign (#), meaning that it won't be taken into account by SSH. Simply remove the sign after you've changed the value so that the change you've made can be read and taken into account. Such a line is a default, meaning that it is normally the value your SSH server adopts. However, uncommenting it will make things clearer for you and may help you avoid an unexpected configuration glitch.

For example, if I wanted to change the imaginary option "SayHelloAndSmile," I would change:

# SomeStrangeSetting yes
# SayHelloAndSmile no
# SomeStrangeSetting yes


# SomeStrangeSetting yes
  SayHelloAndSmile yes
# SomeStrangeSetting yes

In order to edit the files, I would recommend that you use pico, a simple text editor that lives right in your Terminal. Once you've opened a file in pico, use your arrow keys exclusively to navigate. At the bottom of the window, you will see reminders of useful shortcuts. Simply keep in mind that "^" means "Control," and you're good to go!

To edit the file, you can either SSH into the server or sit in front of it and use its keyboard.

The Server Configuration File

In order to open the server configuration file in pico, type the following command and press Return:
sudo pico /private/etc/sshd_config

You will be asked for your administrator password. Make sure that you provide the one for the account you are logged in to.

PermitRootLogin no

Turning this option off will prevent anyone from logging as root through SSH. Because no administrative task should be performed in the root account--unless you are a really advanced Unix user and know the consequences this may have--this will greatly increase the security of your setup without preventing you from doing your work. Because the root account is all-powerful in traditional Unix systems, it is the one that most often is targeted by remote attackers--another good reason to prevent access to it.

PasswordAuthentication no 

Password authentication is the weak authentication scheme we are trying to avoid. Therefore, turning it off is our main goal.

PermitEmptyPasswords no

Nothing is more dangerous than an account with an empty password. As a security-conscious administrator, you already should have made sure that no user account is set up that way. However, for additional security, make sure that you use this option: When it is turned on, SSH will deny access to any account that does not have a set password.

PubKeyAuthentication yes 

Public key is the strong authentication scheme we are working on. Therefore, it is essential that you enable it--or you could lock yourself out of the remote machine, which is never a comfortable situation.

RSAAuthentication no 
RhostsAuthentication no
ChallengeResponseAuthentication no 
PAMAuthenticationViaKbdInt no

These authentication schemes are weak or do not apply to our setup. Therefore, it is best to turn them off. Leaving them on would defeat our efforts to secure the SSH server.

StrictModes yes

When this option is enabled, SSH will make sure that the user's files and directories that are involved in the SSH logging process are adequately protected by the permissions scheme on the server. If this were not the case, SSH would simply deny the connection. Of course, file permissions are far from the ultimate security system, but they still provide some level of security that we should not knowingly neglect.

LoginGraceTime 30

When this option is enabled, SSH will give you 30 seconds to authenticate, after which the connection will be closed. That way, an attacker trying passwords or hesitating will have to request multiple connections, which slows him down. Also, it will prevent the server from listening to connections that are not going to be used and were established by mistake. Ideally, this value should be just long enough to allow you to type your password quickly--but if it's too short, you could lock yourself out.

KeyRegenerationInterval 3600
ServerKeyBits 768

These two settings will make sure that the server key, which is used in the encryption and securing process, is long enough and will be changed frequently. Indeed, the more data is encrypted with a key, the easier it is to guess it and to crack the encryption. By creating a new key frequently, you can prevent such attempts.

Protocol 2

This option will restrict the OpenSSH server that runs on your Mac so that it uses only the SSH2 protocol, which features a better integrity check mechanism and is considered more secure. While recent versions of the OpenSSH client normally default to SSH2, it will prevent any remaining SSH1 authentication mechanism to cause your remote Mac to rely on this older protocol. It will also make things more difficult for potential malicious users by limiting their options and the number of vulnerabilities they can try to exploit.

AllowUsers username

You'll actually have to add this line. Of course, replace username with the name of the account(s) you want to be able to SSH into. The goal of this line is to prevent SSH connections to any account that has not been explicitly authorized. It adds a layer of security that is always welcome and prevents forgotten keys from firing back when you least expect it.

If you want to refine this setting, you can enter a list of usernames or username patterns, separated by spaces. For example, you can use the traditional Unix wildcards ? and *. Just keep in mind that user IDs do not work with this keyword.

Finally, you can write the username in a user@host form, allowing log in only to a user from a specific host. However, be very careful with this option; it does not considerably improve security and, knowing how easily host names can change on networks, you could lock yourself out of your own server easily.

SSH features a DenyUsers command that you may use instead--don't try to use both, though, since they can conflict. In this case, AllowUsers is more powerful and should be what you are looking for.

To save your work, type Control-O followed by Return. Then, to exit pico, type Control-X, which should cause the prompt to reappear.

Securing the Client

Securing the host is the most important part of our process. However, by setting up a few options in the client configuration file as well, you can reduce the length of the SSH authentication procedure and prevent SSH from falling back to insecure methods without your knowledge or approval.

This time, you want to edit /private/etc/ssh_config and to set up the following two values for the reasons that we have seen earlier:

RSAAuthentication no 
PasswordAuthentication no 

A Word About Time-out

Related Reading

SSH, The Secure Shell: The Definitive Guide
By Daniel J. Barrett, Richard E. Silverman

When acting over such long links, you should keep in mind that your connection goes through many devices that enforce various time-out policies. For example, your router may end NAT links after a few minutes of inactivity, without giving you the opportunity to alter the setting. It is therefore a good idea to avoid letting your connection be idle for more than a few seconds.

Indeed, should a device drop the connection while you are working, you not only may lose data but also may have difficulties establishing a new connection to the server.

A Special Note for FileVault Users

As we saw a few months ago, FileVault replaces your regular Home folder by a disk image that is mounted when you log in.

However, this means, quite logically, that as soon as you log out of your account, its contents are unmounted and cannot be accessed by any other process, including the SSH server. Therefore, the keys that you have just placed in your .ssh folder won't be available and authentication will systematically fail unless you are logged in locally.

There are ways around this, of course, one of them being to create a nonvaulted account, into which you would log in before mounting the .spaseimage that actually makes the vault. However, you should keep in mind that if the information you store on your computer is important enough to be vaulted, it is probably not a good idea to access it remotely that way and to type your FileVault password in a way that makes it more or less easy to get--depending on the method you pick. You may want to look into VPN solutions for high-security environments.

You can always put your keys into another folder, but this raises security issues of its own and is beyond the scope of our discussion.

Note that this is the case only on the server; you can FileVault your client without incident since, by definition, you will be logged in to the account when accessing the remote machine. Just make sure that your backups are in encrypted form too--or someone stealing your backup could access the contents of your home folder, including your keys.

Testing the New, Secure Configuration

Now that you have modified the SSH configuration files, you need to tell the server that it needs to reread it--otherwise your settings will not take effect. The easiest way to do this is to use the Sharing preferences pane to disable Remote Login and enable it again.

Also, restart your administrative machine as an added security, to make sure that any changes you have made are taken into account. This restart is also a good time to make sure that automatic log in is turned off, if applicable, and that your log-in window does not give away the name of your account--Mike's computer, for example, is not a great idea if your account name is mike. On the other hand, it would be OK if your account name is john. Of course, this is applicable only if users are required to type in both their username and password to access their account.

Then, try to SSH in to the usual account and, in order to test the reaction of the SSH server, do not provide your key's password. If everything goes well, it should immediately close the connection. On the other hand, the key password alone should let you in without a hitch. Note that the first connection to a host may fail if you have set up a log-in time limit, because more processing takes place behind the scenes and it may exceed the log-in time limit. In that case, simply try again.

Outside the Firewall

Until now, we have seen how to leverage the power of SSH to remotely log in to a machine over your LAN.

Remote logging wouldn't really be remote if you couldn't reach a computer over the Internet, would it? However, doing so requires punching a hole through your firewall in order to allow incoming SSH connections.

While many firewalls now feature complex inbound rules that will let you limit the number of people who can go through the hole you have punched (depending on their IP address, for example), you may not be able to use them, for various reasons. Some ISPs have an unpredictable addressing scheme and operate in various IP ranges. Also, IP-based controls are never really secure and should therefore not be considered too reliable. They are a deterrent at most, and probably a good one.

Before you read further and enable true remote logging, I strongly urge you to weigh the pros and cons of doing so. Is your LAN secure enough? Should a computer on your LAN be compromised; will the incident be noticed in a short time frame? Would it affect other computers on the LAN? Can you afford to take this risk?

If you're willing to go further, we're now going to see how to remotely log in to your Mac, regardless of where you are located and what IP addressing your Internet service provider uses.

A Brief Introduction to DNS

As an experienced Internet user, you're probably familiar with the concept of IP addresses: strings of numbers that uniquely identify a host. However, you never have to type IP addresses in your web browser's address field, even though you could if you wanted to.

How's this possible? Roughly speaking, this is due to the wonders of DNS, the Internet equivalent of the phone book, which translates domain names into IP addresses so that your computer can contact the appropriate server. When your computer requests a specific URL, a chain of queries begins, from DNS server to DNS server, in order to find the matching IP address.

Most sites have a fixed IP address or a range of addresses. Once and for all, the DNS records are set and, unless something big happens to the servers of this company--they may be moved, for example--they are likely to stay the same indefinitely.

However, the DNS service is extremely flexible, and nothing prevents it from linking a domain name to a new IP address every day, if it were needed. The services handling these frequently changing records are typically called Dynamic DNS or DDNS.

OK, enough of that. Let's get back to work.

Accessing Your Router

Since the Mac you are trying to remotely log in to is located behind a router/firewall, we first need to know how we are going to reach it. We'll worry about how to get through it in a moment.

Like any other device connected to the Internet, your router has an IP address assigned to it by your Internet service provider. In some cases, IP addresses are fixed, while in others they are rotated every few hours.

If you're one of the lucky owners of a static IP address, you don't need to worry about finding your router on the Internet. Simply use the same address again and again, knowing that your router is the one who stands behind it.

Unfortunately, most users are not that lucky, and even expensive broadband subscriptions often come with a dynamic IP address that randomly changes every few hours. What's the solution, then? You're right, Dynamic DNS!

Indeed, a good workaround is to set up a domain name and have a special software update the DNS records associated to it every time your IP changes. Therefore, you don't need to worry about addresses anymore. Just type the domain, knowing that it will automatically translate into the address that your router has been assigned at the very moment you type it.

Contrary to what it may seem at first sight, updating the DNS records on a regular basis is not too complex a task. Indeed, many home routers and firewalls now feature a built-in application that will take care of this by itself. As soon as the router detects an IP change, it alerts your DDNS provider. This requires that your DDNS provider be known enough so that the engineers who built the router included a specific function for it in their firmware.

If you don't own such a router, you can install a specific client on your server that will take care of it. You should just make sure that the client you install launches itself automatically at log in and fetches the router's IP address reliably.

Getting a DDNS Account

One of the leaders in DDNS services is a company called DynDNS. You can learn more about its services here. It has earned the trust of many web users over the years with some excellent services and great customer service.

Because the company is widely popular, I'm going to show you how to set up a DDNS account by using its site. Feel free to rely on the company that best suits your needs; make sure, however, that you read all the help pages posted on DynDNS's web site. It will help you avoid many potential surprises.

In order to create an account, simply use the Create Account page, and remember to visit it securely. Make sure that you agree to the terms and conditions and fill in the required information.

If you already have an account at the company you pick, it's a good idea to create a separate one for DDNS services. Indeed, most DDNS software (either clients or the ones built into routers) sends your authentication information in the clear when it updates the DNS records. While this is acceptable for an account that does not hold any critical or banking-related information, you don't want someone to be able to access your domain names, mail settings, and banking numbers by simply sniffing a password.

The account creation procedure is quite straightforward. To activate your account, you may need to follow further instructions that you receive by email.

Once you've created your account, simply log in and click on the Services tab to display the various services offered by DynDNS. In the left column, pick Dynamic DNS and Add Host.

In the form that appears, you will be asked to pick a domain name. Don't hesitate to use the pop-up menu on the right to find a domain name that fits your needs and taste. The custom part should be simple enough for you to remember--though the simpler it is, the greater the chances that it has already been taken. Also, keep in mind that you may need to give this domain name to someone; picking a neutral one will make things easier.

The I.P. address field contains your current IP address, as detected by your browser. You can change it if it's not accurate.

Although extremely useful, the other options are outside the scope of our discussion. You may want to refer to the documentation for more information of what the options do and how they perform their magic. Paid accounts can set up an offline redirection page that will appear when your Mac or router goes offline. While this can be convenient, it is up to you to decide whether you need it--also, keep in mind that entering banking information into the account raises a risk.

Once you've set up the account, you can safely log out. Then, immediately set up your router or software client so that it automatically takes care of keeping the DNS records up-to-date. Make sure that your client does not unknowingly violate DynDNS's abuse policy, which could cause you trouble.

It's also a good idea to monitor the DDNS setup for a few days, making sure that it works as expected.

Going Through Your Firewall

For now, typing this newly creating domain name into a web browser's address field, pinging it through a terminal, or attempting to establish an SSH connection to it will automatically fail.

Why? Because your firewall is blocking any connection attempts that were not requested from the inside of the network--at least, that's what any good, self-respecting firewall should do.

Therefore, it will be necessary to punch a hole through your firewall and specify the computer on the network to which to forward requests sent to a particular port. This method is called, unsurprisingly, port forwarding. Most firewalls and routers now include this option.

In fact, this method is a bit more secure than simply opening a port in your firewall. Indeed, in addition to accepting incoming connections and letting them reach any computer on the network, it reroutes them so that they all hit the same server. That way, the other computers located on the LAN are somehow better protected--although to a certain extent the whole LAN is at risk, since a compromised server can be used in turn to compromise other hosts on the LAN.

Once you have set up your firewall, make sure that remote administration is properly shut down and secured, should your device include this option. Indeed, such firewalls make a tempting target for hackers--own the main networking device of a network, and you own the whole network.

DHCP Is Our Enemy

Most routers or firewalls allocate IP addresses to the various hosts on the network on a dynamic basis, meaning that the same computer won't have the same address every time that the device is turned on or the network is reconfigured.

You should therefore configure your firewall so that it always assigns the same IP address to the same Mac--leaving the other computers on the network with dynamic addressing if you like. Often this is possible by instructing the device to associate a NAT address to an IP one. You could otherwise use static IPs for all the computers on your network, but keep in mind that this requires more precise maintenance and may raise security issues in the long term.

The Big Test

Then, open your terminal, enter ssh username@yourdomainname.ext and see what happens. On some LANs, you will immediately get an Access Denied message because your firewall does not understand what is going on--you are inside the network and attempting to use a WAN domain name. Therefore, it's a good idea to test this setup while using another, independent connection to the Internet. It will also make for a much better simulation of real-world conditions, when you will be miles away from the server.

If everything goes well, both of your Macs should behave exactly as if they were both on the LAN.

Next Time

You've made it three-quarters of the way through this series! Next week we wrap up with a little Terminal application work (so you can tap all of the power available to you), a look at updating your Mac remotely, and a few other goodies too. See you then.

FJ de Kermadec is an author, stylist and entrepreneur in Paris, France.

Return to the Mac DevCenter

Copyright © 2009 O'Reilly Media, Inc.