Secure Shell (SSH)
In Chapter 16, we discussed techniques (and considerations) for securing your Linux system. Our discussions emphasized the importance of limiting network-based exposure to your system to the bare essentials. But what if you need to perform system administrative duties remotely? How can you reap the benefits of a truly multiuser system if you can’t easily and securely log into it?
Secure Shell (SSH) was developed to tackle the issue of secure remote logins. SSH is a suite of network communication tools that are collectively based on an open protocol/standard that is guided by the Internet Engineering Task Force (IETF). It allows users to connect to a remote server just as they would using Telnet, rlogin, FTP, and so on, except that the session is 100 percent encrypted. Someone using a packet sniffer merely sees encrypted traffic going by. Should they capture the encrypted traffic, decrypting it could theoretically take a long time!
In this chapter, we take a brief and general look at cryptography concepts. Then we take a grand tour of SSH, how to get it, how to install it, and how to configure it.
Understanding Public Key Cryptography
A quick disclaimer is probably necessary before proceeding: This chapter is by no means an authority on the subject of cryptography and, as such, is not the definitive source for cryptography matters. What you will find here is a general discussion as it relates to systems administration.
Secure Shell relies on a technology called public-key cryptography. It works similarly to a safe deposit box at the bank: You need two keys to open the box or at least multiple layers of security/checks have to be crossed. In the case of public-key cryptography, you need two mathematically related keys: a public one and a private one. Your public key can be published on a public web page, printed on a T-shirt, or posted on a billboard in the busiest part of town. Anyone who asks for it can have a copy. Any data encrypted with the public key can be decrypted with the private key. On the other hand, your private key must be protected to the best of your ability. It is this piece of information that makes the data you want to encrypt truly secure. Any data signed (encrypted) with the private key can be verified (decrypted) with the public key. Every public key/private key combination is unique.
The actual process of encrypting data and sending it from one person to the next requires several steps. We’ll use the popular “Alice and Bob” analogy and go through the process one step at a time, as they both try to communicate in a secure manner with one another. Figures 23-1 through 23-41 illustrate an oversimplified version of the actual process.
Figure 23-1 Alice and Bob exchange public keys via billboard, T-shirt, or over the network.
Figure 23-2 Alice uses Bob’s public key, along with her private key, to encrypt and sign the data, respectively.
Figure 23-3 Alice sends the encrypted and signed data to Bob.
Figure 23-4 Bob uses Alice’s public key, along with his private key, to verify and decrypt the data, respectively.
Looking at these steps, you’ll notice that at no point was the secret (private) key sent over the network. Also notice that once the data was encrypted with Bob’s public key and signed with Alice’s private key, the only pair of keys that could decrypt and verify it were Bob’s private key and Alice’s public (signing) key. Thus, if someone intercepted the data in the middle of the transmission, he or she wouldn’t be able to decrypt the data without the proper private keys.
To make things even more interesting, SSH regularly changes its session key. The session key is a randomly generated, symmetric key for encrypting the communication between the SSH client and server. It is shared by the two parties in a secure manner during SSH connection setup. In this way, the data stream gets encrypted differently every few minutes. Thus, even if someone happened to figure out the key for a transmission, that miracle would be valid for only a few minutes until the keys changed again.
NOTE SSH supports a variety of encryption algorithms. Public-key encryption just happens to be one of the more interesting methods of performing end-to-end encryption, and it’s arguably the most secure!
So what exactly is a key? Essentially, a key is a large number that has special mathematical properties. Whether someone can break an encryption scheme depends on his or her ability to find out what the key is. Thus, the larger the key is, the harder it will be to discover it.
Low-grade encryption has 56 bits. This means there are 256 possible keys. To give you a sense of scale, 232 is equal to 4 billion, 248 is equal to 256 trillion, and 256 is equal to 65,536 trillion. Although this seems like a significant number of possibilities, it has been demonstrated that a loose network of PCs dedicated to iterating through every possibility could conceivably break a low-grade encryption code in less than a month.
For a key to be sufficiently difficult to break, experts usually recommended minimum key lengths. Keep in mind that every extra bit effectively doubles the number of possibilities. For example, if you really want to make the encryption solid, a key size of 2048 bits or higher is recommended for RSA type keys. Depending on the internal limitations of the key type (RSA, DSA, ECDSA, and so on), SSH can use various key lengths to encrypt your data.
The trade-off to using higher bit encryption is that it requires more math-processing power for the computer to churn through and validate a key. This takes time and, therefore, makes the authentication process a touch slower—but most people think this trade-off is worthwhile.
SSH Backstory (Versions)
The first version of SSH that was made available by DataFellows (now F-Secure) restricted free use of SSH to noncommercial activities; commercial activities required that licenses be purchased. The early closed source versions of SSH suffered from some serious security deficiencies. Some of these security issues might have been avoidable if the vendors of the software had made the source code open. This open access is especially important to cryptographic software, because it allows peers to examine the source code and make sure there are no holes that might allow hackers to easily break the security. In other words, serious cryptographers do not rely on security through obscurity. Since the U.S. government has relaxed some of its encryption laws, work on the OpenSSH project has increased and it has become a popular alternative to some of the commercial versions of the SSH protocol.
Because the SSH protocol has become an IETF standard, other developers are also actively working on SSH implementations for other operating systems. There are many Linux/UNIX clients, Microsoft Windows implementations, macOS and iOS clients, Android clients, and even a Palm client (for people who like devices from the 1820s). You can find the version of OpenSSH discussed in this chapter at www.openssh.org.
OpenSSH and OpenBSD
The OpenSSH project was spearheaded by the OpenBSD project. OpenBSD is a version of the Berkeley Software Distribution (BSD) operating system (another UNIX variant) that strives for the best security of any operating system available. A quick trip to its web site (www.openbsd.org) shows that the organization has gone over two decades with only two remote exploits in its default installation. Unfortunately, this level of fanaticism over security comes at the expense of sometimes not having the most whiz-bang-feature-rich tools available, since anything added to their distribution must get audited for security first. The nature and focus of OpenBSD has also made it a popular foundation for firewalls.
The core of the OpenSSH package is considered part of the OpenBSD project and is thus simple and specific to the OpenBSD operating system. To make OpenSSH available to other operating systems, a separate group exists to make OpenSSH portable with each new release issued. Typically, this happens quickly after the original release.
NOTE Since this book focuses on Linux-based operating systems, you will frequently see versions of OpenSSH for this platform that are suffixed with the letter p, indicating that they have been ported.
Alternative Vendors for SSH Clients
The SSH client is the client component of the SSH protocol suite. It allows users to interact with the service(s) provided by an SSH server daemon.
These days, people work within heterogeneous environments, and it’s impossible to ignore all the Windows 20**/7/8/10 and macOS systems out there. To allow these folks to work with a real operating system (Linux, of course!), there must be a mechanism in place for logging into such systems remotely. Virtually all Linux systems come with their own built-in SSH clients, and as such, there isn’t any need to worry about them; however, the non-UNIX operating systems are a different story.
Here is a quick rundown of some SSH clients and other useful SSH resources:
• PuTTY (www.chiark.greenend.org.uk/~sgtatham/putty) This is probably one of the oldest and most popular SSH implementations for the Win32 (Microsoft Windows) platforms. It is extremely lightweight and can either be used as a stand-alone, self-contained executable or be installed like other Windows programs. The web site also hosts other tools such as
pscp, which is a Windows command-line version of Secure Copy (SCP).
• OpenSSH for Apple systems macOS is actually a UNIX-based and UNIX-compliant operating system. One of its main core components—the kernel—is based on the BSD kernel. So you shouldn’t be too surprised that OpenSSH is available on macOS systems. When you open the terminal application, you can simply issue the
ssh command. macOS systems also ship with an OpenSSH SSH server.
• MindTerm, multiplatform (www.cryptzone.com) This program supports versions 1 and 2 of the SSH protocol. Written in 100 percent Java, it works on many UNIX platforms (including Linux), as well as Windows and macOS. See the web page for a complete list of tested operating systems.
• Cygwin (www.cygwin.com) This might be a bit of overkill, but it is well worth the initial effort involved with getting it set up. It is a collection of tools that provides a POSIX-compatible environment for Windows. It can be used to run numerous GNU/Linux programs without extensive changes to their source code. Under Cygwin, you can run all your favorite GNU/Linux programs, such as
rsync, OpenSSH client (
ssh), OpenSSH server (
sshd), and so on, as though you were at a traditional GNU/Linux shell.
• FileZilla (https://filezilla-project.org/) The FileZilla client is a cross-platform FTP, FTPS, and SFTP client.
• PowerShell (https://github.com/PowerShell/openssh-portable) A native port of OpenSSH to Microsoft Windows platforms via the PowerShell environment.
The Weakest Link
You’ve probably heard the saying, “Security is only as strong as your weakest link.” This saying is particularly relevant when it comes to OpenSSH and securing your network: OpenSSH is only as secure as the weakest connection between the user and the server. This means that, for example, if a user uses Telnet to connect from host A to host B and then uses
ssh to connect to host C, the entire connection can be monitored from the link between host A and host B. The fact that the link between host B and host C is encrypted becomes irrelevant. Be sure to explain these subtle points to your users.
NOTE As you make connections and use services across the Internet, you are crossing several network boundaries. Each of those providers has full rights and capabilities to sniff traffic and gather any information they want. For example, someone can easily see your e-mail as you read it. With SSH and other things being equal, you can rest assured that your connection is secure.
Installing OpenSSH on RPM-Based Systems
The easiest and quickest way to get an SSH server up and running on any RPM-based Linux system (like Fedora, CentOS, or RHEL) is to use the default package manager available on the system. It is almost guaranteed that you will already have the SSH package installed and running on most modern Linux distributions.
But, again, just in case you are running a Linux distribution that was developed on the planet Neptune but which at least has Red Hat Package Manager (RPM) installed, you can always download and install the precompiled RPM package for OpenSSH.
On our sample Fedora system, we’ll type the following to query the RPM database to make sure that OpenSSH is indeed installed:
And, if by some freak occurrence, you don’t have it already installed (or you accidentally uninstalled it), you can install an OpenSSH server using
dnf (or Yum) by issuing this command:
Installing OpenSSH via APT in Ubuntu
The Ubuntu Linux distribution usually comes with the client component of OpenSSH preinstalled, but you may sometimes have to (re)install the server component explicitly. Installing the OpenSSH server using Advanced Packaging Tool (APT) in Ubuntu is as simple as running this:
The install process will also automatically start the SSH daemon for you after installation.
You can confirm that the software is installed by running the following:
Server Startup and Shutdown
If you want users to be able to log into your system via SSH, you will need to make sure that the service is running and also make sure that the service gets started automatically between system reboots.
On modern systemd-enabled RPM-based Linux distros, use the
systemctl utility to manage the sshd service unit. First check the status of the sshd daemon by running the following:
The sample output shows the service is up and running. On the other hand, if the service is stopped, issue this command to start it:
If you are connected to the SSH server remotely, you should be very careful before stopping the service, because you run the risk of kicking yourself off the server once SSHD is stopped. But, if for some reason, you do need to stop the SSH server, type the following:
If you make configuration changes that you want to go into effect, you can restart the daemon at any time by simply running this:
On a systemd-enabled Debian-based Linux distro such as Ubuntu, you can also use
systemctl to manage the OpenSSH daemon. Note, however, that the daemon is referred to as “ssh” in this world and not “sshd” (as in the RPM world).
For example, to view the status of the OpenSSH daemon on an Ubuntu distro, type this:
To start the OpenSSH server, you would run the following:
To reload the daemon after making any configuration changes, type this:
TIP On an openSUSE distro, the command to check the status of sshd is
And to start it, the command is
SSHD Configuration File
Out of the box, most Linux systems already have the OpenSSH server configured and running with sane default settings.
On most Linux distributions, the main configuration file for sshd usually resides under the /etc/ssh/ directory and is called sshd_config. For the OpenSSH version that we installed from source earlier, the configuration file is located under the /usr/local/ssh/etc/ directory.
Next we’ll discuss some of the configuration options found in the sshd_config file:
AuthorizedKeysFile Specifies the path to the file that contains the public keys that can be used for user authentication. The default is /<
Ciphers This is a comma-separated list of ciphers allowed for the SSH protocol version 2. Examples of supported ciphers are 3des-cbc, aes256-cbc, aes256-ctr, arcfour, and blowfish-cbc.
HostKey Defines the file containing a private host key used by SSH. The default is either /etc/ssh/ssh_host_rsa_key, /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_ecdsa_key, or /etc/ssh/ssh_host_ed25519 for protocol version 2.
Port Specifies the port number on which sshd listens. The default value is
AllowTcpForwarding Specifies whether Transmission Control Protocol (TCP) forwarding is permitted. The default is
X11Forwarding Specifies whether X11 (or Xorg) forwarding is permitted. The argument must be
no. The default is
ListenAddress Specifies the local address on which the SSH daemon listens. By default, OpenSSH will listen on both Internet Protocol version 4 (IPv4) and Internet Protocol version 6 (IPv6) sockets. But if you need to specify a particular interface address, you can tweak this directive.
NOTE sshd_config is a rather odd configuration file. Unlike other Linux configuration files, out-of-the-box comments (#) in the sshd_config file denote the default values of the options that are enabled. In other words, the commented-out parameters represent defaults that are already compiled in.
OpenSSH comes with several useful programs that are covered in this section: the
ssh client program, the Secure Copy (
scp) program, and the Secure FTP (
sftp) program. The most common application you will probably use is the
ssh client program.
Secure Shell (ssh) Client Program
ssh client program can be used to securely log into a machine running an
sshd server daemon from any remote location.
By default, the
ssh client program assumes that you want to log into the remote system (destination) as the same user with which you are logged into the local system (source). However, if you need to use a different login (for instance, if you are logged in as root on one host and want to
ssh to another and log in as the user yyang), all you need to do is provide the
-l option along with the desired login. For example, if you want to log into the host server-B as the user yyang from server-A, you would type this:
Or you could use the
username@host command format, like so:
You would be prompted with a password prompt from server-B for the user yyang.
But if you just want to log into the remote host without needing to change your login at the remote end, simply run
ssh, like so:
With this command and the proper credentials, you’ll be logged in as the master user at server-B.
Of course, you can always replace the hostname with a valid IP address, like this:
To connect to a remote SSH server that is also listening on an IPv6 address (for example, 2001:DB8::2), you could try the following:
TIP If you don’t have a remote server to test your ssh/scp/sftp connections, you can easily switch all references to
localhost. Similarly, you can also switch all references to remote IP addresses from 192.168.1.50 to the loopback IP address of 127.0.0.1. Note that both
localhost and 127.0.0.1 refer to your local system.
Creating a Secure Tunnel
This section covers what is commonly called the “poor man’s virtual private network” (VPN). Essentially, you can use SSH to create a tunnel from your local system to a remote system. This is a handy feature when you need to access an intranet or another system that is not exposed to the outside world on your intranet. For example, you can
ssh to a file server that will set up the port forwarding to the remote web server.
Let’s imagine a scenario like the one described next with the following components:
• Inside The inside component consists of the entire local area network, or LAN (the 192.168.1.0 network). It houses various servers and workstations that are accessible only by other hosts on the inside. Let’s assume that one of the internal servers on the LAN hosts a web-based accounting application. The internal web server’s hostname is “accounts,” with an IP address of 192.168.1.100.
• Middle In the middle, we have our main component—a system with two network interfaces. The system’s hostname is serverA. One of the interfaces is connected directly to the Internet. The other interface is connected to the company LAN.
On serverA, assume the first interface (the wide area network, or WAN, interface) has a public/routable-type IP address of 126.96.36.199 and the second interface has a private-type IP address of 192.168.1.1. The second interface of serverA is connected to the LAN (the 192.168.1.0 network), which is completely cut off from the Internet.
The only service that is allowed and running on the WAN interface of serverA is the sshd daemon. ServerA is said to be “dual-homed” because it is connected to two different networks: the LAN and the WAN.
• Outside Our remote user, yyang, needs to access the web-based accounting application running on the internal server (accounts) from home. User yyang’s home workstation hostname is hostA. Yyang’s home system is considered to be connecting via a hostile public Internet. HostA has an SSH client program installed.
We already said the entire internal company network (LAN, accounts server, other internal hosts, and so on) is cut off from the Internet and the home system (hostA) is part of the public Internet, so what gives? The setup is illustrated in Figure 23-5.
Figure 23-5 Port forwarding with SSH
Enter the poor man’s VPN (aka SSH tunneling). The user yyang will set up an SSH tunnel to the web server running on “accounts” by following these steps:
1. While sitting in front of her home system (hostA), the user yyang will log into the home system as herself.
2. Once logged in locally, she will create a tunnel from port 9000 on the local system to port 80 on the system (named accounts) running the web-based accounting software.
3. To do this, yyang will connect via SSH to serverA’s WAN interface (188.8.131.52) by issuing this command from her system at home (hostA):
NOTE The complete syntax and meaning of the port-forwarding command is
ssh -L local_port:destination_host:destination_port ssh_server, where
local_port is the local port you will connect to after the tunnel is set up,
destination_host:destination_port is the host:port pair where the tunnel will be directed, and
ssh_server is the host that will perform the forwarding to the end host.
4. After yyang successfully authenticates herself to serverA and has logged into her account on serverA, she can then launch a web browser installed on her workstation (hostA).
5. User yyang can use a web browser to access the forwarded port (9000) on the local system. For this example, she needs to type the Uniform Resource Locator (URL) http://localhost:9000 into the address field of the browser.
6. If all goes well, the web content being hosted on the accounting server should show up on yyang’s web browser—just as if she were accessing the site from within the local office LAN (that is, the 192.168.1.0 network).
7. To close down the tunnel, she simply closes all windows that are accessing the tunnel and then ends the SSH connection to serverA by typing exit at the prompt.
The secure tunnel affords you secure access to other systems or resources within an intranet or a remote location. It is a great and inexpensive way to create a virtual private network between your host and another host. It is not a full-featured VPN solution, since you can’t easily access every host on the remote network, but it gets the job done.
In this demo, we port-forwarded HTTP traffic. You can tunnel almost any protocol, such as Virtual Network Computing (VNC) or Remote Desktop Protocol (RDP). Note that this is a way for people inside a firewall or proxy to bypass the firewall mechanisms and get to computers on the outside world. The ProxyJump and SOCKS Proxy features of OpenSSH are alternative methods of transparently traversing firewalls or other barriers to connect to other hosts/resources.
Secure Copy (scp) Program
Secure Copy (
scp) is used for securely copying data from one host to another remote host. The format and usage of
scp is very simple—you only need to know the source and the destination.
Suppose user yyang, for example, is logged into her home workstation (client-A) and wants to copy a file named .bashrc located in the local home directory to her home directory on server-A. Here’s the command:
If she wants to copy the other way—that is, from the remote system server-A to her local system client-A—the arguments need to be reversed, like so:
Secure FTP (sftp) Program
Secure FTP is a subsystem of the sshd daemon. You access the Secure FTP server by using the
sftp command-line tool. To
sftp from a system named client-A to an SFTP server running on server-A as the user yyang, type this:
You will then be prompted for your password (similar to a regular ssh session). Once you have been authenticated, you will see a prompt like the following:
You can issue various
sftp commands while at the sftp shell. For example, to list all the files and directories under the /tmp folder on the sftp server, you can use the
For a listing of all the commands, just type a question mark (?):
Notice that some of the commands look strikingly similar to the FTP commands discussed in Chapter 18. Among other things,
sftp is handy if you forget the full name of a file you are looking for, because you can browse the remote file system using familiar FTP commands.
Files Used by the OpenSSH Client
The configuration files for the SSH client and SSH server typically reside in the directory /etc/ssh/ on most Linux distributions. (If you installed SSH from source into /usr/local/ssh/, the full path will be /usr/local/ssh/etc/.) If you want to make any system-wide changes to defaults for the SSH client, you need to modify the /etc/ssh/ssh_config file or its equivalent.
CAUTION Remember that the sshd_config file is for the server daemon, while the ssh_config file is for the SSH client! Note the letter d for daemon in the server configuration filename.
Within a user’s home directory, SSH-related data is stored in the ~username/.ssh/ directory. The file known_hosts stores host key information and is used to guard against man-in-the-middle attacks. SSH will alert you when remote host keys change. If the keys have changed for a valid reason—for instance, if the server was reinstalled—you will need to edit the known_hosts file and delete the line referencing the (now incorrect) identity of the changed server.
The Secure Shell is the de-facto protocol for enabling secure remote logins for performing system administration tasks and everyday use on Linux and UNIX-like systems. Even Microsoft Windows systems have fully jumped on board and now have their own native SSH implementations! When properly implemented and used, SSH can help to provide confidentiality and integrity of data when used for communications or data transfers on untrusted networks like the Internet.
In closing, remember that using OpenSSH alone doesn’t make your system magically and automatically secure. There is no replacement for a set of good security practices. Following the lessons from Chapter 16, you should disable all unnecessary services on any system exposed to untrusted networks.