Confidentiality
A secret is a piece of information known only to one or more persons—that is, something kept hidden from others or known only to oneself or to a few other people. To ensure secrecy, the data is encoded in a form that can be decoded only by the intended persons. Cryptology is the field of study underlying the development of new methods of encoding secrets (cryptology), and inverse methods to break those techniques (cryptanalysis). Cryptography involves the design of new ciphers and enhancement of existing ciphers, which are algorithms that convert the source data (plaintext) into a secret (ciphertext). The encoding process is known as encryption, and the decoding process is called decryption. A large integer, known as a key, is central to the encryption and decryption process—and, depending on the algorithm, a different key may be used for encryption and decryption. Algorithms that use only a single key for encryption and decryption are called symmetric, while algorithms that use two separate keys are known as asymmetric.
An individual user usually wants to encrypt their own data and ensure secrecy from everyone else, in which case a symmetric algorithm typically suffices. The drawback for sharing data secretly with multiple users is that once the key is known to one unauthorized user, then all users' data is compromised. This is where asymmetric algorithms come into play—the encoding key can be compromised, but the data will still be protected unless the decoding key is known to an attacker, because the decoding key cannot be derived from the encoding key.
Given that much data in defense, commerce, and government spheres must be kept secret, it's little surprise that cryptography is what most lay people associate with security. However, as you've seen from the other requirements of security in this chapter, secrecy is only one part of the overall equation—if data is inauthentic, inaccurate, and lacks integrity, then there's little point in keeping it secret.
This section examines basic aspects of how both symmetric and asymmetric cryptography are used in modern applications to ensure secrecy of data.
Symmetric Key Cryptography
In UNIX, a simple symmetric key encryption system is made available through the crypt command. crypt takes a passphrase entered on the command line and uses it to encrypt plaintext from standard input. The plaintext is passed through a stream cipher, and crypt then sends the ciphertext to standard output.
Consider a simple example. Imagine that a list of secret agents' names is stored in a flat-file database called agents.txt. To protect these identities, you need to encrypt the data and store the ciphertext in a file called agents.crypt. You also need to select an appropriate passphrase in order to protect the data—in this case, use a random string of78hg65df. Thus, to encrypt the file, you would use the following command:
% crypt 78hg65df < agents.txt > agents.crypt; rm agents.txt
Since the contents of agents.crypt would contain binary data, you could view the ciphertext using the following command:
% strings agents.crypt 8rgj5kg_-90fg++fg8ijrfssfjghkdfmvv 8dg0gf90ggd,rkf8b8fdk234,k_+_7gfsg …
To decrypt the ciphertext, and recover the plaintext, the crypt command can also be used. The passphrase 78hg65df will need to be supplied. If the passphrase is lost, then the data is not recoverable—unless brute-force cracking is attempted.
It looks like crypt solves all of your secrecy problems, but actually there are several problems with this simple scenario. The first problem is that when the crypt command is executed, the passphrase appears in the clear in the process list, making it visible to any user who is scanning the list on a regular basis for the token "crypt". A cracker might be able to determine the average file size on the system and the average time it takes to encrypt that file size under an average system load. If average encryption time for an average file is ten minutes, then a simple cron using the command ps –eaf | grep crypt would intercept many of the crypt invocations. These could be e-mailed to the attacker when detected, thereby bypassing the secrecy measures implemented.
The second problem with the preceding simple example is that the cipher used by the crypt program is much less secure than current standards, making it susceptible to brute-force cracking attacks. Other symmetric key ciphers that could be used include the 56-bit Data Encryption Standard (DES). A modified DES variant known as triple-DES encrypts the plaintext, then further encrypts this first ciphertext, and again encrypts the second ciphertext to yield a third and final ciphertext. Clearly, this is more secure than one pass—but the success of cryptanalytic attacks depends on the size of the keys involved, and also on the nature of the plaintext. Many attacks are based on the fact that in natural language, there are differences in character and word frequency—so the word "the" appears in natural language much more frequently than "hippopotamus." Also, knowing even a small section of the plaintext can assist in cryptanalysis. Imagine if every company invoice was encrypted—the company's name would appear on every invoice and would provide an excellent starting point for examining commonalities between the ciphertext of all invoices.
If data is only available for a short period of time, and just needs to be scrambled, then a compression algorithm may be utilized. These make use of the redundancies previously described to recode the plaintext into a compressed text. By inspection, the compressed text appears to be ciphertext. There is much interest in combining compression and cryptography where data security is required, in applications where bandwidth is limited. For example, studio-quality video streaming should be encrypted between sender and receiver, but should be compressed as much as possible without sacrificing quality to minimize bandwidth use.
Asymmetric Key Cryptography
One major limitation of symmetric key cryptography is that the same key is required to encrypt and decrypt data. This is fine for protecting individual files from unauthorized users, but many data-protection scenarios require multiple users to interact with each other, when trust has never been established. For example, if a manager in New York needs to exchange sales data with a manager in Buffalo, and this data requires encryption, both managers could simply share the key required to decrypt the data. However, this approach has two problems. First, users tend to apply the same password and key to multiple purposes, meaning that one manager might be able to access the other manager's files; second, what if more than two managers were involved? Clearly, passing a password around a user group of 1,000 users is tantamount to having no security at all! A system is required that allows individual users to encrypt data using one key, and for the file to be decrypted using a separate key for each user.
Asymmetric encryption allows separate keys to be used for encrypting and decrypting data. How is this possible? Basically, every user is assigned a private key, which they never release to anyone else, and a public key, which is supplied to other users who need to send the user encrypted data. For example, the New York manager would have a private key stored on a floppy disk, locked in a safe, as would the Buffalo manager. Both would also exchange their public keys via e-mail, or another offline method such as floppy disk, verifying that the keys were genuine by using a key "fingerprints" check over the telephone. To encrypt a file for the Buffalo manager, the New York manager would need to use both his/her own private key and the Buffalo manager's public key. Conversely, the Buffalo manager would need to use her private key and the New York manager's public key to encrypt a file for him. Remember that if you exchange public keys via e-mail, and have no other method of verifying who is on the other end of the line, then you're ripe for a "man in the middle attack," because the person you think you are exchanging data with could be an intermediary. For example, imagine if Joe substitutes his key in place of his manager's, and manages to place his machine between a manager's machine and an external router. Now Joe is able to pretend to be his manager, issuing his own public key with his manager's name for which he actually has the corresponding private key.
The most important feature (or limitation, depending on your requirements) of asymmetric key cryptography is that obtaining the private key used to encrypt data is not sufficient to decrypt that data: only the private key of the individual whose public key was used for signing can be used for this purpose. This can be very important in situations where data may be compromised in a specific location. For example, an embassy in a foreign country under threat of attack may decide to encrypt all data by using the public key of an officer in the State Department in Washington, send it via e-mail, and then delete the on-site originals. Even if the encrypted data and the embassy's private key were obtained by force, they could not be used to decrypt the data.
Of course, asymmetry implies that if you lose your original data accidentally, you must rely on the public key holder's private key to decrypt the data. However, at least one avenue of recourse is available, unlike when using symmetric key cryptography, where a lost key almost certainly means lost data.
Public Key Cryptography
One of the most commonly used public key systems that uses asymmetric keys is the Pretty Good Privacy (PGP) application (http://www.pgp.com/). PGP is available for a wide variety of operating systems, making it very popular among PC and UNIX users, because data can be exchanged without conversion. PGP works both on the command line, to facilitate secure storage of files, and as a plug-in to e-mail programs, allowing messages to be exchanged securely. This ensures that intermediate mail servers and routers cannot intercept the decrypted contents of transmitted messages, even if they can intercept packets containing the encrypted data.
To use PGP, each user needs to generate their own public/private key pair. This can be performed by using the following command:
$ pgp -kg
The following prompt will be displayed:
Choose the type of your public key: 1) DSS/Diffie-Hellman - New algorithm for 5.0 (default) 2) RSA Choose 1 or 2:
The public key format that you choose will determine what types of block ciphers can be used to encrypt your data. The DSS/Diffie-Hellman algorithm allows Triple DES, CAST, or IDEA, while RSA keys work only with IDEA, so most users will want to select the DSS/Diffie-Hellman algorithm.
Next, you need to select the key size:
Pick your public/private keypair key size: (Sizes are Diffie-Hellman/DSS; Read the user's guide for more information) 1) 768/768 bits- Commercial grade, probably not currently breakable 2) 1024/1024 bits- High commercial grade, secure for many years 3) 2048/1024 bits- "Military" grade, secure for foreseeable future(default) 4) 3072/1024 bits- Archival grade, slow, highest security Choose 1, 2, 3 or 4, or enter desired number of Diffie-Hellman bits (768 - 4096):
Keep in mind that although a large key provides greater security, it also slows down operations significantly because it is CPU-intensive. Thus, if your needs are commercial rather than military, you should use the 768- or 1024-bit key. Military users should certainly select the largest key size available (currently 4096 bits).
Next, you need to enter a user ID. This should be recognizable by your intended recipients. For example, a programmer called Yayoi Rei from Rei Corporation would have a user ID of Yayoi Rei <yayoi@rei.com>. Even in countries in which the family name is usually written first, the expectation for the key server is that the family name will appear last, followed by an e-mail address:
You need a user ID for your public key. The desired form for this user ID is your FULL name, followed by your E-mail address enclosed in <angle brackets>, if you have an E-mail address. For example: Joe Smith <user@domain.com> Enter a user ID for your public key:
If you wish your key to be valid for a specific time period, you can enter its period of validity in days next; or if the key is intended to be permanent, you can enter zero days:
Enter the validity period of your key in days from 0 - 999 0 is forever (and the default):
You need a password to be associated with the private key for future use, and you will need to enter it twice for verification:
You need a pass phrase to protect your private key(s). Your pass phrase can be any sentence or phrase and may have many words, spaces, punctuation, or any other printable characters. Enter pass phrase: Enter again, for confirmation:
Finally, a number of random numbers needs to be generated from the intervals between random key presses on your keyboard. Try to insert some variation in the key press latency to ensure security:
We need to generate 595 random bits. This is done by measuring the time intervals between your keystrokes. Please enter some random text on your keyboard until you hear the beep:
Once the keypair has been created, you can list all the keys on your local keyring by using the following command:
$ pgp -kl Type Bits KeyID Created Expires Algorithm Use sec+ 768 0x71849810 2002-01-07 ————— DSS Sign & Encrypt sub 768 0x78697B9D 2002-01-07 ————— Diffie-Hellman uid Yayoi Rei <yayoi@rei.com> 1 matching key found
The keypair is now available for use. To generate a copy of your public key for your correspondents and colleagues to use, you need to extract this from your keyring as follows:
$pgp -x Yayoi ——-BEGIN PGP PUBLIC KEY BLOCK——- mQFCBDw5+oURAwDBKeBtW+0PdDvCC7KO1/gUAF9X//uGRhbPkg6m83QzaA7pr6T+ QAVQE4q74NXFCakX8GzmhzHtA2/Hoe/yfpfHGHMhJRZHZIWQWTS6W+r5wHYRSObm NNNTeJ4C+3/klbEAoP/Mjlim4eMkfvYwNmifTUvak5zRAv48SrXOHmVI+5Mukx8Z lT7txut60VeYd34QvidwtUbbL7p2IVVa3fGW/gsuo7whb1aW//+5Z/+4wxbaqnu6 WxT5vFObm1sJ7E20OW3SDLxdVjeTlYbzTUfNwbN/KHoUzMsC/2EZ3aDB6mGZuDPL 0SMT8sOoxlbpPouuBxnF/sbcxgOVKkGZDS5XrhodUbp2RUflwFSMyqjbmoqITnNq xzpSXEhT0odwjjq3YeHj1icBaiy9xB/j0CBXe3QQKAXk5bXMEbQZWWF5b2kgUmVp IDx5YXlvaUByZWkuY29tPokASwQQEQIACwUCPDn6hQQLAwECAAoJEHCOVqNxhJgQ riMAn18a5kKYaepNk8BEksMJOTbRgDQmAKC0JD6wvYfo5zmziGr7TAv+uFWN5LkA zQQ8OfqHEAMA6zd3dxeMkyKJmust3S3IrKvQzMLlMoRuQdb+N2momBYDF1+slo8k EMK8F/Vrun+HdhJW+hWivgZRhTMe9fm6OL7PDYESkwuQsMizqAJJ1JF0yhbfTwE5 GjdVPcUMyPyTAAICAwCgdBO1XyiPbwdQtjxq+8CZ7uchASvJXsU28OFqbLzNcAW2 Q64lWSs6qr2HNfgf+ikG8S8eVWVKEBgm6md9trr6CK25SYEu4oB3o1f45X4daa/n iNytKUglPPOJMK/rhJOJAD8DBRg8OfqHcI5Wo3GEmBARAs3mAJ0ZPQjmlYyNsMDY ZVbR9/q2xQl8gACgkqVCNYR40mPIaxrd5Cw9ZrHqlkQ= =Gsmt ——-END PGP PUBLIC KEY BLOCK——-
To encrypt a file using standard, symmetric encryption, you simply pass the –c option on the command line along with the name of the file that you want to encrypt. This provides Solaris users with an alternative to crypt, where a more secure encryption algorithm is desired.
$ pgp -c secret.doc You need a passphrase to encrypt the file Enter pass phrase: Enter same passphrase again Enter pass phrase: Creating output file secret.pgp
After entering a password to protect the data in secret.doc, the encrypted file secret.pgp is created. In order to sign the file for another user, you need to pass the –e option, along with the name of the user from your keyring who will have the power to decrypt your data:
$ pgp -e Henry secret.doc 4096 bits, Key ID 76857743, Created 2002-01-07 "Henry Bolingbroke <henry@bolingbroke.co.uk>" Creating output file secret.pgp
The file can then be transmitted to Henry by uuencoding it, by sending it as an e-mail attachment, or by directly generating the file in ASCII format:
$ pgp -ea Henry secret.doc
Disabling IP Ports
The first step in network security is to prevent unauthorized entry by disabling access to specific IP ports, as defined by individual entries in the services database. This action prevents specific services from operating, even if the inetd attempts to accept a connection for a service because it is still defined in /etc/inetd.conf. This section examines how to disable specific services from inetd, in conjunction with the services database. It's also important to shut down unnecessary services outside of inetd, such as disabling startup scripts, as discussed in Chapter 4.
The following services are typically enabled in /etc/services and configured in /etc/inetd.conf. Most sites will want to disable them and install more secure equivalents. For example, the ftp and telnet services may be replaced by the encrypted secure copy (scp) and secure shell (ssh) programs, respectively. To disable the ftp, telnet,shell, login, exec, comsat, talk, uucp, and finger services, you would comment out their entries in /etc/inetd.conf by inserting a hash character (#) at the first character position of the line that defines the service. The following configuration enables the ftp, telnet, shell, login, exec, comsat, talk, uucp, and fingerservices in /etc/inetd.conf:
ftp stream tcp nowait root /usr/sbin/in.ftpd in.ftpd -l telnet stream tcp nowait root /usr/sbin/in.telnetd in.telnetd shell stream tcp nowait root /usr/sbin/in.rshd in.rshd login stream tcp nowait root /usr/sbin/in.rlogind in.rlogind exec stream tcp nowait root /usr/sbin/in.rexecd in.rexecd comsat dgram udp wait root /usr/sbin/in.comsat in.comsat talk dgram udp wait root /usr/sbin/in.talkd in.talkd uucp stream tcp nowait root /usr/sbin/in.uucpd in.uucpd finger stream tcp nowait nobody /usr/sbin/in.fingerd in.fingerd
The following configuration disables the ftp, telnet, shell, login, exec, comsat, talk, uucp, and finger services in /etc/inetd.conf:
#ftp stream tcp nowait root /usr/sbin/in.ftpd in.ftpd -l #telnet stream tcp nowait root /usr/sbin/in.telnetd in.telnetd #shell stream tcp nowait root /usr/sbin/in.rshd in.rshd #login stream tcp nowait root /usr/sbin/in.rlogind in.rlogind #exec stream tcp nowait root /usr/sbin/in.rexecd in.rexecd #comsat dgram udp wait root /usr/sbin/in.comsat in.comsat #talk dgram udp wait root /usr/sbin/in.talkd in.talkd #uucp stream tcp nowait root /usr/sbin/in.uucpd in.uucpd #finger stream tcp nowait nobody /usr/sbin/in.fingerd in.fingerd
Similarly, the following configuration enables the ftp, telnet, shell, login, exec, comsat, talk, uucp, and finger services in /etc/services:
ftp 21/tcp telnet 23/tcp shell 514/tcp cmd login 513/tcp exec 512/tcp biff 512/udp comsat talk 517/udp uucp 540/tcp uucpd finger stream tcp nowait nobody /usr/sbin/in.fingerd in.fingerd
Similarly, the following configuration disables the ftp, telnet, shell, login, exec, comsat, talk, uucp, and finger services in /etc/services:
#ftp 21/tcp #telnet 23/tcp #shell 514/tcp cmd #login 513/tcp #exec 512/tcp #biff 512/udp comsat #talk 517/udp #uucp 540/tcp uucpd #finger stream tcp nowait nobody /usr/sbin/in.fingerd in.fingerd
Don't forget that you need to HUP the inetd daemon for these changes to be enabled.
Checking User and Group Identification
The concept of the user is central to Solaris—all processes and files on a Solaris system are "owned" by a particular user and are assigned to a specific user group. No data or activities on the system may exist without first establishing a valid user or group. Managing users and groups as a Solaris administrator can be a challenging activity— you will be responsible for assigning all the privileges granted or denied to a user or group of users, and many of these permissions carry great risk. For example, a user with an inappropriate privilege level may execute inappropriate commands as the superuser, causing damage to your system.
You can determine which user is currently logged in from a terminal session by using the id command:
$ id uid=1001(natashia) gid=10(dialup)
The output shows that the currently logged-in user is natashia, with UID=1001. In addition, the current group of natashia is a dialup group with GID=10. It is possible for the user and group credentials to change during a single terminal session. For example, if the su facility is used effectively to "become" the superuser, the UID and GID associated with the current terminal session will also change:
$ su root Password: # id uid=0(root) gid=1(other)
Here, the root user (UID=0) belonging to the group other (GID=1) has spawned a new shell with full superuser privileges.
You can obtain a list of all groups that a user belongs to by using the groups command. For example, to view all the groups that the root user belongs to, use the following command:
# groups root other root bin sys adm uucp mail tty lp nuucp daemon
Protecting the Superuser Account
You've just examined how to use the su facility to invoke superuser privileges from an unprivileged account. The user with UID=0 (typically the root user) has unlimited powers to act on a Solaris system. The root user can perform the following potentially dangerous functions:
- Add, delete, or modify all other user accounts
- Read and write all files, and create new ones
- Add or delete devices to the system
- Install new system software
- Read everyone's e-mail
- Snoop network traffic for usernames and passwords of other systems on the LAN
- Modify all system logs to remove all traces of superuser access
- Pretend to be an unprivileged user and access their accounts on other systems where login access is authenticated against a username
These powers combine to make the root account sound rather sinister: however, many of these activities are legitimate and necessary system administration routines that are undertaken daily. For example, network traffic can be snooped to determine where network outages are occurring, and copying user files to backup tapes every night is generally in everyone's best interest. However, if an intruder gains root access, they are free to roam the system, deleting or stealing data, removing or adding user accounts, or installing Trojan horses that can transparently modify the way that your system operates.
One way to protect against an authorized user gaining root access is to use a hard-to-guess root password. This makes it difficult for a cracker to use a password-cracking program to guess your password successfully. The optimal password is a completely random string of alphanumeric and punctuation characters.
In addition, the root password should never be written down unless it is locked in the company safe, nor should it be told to anyone who doesn't need to know it. The root password must usually be entered twice—just in case you should happen to make a typographical error, as the characters that you type are masked on the screen.
The root user should never be able to log in using Telnet: instead, the su facility should be used by individual users to gain root privileges where necessary. This protects the root account, since at least one other password is required to log in, unless the root user has access to the console. In addition, the su command should be owned by a sysadmin group (or similar) so that only those users who need access to the root account should be able to obtain it. Once su has been used to gain root access, the root user can use su to spawn a shell with the effective ID of any other user on the system. This is a security weakness, because the root user could pretend to be another user and perform actions or modify data which is traceable to the effective user, and not root.
A more practical and secure solution in a large Solaris environment is to use solutions such as one-time passwords or a mechanism that employs two-factor authentication such as SecurID. It's also very important to check for obvious flaws in the content of the password and group files, such as empty passwords or group affiliations, which should always be checked and fixed.
Monitoring User Activity
System access can be monitored interactively using a number of measures. For example, syslog entries can be automatically viewed in real time using this command:
$ tail -f /var/adm/messages
However, most administrators want to view interactively what remote users are doing on a system at any time. This section examines two methods for viewing remote- user activity. The command who displays who is currently logged into the system. The output of who displays the username, connecting line, date of login, idle time, process ID, and a comment. Here's an example output:
$ who root console Nov 22 12:39 natashia pts/0 Nov 19 21:05 (client.site.com)
This command can be automated to update the list of active users. An alternative to who is the w command, which displays a more detailed summary of the current activity on the system, including the current process name for each user. The header output from w shows the current time, the uptime of the current system, and the number of users actively logged into the system. The average system load is also displayed as a series of three numbers at the end of the w header, indicating the average number of jobs in the run queue for the previous 1, 5, and 15 minutes. In addition to the output generated by who, the w command displays the current foreground process for each user, which is usually a shell. For example, the following command shows that the root user has an active perl process, while the user natashia is running the Cornell shell:
7:15pm up 1 day(s), 5:11, 2 users, load average: 1.00, 1.00, 1.01 User tty login@ idle JCPU PCPU what root console Thu12pm 3days 6 6 perl natashia pts/12 Thu11am 8:45 9 /usr/local/bin/tcsh
The w and who commands are useful tools for getting an overview of current usage patterns on any Solaris system. Another useful command is last, which displays historical usage patterns for the current system in a sequential format:
$ last natashia pts/4 hp Wed Apr 11 19:00 still logged in root console :0 Tue Apr 10 20:11 still logged in natashia pts/2 nec Tue Apr 10 19:17 - 19:24 (00:06) natashia pts/6 austin Tue Apr 10 15:53 - 15:53 (00:00) root console :0 Tue Apr 10 14:24 - 16:25 (02:01) reboot system boot Tue Apr 10 14:04 natashia pts/5 hp Thu Apr 5 21:38 - 21:40 (00:01) natashia pts/5 hp Thu Apr 5 21:22 - 21:37 (00:15) natashia pts/5 10.64.18.1 Thu Apr 5 19:30 - 20:00 (00:30) natashia pts/5 hp Thu Apr 5 19:18 - 19:29 (00:11) root console :0 Thu Apr 5 19:17 - 22:05 (4+02:48) reboot system boot Thu Apr 5 19:14 natashia pts/5 hp Tue Apr 3 16:14 - 18:26 (02:11) natashia pts/5 hp Tue Apr 3 08:48 - 10:35 (01:47) root console :0 Tue Apr 3 08:45 - 22:01 (13:15) reboot system boot Tue Apr 3 08:43 root console :0 Fri Mar 30 18:54 - 19:27 (00:32) reboot system boot Fri Mar 30 18:46 natashia pts/6 hp Tue Mar 27 20:46 - 21:51 (01:04) root console :0 Tue Mar 27 19:50 - 21:51 (02:01) reboot system boot Tue Mar 27 19:48 root console :0 Mon Mar 26 17:43 - 17:47 (00:04)
Securing Remote Access
Remote access is the hallmark of modern multiple-user operating systems such as Solaris and its antecedents, such as VAX/VMS. Solaris users can concurrently log into and interactively execute commands on Solaris server systems from any client that supports Transmission Control Protocol/Internet Protocol (TCP/IP), such as Solaris, Windows, and Macintosh OS.
This section examines several historically popular methods of remote access, such as Telnet. It also outlines the much-publicized security holes and bugs that have led to the innovation of secure remote-access systems, such as SSH. These "safer" systems facilitate the encryption of the contents of user sessions and/or authentication sequences and provide an important level of protection for sensitive data. Although remote access is useful, the administrative overhead in securing a Solaris system can be significant, reflecting the increased functionality that remote-access services provide.
Telnet
Telnet is the standard remote-access tool for logging into a Solaris machine from a client using the original DARPA Telnet protocol. A client can be executed on most operating systems that support TCP/IP. Alternatively, a Java Telnet client is available (http://srp.stanford.edu/binaries.html), which is supported on any operating system that has a browser that runs Java natively or as a plug-in. Telnet is a terminal-like program that gives users interactive access to a login shell of their choice (for example, the C-shell, or csh). Most Telnet clients support VT100 or VT220 terminal emulations. The login shell can be used to execute scripts, develop applications, and read e-mail and news—in short, everything a Solaris environment should provide to its users, with the exception of X11 graphics and Open Windows, and, more recently, the common desktop environment (CDE). A common arrangement in many organizations is for a Solaris server to be located in a secure area of a building with Telnet-only access allowed. This arrangement is shown in Figure 9-1.
The sequence of events that occurs during a Telnet session begins with a request for a connection from the client to the server. The server either responds (or times out) with a connection being explicitly accepted or rejected. A rejection may occur because the port that normally accepts Telnet client connections on the server has been blocked by a packet filter or firewall. If the connection is accepted, the client is asked to enter a username followed by a password. If the username and password combination is valid, a shell is spawned, and the user is logged in. This sequence of events is shown in Figure 9-2.
The standard port for Telnet connections is 23. Thus, a command like this,
$ telnet server
is expanded to give the effective command:
$ telnet server 23
This means that Telnet can be used as a tool to access a service on virtually any port. Telnet is controlled by the super Internet daemon (inetd), which invokes the in.telnetdserver. An entry is made in /etc/services that defines the port number for the Telnet service, which looks like this:
telnet 23/tcp
The configuration file /etc/inetd.conf also contains important details of the services provided by inetd. The telnet daemon's location and properties are identified here:
In this case, you can see that in.telnetd is protected by the use of TCP wrappers, which facilitate the logging of Telnet accesses through the Solaris syslog facility. In addition,inetd has some significant historical security holes and performance issues that, although mostly fixed in recent years, have caused administrators to shy away from servers invoked by inetd. The Apache Web server (http://www.apache.org), for example, runs as a standalone daemon process and does not use inetd.
inetd also controls many other standard remote-access clients, including the so-called r-commands, including the remote login (rlogin) and remote shell (rsh) applications. The rlogin application is similar to Telnet in that it establishes a remote connection through TCP/IP to a server, spawning an interactive login shell. For example, the command
$ rlogin server
by default produces the response
password:
after which the password is entered, the password is authenticated by the server, and access is denied or granted. If the target user account has a different name than your current user account, you can try this:
$ rlogin server –l user
There are two main differences between Telnet and rlogin, however, which are significant. The first is that rlogin attempts to use the username on your current system as the account name to connect to on the remote service, whereas Telnet always prompts for a separate username. This makes remotely logging into machines on a single logical network with rlogin much faster than with Telnet. Second, on a trusted, secure network, it is possible to set up a remote authentication mechanism by which the remote host allows a direct, no-username/no-password login from authorized clients. This automated authentication can be performed on a system-wide level by defining an "equivalent" host for authentication purposes on the server in /etc/hosts.equiv, or on a user-by-user basis with the file .rhosts. If the file /etc/hosts.equiv contains the client machine name and your username, you will be permitted to automatically execute a remote login. For example, if the /etc/hosts.equiv file on the server contains this line,
client
any user from the machine client may log into a corresponding account on the server without entering a username and password. Similarly, if your username and client machine name appear in the .rhosts file in the home directory of the user with the same name on the server, you will also be permitted to remotely log in without an identification/ authentication challenge. This means that a user on the remote system may log in with all the privileges of the user on the local system, without being asked to enter a username or password—clearly a dangerous security risk. The sequence of identification and authentication for rlogin is shown in Figure 9-3.
Remote-shell (rsh) connects to a specified hostname and executes a command. rsh is equivalent to rlogin when no command arguments are specified. rsh copies its standard input to the remote command, the standard output of the remote command to its standard output, and the standard error of the remote command to its standard error. Interrupt, quit, and terminate signals are propagated to the remote command. In contrast to commands issued interactively through rlogin, rsh normally terminates when the remote command does.
As an example, the following command executes the command df –k on the server, returning information about disk slices and creating the local file server.df.txt that contains the output of the command:
$ rsh server df -k > server.df.txt
Clearly, rsh has the potential to be useful in scripts and automated command processing.
Vulnerabilities
One of the unfortunate drawbacks of the Telnet system is that usernames and, especially, unencrypted passwords are transmitted in cleartext around the network. Thus, if you were using a Telnet client to connect from a cyber café in Paris to a server in New York, your traffic might pass through 20 or 30 routers and computers, all of which can be programmed to "sniff" the contents of network packets. A sample traceroute of the path taken by packets from AT&T to Sun's Web page looks like this:
$ traceroute www.sun.com Tracing route to wwwwseast.usec.sun.com [192.9.49.30] over a maximum of 30 hops: 1 184 ms 142 ms 138 ms 202.10.4.131 2 147 ms 144 ms 138 ms 202.10.4.129 3 150 ms 142 ms 144 ms 202.10.1.73 4 150 ms 144 ms 141 ms ia4.optus.net.au [202.139.32.17] 5 148 ms 143 ms 139 ms 202.139.1.197 6 490 ms 489 ms 474 ms sf1.optus.net.au [192.65.89.246] 7 526 ms 480 ms 485 ms gn.cwix.net [207.124.109.57] 8 494 ms 482 ms 485 ms core7.SanFrancisco.cw.net [204.70.10.9] 9 483 ms 489 ms 484 ms core2.SanFrancisco.cw.net [204.70.9.132] 10 557 ms 552 ms 561 ms xcore3.Boston.cw.net [204.70.150.81] 11 566 ms 572 ms 554 ms sun.Boston.cw.net [204.70.179.102] 12 577 ms 574 ms 558 ms wwwwseast.usec.sun.com [192.9.49.30] Trace complete.
That's a lot of intermediate hosts, any of which could potentially be sniffing passwords and other sensitive data. If the network packet that contains the username and password is sniffed in this way, a rogue user could easily log into the target account using a Telnet client. This risk has led to the development of SSH and similar products that encrypt the exchange of username and password information between client and server, making it difficult for sniffers to extract useful information from network packets. OpenSSH, an open source version of SSH, is now supplied with Solaris.
Although rlogin is the fastest kind of remote login possible, it can be easily exploited on systems that are not trusted and secure. Systems that are directly connected to the Internet, or those that form part of a subnet that is not firewalled, should never be considered secure. These kinds of configurations can be dangerous in some circumstances, even if they are convenient for remotely administering many different machines.
The most dangerous use of /etc/hosts.equiv occurs, for example, when the file contains the single line
+
The .rhosts file is also considered dangerous in some situations. For example, it is common practice in some organizations to allow the root and privileged users to permit automatic logins by root users from other machines by creating a /.rhosts file. A more insidious problem can occur when users define their own .rhosts files, however, in their own home directories. These files are not directly controlled by the system administrator and may be exploited by malicious remote users. One way to remove this threat is to enforce a policy of disallowing user .rhosts files and activating a nightly cron job to search for and remove any files named .rhosts in the user directories. A cron entry for a root like this
0 2 * * * find /staff –name .rhosts –print –exec rm{} \;
should execute this simple find and remove command every morning at 2 A.M. for all user accounts whose home directories lie within the /staff partition.
Secure Shell
OpenSSH (or just plain SSH) is a secure client and server solution that facilitates the symmetric and asymmetric encryption of identification and authentication sequences for remote access. It is designed to replace the Telnet and rlogin applications on the client side, with clients available for Solaris, Windows, and many other operating systems. On the server side, it improves upon the nonsecure services supported by inetd, such as the r-commands. Figure 9-4 shows a typical SSH client session from a Windows client.
SSH uses a generic Transport layer encryption mechanism over TCP/IP, which uses either the popular Blowfish algorithm or the U.S. government–endorsed triple-DES algorithm for the encryption engine. This is used to transmit encrypted packets whose contents can still be sniffed like all traffic on the network by using public key cryptography, implementing the Diffie-Hellman algorithm for key exchange. Thus, the contents of encrypted packets appear to be random without the appropriate "key" to decrypt them.
The use of encryption technology makes it extremely unlikely that the contents of the interactive session will ever be known to anyone except the client and the server. In addition to the encryption of session data, identification and authentication sequences are also encrypted using RSA encryption technology. This means that username and password combinations also cannot be sniffed by a third party. SSH also provides automatic forwarding for graphics applications, based around the X11 windowing system, which is a substantial improvement over the text-only Telnet client.
The sequence of events for establishing an SSH client connection to a server is demonstrated in Figure 9-5, for the standard username/password authentication, and proceeds as follows:
- The client connects to a server port (usually port 22, but this can be adapted to suit local conditions) and requests a connection.
- The server replies with its standard public RSA host key (1024 bits), as well as another RSA server key (768 bits) that changes hourly. Since the server key changes hourly, even if the key for the traffic of one session was cracked, historic data would still remain encrypted, limiting the utility of any such attack.
- The server can be configured to reject connections from hosts that it doesn't know about, but by default, it will accept connections from any client.
- If the connection is accepted, the client generates a session key composed of a 256-bit random number and chooses an encryption algorithm that the server supports (triple-DES or Blowfish).
- The client encrypts the session key using RSA, using both the host and server key, and returns the encrypted key to the server.
- The server decrypts the session key and encryption is enabled between the client and server.
- If the default authentication mechanism is selected, the client passes the username and password for the server across the secure channel.
SSH supports public key–based authentication: it is easy to disable the username/password authentication sequence by permitting logins to clients that have an appropriate private RSA key, as long as the server has a list of accepted public keys. However, if a client computer is stolen, and the private key is retrieved by a rogue user, access to the server can be obtained without a valid username and password combination.
On the client side, a knwnhsts.txt or known_hosts file is created and server keys are recorded there. Entries look like this:
server 1024 35 0744831885522065092886345918214809000874876031312 6632026365561406995692291726767198155252016701986067549820423736 3937365939987293508473066069722639711474295242507691974151195842 9560631766264598422692206187855359804332680624600001698251375726 2927556592987704211810142126175715452796748871506131894685401576 4183
In addition, a private key for the client is stored in Identity, and a public key for the client is stored in Identity.pub. Entries in this file are similar to the server key file:
1024 37 25909842022319975817366569029015041390873694788964256567 2146422966722622743739836581653452906032808793901880289422764252 4259614636549518998450524923811481002360439473852363542223359868 1146192539619481853094466819335629797741580708609505877707742473 7311773531850692230437799694611176912728474735224921771041151 Paul Watters
It is sensible in a commercial context to enforce a policy of SSH-only remote access for interactive logins. This can easily be enforced by enabling the SSH daemon on the server side and removing entries for the Telnet and rlogin services in /etc/services and /etc/inetd.conf. Now that OpenSSH is supplied with Solaris, there is no excuse for not deploying SSH across all hosts in your local network. Also, there are many items in the /etc/ssh/ssh_config and /etc/ssh/sshd_config files that can be configured, such as whether X11 can be forwarded, or whether to support IPv4, IPv6, or both.
![]() |
Next |