Linux Today: Linux News On Internet Time.

ISP-Planet: SSH: From Secure Administration to Virtual Private Networking

May 16, 2000, 20:03 (5 Talkback[s])
(Other stories by Lisa Phifer)

By Lisa Phifer, ISP-Planet

If you're still administering *NIX servers over the Internet using rsh or telnet, stop right now. OpenSSH is an inexpensive improvement well worth the minimal effort required to install and configure it. You can also use SSH to set up simple "circuit level" VPNs.

It's midnight and you've just been paged. Your largest, multi-domain web server is on the blink. You quickly rshell or telnet in to fix the problem. In doing so, you've probably just transferred sensitive information-your root password-over the public Internet. What's to stop a wily hacker from sniffing your password, then masquerading as you to exploit your server? If you're security-savvy, you've used something like Secure Shell (SSH) to avoid this common breach of security.

Originally designed as a secure replacement for *NIX "r" commands-rsh, rlogin, rcp-SSH uses strong authentication and encryption to secure management sessions. But somewhere along the way, SSH morphed. Today, SSH2 is a general-purpose secure tunneling protocol. As such, it can be used to construct a type of virtual private network sometimes referred to as a circuit-layer VPN.

In this article, we take a hands-on look at the two faces of SSH2: the open source *NIX implementation freely available from OpenSSH, and a trio of commercial Windows clients sold by F-Secure (formerly DataFellows), SSH Communications, and VanDyke Technologies. We'll show you how to enable secure administration and create a circuit-layer VPN with OpenSSH. We'll also illustrate multi-vendor compatibility between OpenSSH and these three Windows clients.

The Evolution of SSH

Many years ago, Tatu Ylonen created SSH version 1 to address several security weaknesses present in rsh.
  • UNIX user and host authentication, based on login/password, .rhosts, and hosts.equiv, are relatively weak. It is not difficult to masquerade as a known host or user to gain remote access. SSH permits stronger authentication methods, most notably the use of public keys. Newer implementations like OpenSSH support many strong authentication methods like SecurID, S/Key, and Kerberos.
  • To avoid transmitting sensitive information-even login/password-in the clear, SSH1 uses RSA to negotiate session keys. Session keys are then used by a symmetric cipher (e.g., DES, 3DES, RC4, CAST128, ArcFour, Blowfish) to provide data confidentiality. To circumvent patent issues associated with RSA, SSH2 now uses DSA and Diffie-Helman to create session keys.
  • To defend against modification of data in transit, SSH1 included a CRC check. SSH2 uses stronger message authentication to ensure data integrity, protecting against "man-in-the-middle" attacks.
Thus, protecting your shell or telnet session with SSH ensures that you've reached the host you intended to, the host has verified your identity and determined that you are permitted access, and that all messages you send and receive are protected against disclosure and modification.

Once you've connected with SSH, you can securely forward X11 traffic-or traffic sent through any port. Suppose you want a laptop with Internet dial-up to reach a private POP3 server located behind an Internet-connected firewall. You might install SSH on the firewall, securely tunnel from an SSH client on the laptop to the firewall, and have the firewall forward port 110 traffic to the private web server. SSH port forwarding can be used in this manner to create an inexpensive circuit-level VPN, but there are limitations, as we'll see.

Commercial Product vs. Open Source

Ylonen made his original SSH1 freely available, and it was soon ported to many other platforms. Several commercial SSH1 products also emerged with the usual benefits: user-friendly GUIs, documentation, and support.

SSH1 was adopted by the IETF as the basis for development of the Internet standard SSH2. Unfortunately, the same protocols changes that significantly strengthened SSH2 also made it incompatible with SSH1. And the only SSH2 implementations were commercial products. Until now.

Last year, OpenBSD 2.6 added built-in support for SSH1. Project members used this code to produce OpenSSH, first available in December, 1999. This month (May, 2000), OpenSSH 2.1 became available with full support for SSH2. We installed OpenSSH 2.1 on RedHat. It has also been ported to SUSE Linux, Solaris, AIX, IRIX, HP/UX, FreeBSD, and NetBSD.

Because OpenSSH support for SSH2 is hot off the presses, we decided it would be wise to check compatibility with commercial clients. We downloaded and installed three 30-day evaluation clients on a laptop running Windows 95:

  • F-Secure SSH Client 4.0 ($119, Win 95/98/NT/2000)
  • VanDyke SecureCRT 3.0 ($99, Win 95/98/NT)
  • SSH Communications SSH for Workstations 2.1 ($89, Win 95/98/NT/2000, Linux, Solaris)
Commercial SSH2 Server products are also available from F-Secure ($594) and SSH Communications ($399). A free, non-commercial version of SSH2 can be obtained from SSH Communications for evaluation and educational/nonprofit use only. We refer to this below as "non-commercial 2.0.13."

Configuring the Server, Step 1: SSHD & HostKey Config

The first step is to install the OpenSSH daemon (sshd) on either the server that you want to administer securely, or the "VPN" server that will forward ports into your private network. We installed OpenSSH on a dual-Ethernet PC with IP forwarding disabled to ensure that nothing but tunneled traffic would get past our SSH "VPN" server.

OpenSSH requires zlib and OpenSSL. We found our RedHat server already had zlib and quickly installed OpenSSL without incident. We also removed a prior version of SSH from our server before installing OpenSSH to avoid ending up with a mix-and-match set of binaries. To compile and install, simply execute the following:

gzip -dc openssh-2.1.0.tar.gz | tar xvpf -
cd openssh-2.1.0
make install
make host-keys
By default, the SSH daemon is installed in /usr/local/sbin and SSH client apps are installed in /usr/local/bin. A pair of configuration files (sshd_config and ssh_config) are installed in /usr/local/etc.

Open source fans will be familiar with all but the last step. SSH uses public keys to authenticate hosts and (optionally) users. To do so, we generate a pair of keys that are mathematically related such that if one is used to encrypt a message, only the other can decrypt it. One host key is made public to all clients, the other is kept private. To prove our server's identity, we encrypt a known value with our private host key. The client decrypts that value with the our public key and considers us authentic if the two values match. An SSH1 daemon requires an RSA key pair; an SSH2 daemon requires a DSA key pair. The "make host-keys" step generates both key pairs and stores them in /usr/local/etc. It is essential that the private host key files are accessible only to root.

Pluggable authentication modules (PAM) are automatically enabled on platforms that support them. To run OpenSSH, you'll either need to disable PAM using the --without-pam ./configure option or create a config file for PAM. On RedHat, this is easily accomplished by copying openssh-2.1.0/contrib/redhat/sshd.pam to /etc/pam.d/sshd. See openssh-2.1.0/contrib for further information and examples.

The default configuration is relatively strict: it prohibits .rhosts authentication, X.11 forwarding, and empty passwords. Use the sshd_config file to modify protocol versions and ports, file locations, and enable/disable authentication methods. We enabled DSA authentication for SSH2, negotiated SSH2 before SSH1, prohibited simple password authentication, and boosted the logging level by making the following changes:

Protocol 2,1
HostDSAKey /usr/local/etc/ssh_host_dsa_key
DSAAuthentication yes
PasswordAuthentication no
The SSH daemon runs in the background when you invoke /usr/local/sbin/sshd. Status and errors can be seen in the system log.

Configuring the Server, Step 2: SSH User Config

Now that you have an SSH daemon running, you'll want to selectively allow users to connect. SSH supports host authentication using .shosts (a more secure version of .rhosts) or .rhosts plus RSA authentication. Either can be used to allow open-door access by trusted hosts. We decided to require user authentication and configured a security policy for each login granted SSH access.

With OpenSSH, configuration files and keys are located in each user's .ssh directory. To use public key user authentication, we start by invoking ssh-keygen to create an RSA key pair for SSH1 and a DSA key pair for SSH2. Unlike the host keys generated earlier, these keys identify this user. Next, we create a pair of authorization files (authorized_keys and authorized_keys2) containing all the public keys permitted access as this user.

Initially, we add our own public key to each authorization file, allowing local OpenSSH client "loopback" connections for testing. We'd do something similar to permit remote OpenSSH clients to connect to this server. For a third-party SSH client to connect, we need to convert the remote user's public key file before adding it to the authorization file. Those familiar with other SSH products will note that OpenSSH also uses different filenames and locations: .ssh instead of .ssh2, authorized_keys instead of authorization, no identification file, embedded keys instead of referenced public key files. The last item is the only deviation we'd quibble with: We find the authorization file format used by OpenSSH less manageable than the by-reference format used by non-commercial SSH 2.0.13.

Running the OpenSSH Client

OpenSSH includes SSH client applications; these can be used to establish SSH connections from any supported *NIX platform. Default client settings are taken from /usr/local/etc/ssh_config, but can be customized by placing a modified ssh_config in each user's .ssh directory. We made changes to enable DSA and disable password authentication in accordance with our security policy:
DSAAuthentication yes
PasswordAuthentication no
IdentityFile2 ~/.ssh/id_dsa
Protocol 1
So that we could easily test SSH1 features, we made our client propose protocol version 1 by default. We then used a command line option to override this whenever we wanted to propose SSH2.

The first time any user connects to a host, SSH offers to add that host's public key to the user's local knownhosts file. In other words: "Do you want to blindly accept that this host is who you think it is?" Config options can close this loophole by allowing only previously-known hosts. Knownhosts files can be seeded by automated update during installation, then locked for production use.

When executed without further qualification, 'ssh hostname' establishes a secure shell session with the named host. Commands can be executed remotely by adding them to the command line: for example, 'ssh hostname xterm'. To create a circuit-layer VPN, use the -L and -R options to forward a specific port. For example:

ssh -L 8001:mailserver:110
tells the SSH client to take any traffic addressed to localhost port 8001 and shove it through the secure tunnel to the SSH server. Upon receipt, the SSH server forwards the traffic (now clear text) to mailserver port 110. The -R option permits reverse port forwarding from remote hosts, through the SSH server, to the SSH client. This mechanism allows simple forwarding for protocols that use a single, well-known port: POP, SMTP, Telnet, HTTP, etc.. But it doesn't work for protocols that use arbitrary ports: typically, a well-known control port and a dynamically-chosen data port such as that used by FTP. We'll see later how this limitation has been overcome for FTP. SSH's inability to forward port ranges and dynamic ports is a major issue to contemplate if you're considering using SSH to create a circuit-level VPN.

Another issue is the ability to restrict SSH port forwarding or prohibit shell access. SSH clients must have login accounts on your SSH server. If these accounts exist for a limited purpose, you need to be able to enforce those limitations. Port forwarding can be restricted by options added to the authorized_keys file. The following example illustrates a login limited to forwarding telnet. Once the SSH session is connected, it automatically telnets to localhost. The connection is forwarded to "private", the telnet server specified in the SSH client command line argument. This example restricts the command the SSH client can issue, but has no control over the forwarded destination and port. The following example blocks all port forwarding. We were only successful using these options with SSH1, but hope that SSH2 support will soon be added.

Rounding out the SSH client apps supported by OpenSSH are secure versions of rcp and rlogin, called scp and slogin. However, OpenSSH 2.1 does not include secure FTP (see F-Secure).

Configuring Windows SSH Clients

While each Windows SSH client has its unique features, all clients must perform the same basic configuration tasks. The first task is to use a wizard to generate a public/private key pair for user authentication. The wizard typically prompts for key length; 1024 bits is common. Here, we see this step as presented by the SSH Communications client (right). Click to veiw larger image

Click to view larger image Each wizard also prompts for a passphrase used to encrypt the private key. It's important that the private key be encrypted so that only a legitimate user can gain access to it. Without a passphrase, there would be no security if the private key file were to fall into the wrong hands (e.g., stolen laptop). Here, we see this step as presented by the VanDyke client (left).

The key generation wizard creates a pair of key files. The next step is to get the public key file to the SSH server so that it can be added to the authorized_keys file. The public key can be safely mailed to the SSH administrator or transferred by "sneaker net." F-Secure automates key registration with a wizard that uses password-authenticated FTP to put the public key and authorization file on the SSH server in the $HOME directory for specified user (right).We successfully used this wizard with the non-commercial SSH server 2.0.13, and it does measurably speed/simplify client configuration. But we were unable to use F-Secure's Registration Wizard with our OpenSSH 2.1 server. Click to veiw larger image

Click to veiw larger image Each client uses a Properties or Options panel to define SSH Connections or Sessions by specifying the SSH server hostname or IP address, SSH port, and user login. Here, we see this step as presented by the VanDyke client (left). Other properties allow configuration of ciphers, fonts, terminal settings, etc.. Connections can be saved for future use and launched automatically or by default at client startup.

As we saw with OpenSSH, these Windows clients support port forwarding. Here, we configure the SSH Communications client to create a circuit-layer VPN by defining two Local Tunnels: localhost port 8001 tunneled to private web server port 80, and localhost port 23 tunneled to private telnet server port 23 (right). There are two noteworthy differences here. OpenSSH allows only root to forward privileged ports and would have rejected non-root execution of 'ssh hostname -L 23:private:23'.

Click to veiw larger image
On Windows, security is relaxed. But then again, it is unusual to find such services running on a Windows 95/98 client. And with GUI clients, it is easy to forward many ports over the same SSH session.

Click to view larger image Here, we use the F-Secure SSH client (left) to connect a session to our OpenSSH server, selecting public key authentication . Unfortunately, we could not get this combo to work.As shown in the log file, there appears to be a known bug using public key authentication with this SSH client. We were successful connecting F-Secure to OpenSSH with password authentication.
And we were successful using OpenSSH public key authentication with SSH Communications and VanDyke clients. For newly-released software, we found OpenSSH 2.1 compatibility strong -- but not yet at 100 percent.

As noted earlier, protocols that use unspecified data ports are troublesome for SSH1. Passive mode FTP is a partial answer, but a better answer was created in SSH2 by defining secure FTP (sftp). F-Secure offers a "Secure FTP" application that tunnels FTP to an SSH server (right).

We tested these SSH clients to illustrate what's required for Windows client deployment and demonstrate interoperability. We didn't perform an exhaustive comparison of these three clients; each has its own strengths and weaknesses.

Click to view larger image
For a fair comparison, we'd also need to give OpenSSH and F-Secure time to work out interoperability kinks.

Bottom Line

If you're still administering *NIX servers over the Internet using rsh or telnet, stop. OpenSSH is an inexpensive improvement well worth the minimal effort required to install and configure it. If you prefer to use a commercial product, there are several to choose from. SSL provides security for web-based administration; use SSH to protect command line and xterm-based administration.

If you're thinking about creating a VPN but your requirements are limited to just a few interactive protocols, consider SSH. Using SSH to provide secure Internet access to your home-office mail server isn't difficult, and performance probably isn't an issue. But if you're looking for high-speed tunneling between sites, SSH isn't for you: go with a network-layer VPN solution optimized for that purpose. And because SSH requires login accounts, it is best used in a trusted environment: I'd let my own users tunnel through my SSH server, but I'd think twice about allowing outsiders-or customers-to do so.

Related Stories: