May 2013
Host: The computer that is somewhere else. You want to connect to this computer.
Client: The machine you are sitting at. You will connect to the host from this computer.
There are many reasons why you might want to connect to a remote computer. The most common reasons? You want to get your files, you want to administer the machine, you want to proxy your Internet connection, or you want to open a remote desktop session and act as though you were seated at the machine... doing the usual things you do when you are there. There is another possibility; you have another computer that is not connected to a monitor, keyboard, or mouse.
Before we can do any of these things, we have to establish a communication channel with the host. Think of it like a telephone number and extension. It has to be setup before we can make a call and have a conservation. With computers, the telephone number is your machine's IP address. The extension is the port and will vary depending on the kind of remote conversation you want to have (remote desktop, file transfer, etc.)
Here's a diagram of our system:
The connection flow includes:
In setting up, we will configure the host to accept connections. Then, stepwise, we will make the remote connection available to the network.
When we make a connection, we want it to be private. Also, we want to be reasonably assured that unauthorized users can't connect. To do this, we will use a protocol called key-authenticated secure shell (SSH). SSH enables us to encrypt our communications. When we setup SSH, we will configure it to require cryptographic keys rather than a simple password when it authenticates a potential user. Don't worry, you won't have to remember the key or type it when you connect.
SSH will be the only service exposed by the host to the outside world. Every other service/port we wish to use will be channeled (tunneled) through this secure shell. When you obtain a secure shell on (ssh into) a machine, you have access to any service ports on that machine, even if they are firewalled.
For this tutorial, let's decide that our SSH port will be 3000 .
Configure the firewall to deny all incoming ports except 3000.
If your remote machine is Linux, you probably have ufw (uncomplicated firewall) installed. If not, consider installing it. Most firewall administrative menu items are simply GTK front ends for ufw.
~$ sudo ufw status
Status: inactive
~$ sudo ufw enable
Firewall is active and enabled on system startup
~$ sudo ufw
default deny
Default incoming policy changed to 'deny' (be sure
to update your rules accordingly)
~$ sudo ufw allow in to any
port 3000
~$ sudo ufw status verbose
Status: active
Logging: on (low) Default: deny (incoming), allow (outgoing)
New
profiles: skip
To Action From
-- ------ ----
3000 ALLOW IN Anywhere
3000 ALLOW IN Anywhere (v6)
The Windows firewall will vary from version to version. The firewall is on and set to deny incoming connections by default – with certain services/ports open for program access. Verify this then add a new rule that allows incoming connections on port 3000.
Just what is this port we are opening in the above networking example? It could be any service (e.g. an ftp server). In our organizations and our homes, we don't like to expose service ports to the greater world. The only port we expose is a secure shell port. Again, we use SSH to tunnel the other necessary ports on the host to the client. Then, we set our client applications to use the tunneled port. For all non-SSH services provided by the host, we will act as though they are being provided locally – making the connection to localhost and not the host's IP. Essentially, we are using a local port as a proxy and encrypting communications with the host through the SSH service.
For example, we can have a remote desktop server running on the host at port 5900. Incoming connections to port 5900 can be firewalled so the service cannot be constantly interrogated by a "bad guy." When you ssh into a machine, you can tunnel the remote port to a local port, perhaps port 5092. Now you can connect to the remote desktop at localhost:5092.
With Linux you can use your package manager. With Windows we will use Cygwin to get a Unix-like virtual utility that will support OpenSSH. This Windows setup is a bit more involved. Appendix A gives a recently tested install procedure for Cygwin.
Use public key authentication and not password authentication. For additional security, I prefer my keys to be password protected to buy time to change all of my hosts if I am careless with my keys.
*A default example sshd.config file is created when you install OpenSSH-server. We need to customize it. Lines beginning with '#' are comments placed in the file for the reader's guidance. The uncommented lines define your custom configurations. Here are the lines that are uncommented in my file:
Port 3000
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey
/etc/ssh/ssh_host_ecdsa_key
UsePrivilegeSeparation yes
KeyRegenerationInterval 3600
ServerKeyBits 2048
SyslogFacility AUTH
LogLevel INFO
LoginGraceTime 120
PermitRootLogin no
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile
%h/.ssh/authorized_keys
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
PasswordAuthentication no
X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
AcceptEnv LANG LC_*
Subsystem sftp
/usr/lib/openssh/sftp-server
UsePAM no
Make note that in this list we have specified our port: 3000. Also see that we have disabled password authentication (PasswordAuthentication no) and we have specified where to find the authorized public keys that the SSH server will accept: AuthorizedKeysFile %h/.ssh/authorized_keys.
The changes above are for a Linux install, but they work with the Windows/Cygwin configuration too, provided you change four lines because they point to files on the system that will be located in other places:
Verify that those paths point to the correct files. Note that the Cygwin root directory.'/', is located at c:/cygwin/ and all file specifications are relative to that.
I will be using Putty to configure, manage, and open my SSH connections. Seasoned Linux users may wince, preferring a command line approach. I like Putty and it is included in the default repositories for most common Linux distributions. With Windows, you will need to get it from the Putty site (http://www.chiark.greenend.org.uk/). Putty is a very useful, well designed GUI that provides a cross-platform, portable SSH management system. You can set the SSH terminal preferences individually for connections to different servers.
Putty is a client application. You don't need to install it on the host machine. Only OpenSSH needs to be running on this machine. In this tutorial, we will install Putty on the host, simply because it will give us a way to do a preliminary configuration test right at the host.
Your master key for connecting to a machine is a single-file key pair. It has encoded within it both a private key and a public key. This master key file will be given the file extension .ppk. You can carry it with you on a thumb drive (but don't loose it). One time only, when you set-up the host, you configure it to reject all other keys (and passwords) by pre-authorizing your access using your public key. You can make your public and private Putty keys from any machine. In this tutorial, I am doing this at the machine that will be the host.
Use the handy puttygen GUI to make the key pair (.ppk). Save it and export the public part (.pub). Bring the public key to the host and save it as "C:\cygwin\home\authorized_keys."
Start the Putty GTK program from within the host.
You now have a command prompt... on the host! If you know how to get administrative privileges, you can do anything you want with/to this machine. That's why we insist on SSH with key-authentication. (When a bad guy installs maleware that does this without your consent, it's called a back door.)
In the test, we entered the key's password and not the system's password. Convince yourself that you cannot reach this machine without the authorization key (try to connect after moving the ppk key to a different folder on your computer).
If the test doesn't work, be sure you have restarted the SSH server/service. If you still have trouble, retrace all of the steps from the beginning. You can ignore the firewall settings. They don't apply to connections to localhost. If the connection is refused, then your SSH server isn't setup properly, isn't running, or you have the wrong port. If you see no authentication methods available, then you probably have to set the permissions on the .ssh folder and the authorized keys file (see above).
Notes:
In the example above we logged into the host from the same machine. This is not very useful, but it allows us to correct errors in the SSH server's configuration before the additional variables associated with network connections compound troubleshooting complexity. If it worked for you, then you are ready to expand the host's availability to the network and Internet level.
Give your host a static address on the LAN (example: 192.168.0.20).
Open your router interface and forward all incoming requests on port 3000 to your host's static IP.
From a different client machine, install Putty and open the Putty GUI:
If all is well, you can connect in the same manner as you did in the test above. If not and you succeeded in the half-way point test, then you know that the problem is network routing, firewall settings, or your Putty session's configuration.
The real power of SSH is it enables us to use services on the host that are firewall-protected from the network/Internet. Services like VNC remote desktops, ftp servers, etc. are not secure. Passwords can be sniffed or cracked. Traffic isn't necessarily encrypted. But tunneling these services through SSH provides an encrypted channel for the use of the services. Better still, when you use key-authenticated SSH to tunnel the services, you only pass your clear text password to the localhost.
Another important use of an SSH tunnel is using a tunneled port as a web browser proxy. Say you are on a potentially hostile network but your host is not. Browser traffic is pretty transparent to eavesdroppers. Even SSL (https) traffic can be interpreted by bad guys if they can subvert your browser's certificate policies. If you have an SSH connection to a host on a safer network then, using a dynamic tunnel, you can browse the web and the local bad guy will only see a stream of nonsensical tcp packets. Another advantage for some is, you can browse the web as though you are located at the host's address. You reveal reverse DNS information to the sites you visit. If you are on the moon and some earth websites block (or discriminate against) moon people, then looking like you are from earth is advantageous.
See Using SSH tunnels to securely access a remote computer's services to learn how to use these tunnels.
Use the Cygwin site as a primary reference for installing. Below is simply a summary of an approach that worked for me.
Download setup.exe and setup.exe.sig, then check the signature.
Double click it. You will be presented with a choice mirror sites to
download from. Pick one that is near you and, preferably, one you
recognize and trust.
During setup, you will be given a dialog window for choosing additional
programs. Add openssh (net), rsync (net), and nano (editor). Type the
names in the window search box to find them.
After the installation is done, navigate to C:/Cygwin and double click the Cygwin.bat file.
Next find the Cygwin desktop icon (or start menu item) and Run As Administrator. In the terminal that opens, run ssh-host-config. There will be a series of mostly yes or no questions that may vary depending on the Windows version and previous installation history. In general, the answers are "yes." One line will prompt; "Enter the value of CYGWIN for the daemon: []." I respond with: "ntsec tty." I used my Windows password when asked to enter one. Here is the output from a Windows 7 install: