Saturday, October 02, 2010

Remote Login to the Command Line

The other day I was away from home when my wife called up and asked me where I'd put the papers I'd promised to print out.

I let out a very soft damn, because of course I'd forgotten to print out anything.

But all was not lost. I simply logged onto my home computer, found the appropriate file, and printed it, on my home printer. She was suitably impressed.

This, of course, is the whole point of a long-ago post, where we figured out how to determine a router's external IP address. What we want to do today is to use that information to log onto one of your home computers from afar. We'll assume you have figured out your current dynamic IP address, perhaps by looking at the bottom of your gmail page, or using the software I assembled in the previous post.

So let's say that you've found that your router currently has the dynamic IP address aaa.bbb.ccc.ddd . Then, in principle, all you have to do to log onto your account at home would be to open up a terminal and type

ssh rcjhawk@aaa.bbb.ccc.ddd

where you'd replace rcjhawk by your own account, of course. Then, if you have ssh set up properly, you'll be logged to a CLI on your home machine.

In the usual home setup, with many computers connected to a router with only one external IP address, this will never work out of the box. First, the router doesn't (usually) do ssh on its own, and if it did there wouldn't be any useful information for you there, unless you wanted to trash fix your own network. Second, the router doesn't know which machine you want to talk to. And third, even if it did, that machine might not be accepting ssh requests (and won't, if you've followed my previous recommendation).

So what do we need to do? Let's see: First, we need to tell the router which computer gets the ssh session. Then, we need to set that computer up to receive ssh commands. Finally, if we want to be able to contact multiple computers, all behind the same router, we have to figure out how to do that, as well.

Setting up the router

First things first: how does the router pick a computer for ssh? Well, though Wikipedia tries to explain it in technical detail, basically your computer connections to the outside world are controlled by a set of 65536 (or 216) ports. If you like, you can consider each port as a connection in an old-style telephone switchboard. When you call up a specific service on a computer, you ask to be hooked up to a specific phone number.

Some of these phone numbers, or ports, are customarily assigned to specific services. For example, port 80 is usually reserved for a web server. It doesn't have to be that way, though, you could start your web server running on port 31526, if you liked. The problem is that everyone's browser would be looking for your server on port 80 of your computer, and you wouldn't get many hits. (If that's what you desire, go for it.)

ssh, it turns out, is typically assigned port 22. So when I run

ssh rcjhawk@aaa.bbb.ccc.ddd

the computer I'm on asks the operator (my home router), to connect it to port 22 so that it can talk to whoever is there. If that contact speaks ssh, then we can communicate. If, however, the contact is speaking telnet, or ftp, we're going to have problems.

The router, as we said above, knows nothing about ssh, or at least doesn't want to talk to the unwashed masses of the Internet. It has to pass the call on to a computer that I've designated to receive ssh requests. This works by what is known as Port Forwarding. This tells that router that whenever someone comes calling at port 22 it is to pass that signal along to a specific computer.

How do you do port forwarding? Well, that depends on your router, your firewall, if any, and maybe on your modem. I can't give general directions, though might be able to help. There is also a YouTube instructional video, and you ought to be able to find specific instructions for your own router/firewall.

Since I'm on Verizon FIOS here at the house, I have a Verizon MI424WR modem/router. There is an old set of instructions for port forwarding online, but the software seems to have changed. That did provide a starting point, however, and I've figured how how to set up forwarding on my current setup:

  1. Point your Browser at
  2. Click Firewall at the top of the page.
  3. Click Port Forwarding on the left.
  4. You see a line that says Create new port forwarding rule: and below that a box that says IP Address forward to or select from menu. Click on that, and then click on the machine you want to pipe your ssh requests to.
  5. Click on the box labeled Application to forward … and select SSH. When things settle down, click apply.

Setting up your home machine

This is fairly straightforward. Let's assume that we've instructed the router to forward port 22 to hal, here. On hal, we've followed all the instructions to get the ssh daemon running, so that we know what to do with incoming ssh requests.

Currently, however, we have the line
in our /etc/hosts.deny file, and
in /etc/hosts.allow, which means that only computers on the local network can ssh to hal. One way to fix this would be to add
sshd: ALL
to /etc/hosts.allow. This allows hal to receive ssh requests from any machine, anywhere. Another way to do it would be to specify those external machines that can access hal by host. For example, if I worked for Google, the line might read:
or some-such, letting me log in from any computer with an ip number

Once we have your home computer's /etc/hosts.allow file properly set up, then running
ssh youraccount@aaa.bbb.ccc.ddd
from an allowed machine, where youraccount is the account name on your home machine, and aaa.bbb.ccc.ddd is your router's current IP address, should get you in, at least after you enter the appropriate password.

Other machines on your network

The problem with all of that is that I can only access hal by this method. Suppose I want to access another computer, fred, instead. I could, of course, get into my router and change port 22 forwarding from hal to fred, but that's difficult to do from the road, unless I allowed my router to be administered remotely.

However, the port/service assignment is more of what you'd call a guideline. We can, in fact, use any port in a storm for ssh services. In the example above the Verizon router had presets for ssh using port 22, but we could have used any other port instead.

Again, the exact way of doing this will vary from router to router, but to set up forwarding of an arbitrary port to a machine with the Verizon router,

  1. Point your Browser at
  2. Click Firewall at the top of the page.
  3. Click Port Forwarding on the left.
  4. Under IP Address … click on your target machine.
  5. Under Application click Custom Ports. When things settle down you'll have a bunch of boxes to click.
  6. Under Protocol select TCP.
  7. Under Source Ports select Any.
  8. Under Destination Ports select Specify, and then put in your selected port. In this case we'll use 1022. We don't have to use 1022, but it's simple to remember, once we know that ssh ordinarily uses port 22.
  9. Click on Apply and you're done here.

Now go back to your target machine. Open up a terminal window. Then,

  1. Run
    sudo vi /etc/hosts.allow
    and edit the file to allow sshd access from your favorite machines, just as you did with the first machine.
  2. Run
    sudo vi /etc/ssh/sshd_config
    Look for a line that says Port 22
  3. Below that line add the line
    Port 1022
    or whatever other number you've chosen.
  4. Stop and restart the ssh daemon by running the command:
    sudo /etc/init.d/ssh restart
  5. Now go over to your remote machine. Run
    ssh youraccount@aaa.bbb.ccc.ddd -p 1022
    if 1022 is the port you've chosen. You should be logged on to the second machine in your network.

That concludes the tutorial on accessing your home machines' command lines. Ubuntu also has a remote desktop feature, which I've yet to use. When I get around to trying it out we'll put that online here as well.