Internet Access

Internet Access

Most users access a Solaris system by means of a remote terminal, across a secure or insecure communications channel, and with or without X11 graphics support. This variety of access methods makes Solaris an ideal multiuser system, since different users can interact with a server using a number of different techniques, based on local conditions. For example, clients on a local network not connected to the Internet may use telnet and X11 graphics to run an application on a server, while a remote user in a foreign country with just VT100 terminal access would be able to use OpenSSH.

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/~tjw/telnet.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 OpenWindows, or 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.

The sequence of events that occur during a telnet session begins with a request for a connection from the client to the server. The server 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. The sequence of events in shown in Figure 17-1.

Click To expand Figure 17-1: Telnet access event sequence.

The standard port for telnet connections is 23. Thus, a command like,

$ 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.telnetd server. 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:

telnet stream tcp nowait root /pkgs/tcpwrapper/bin/tcpd in.telnetd

In this case, we 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 stand-alone daemon process and does not use inetd.

The Solaris telnet client has an extensive help facility available, which can be viewed by keying the escape sequence (usually ^]), and typing the command help. The main telnet commands are shown in Table 17-1.

Table 17-1: Telnet Client Commands

Command

Description

close

Quit telnet session.

logout

Close connection.

display

Print connection characteristics.

mode

Change mode.

open

Open connection.

quit

Quite telnet session.

send

Send special characters.

set

Set connection characteristics.

unset

Unset connection characteristics.

status

Display connection status.

toggle

Change connection characteristics.

slc

Toggle special character mode.

z

Suspend connection.

!

Spawn shell.

environ

Update environment variables.

?

Display help.

ENTER

Return to session.

As an example of how these commands work, the display command will print all of the current settings being used by your terminal:

telnet> display
will flush output when sending interrupt characters.
won't send interrupt characters in urgent mode.
won't skip reading of ~/.telnetrc file.
won't map carriage return on output.
will recognize certain control characters.
won't turn on socket level debugging.
won't print hexadecimal representation of network traffic.
won't print user readable output for "netdata".
won't show option processing.
won't print hexadecimal representation of terminal traffic.
echo            [^E]
escape          [^]]
rlogin          [off]
tracefile       "(standard output)"
flushoutput     [^O]
interrupt       [^C]
quit            [^\]
eof             [^D]
erase           [^?]
kill            [^U]
lnext           [^V]
susp            [^Z]
reprint         [^R]
worderase       [^W]
start           [^Q]
stop            [^S]
forw1           [off]
forw2           [off]
ayt             [^T]

Alternatively, the status command reveals the characteristics of the current telnet connection:

telnet> status
Connected to currawong.cassowary.net.
Operating in single character mode
Catching signals locally
Remote character echo
Escape character is '^]'.

To resume the telnet session, simply hit the ENTER key at the telnet>> prompt.

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, authenticated by the server, and access 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

However, there are two main differences between telnet and rlogin that 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 the 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.

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 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.

Testing Service Connectivity

Because a port number can be specified on the command line, telnet clients can be used to connect to arbitrary ports on Solaris servers. This makes a telnet client a useful tool for testing whether services that should have been disconnected are actually active. For example, you can interactively issue commands to an FTP server on port 21

$ telnet server 21
Trying 172.16.1.1...
Connected to server.
Escape character is '^]'.
220 server FTP server (UNIX(r) System V Release 4.0) ready.

and on a sendmail server on port 25:

$ telnet server 25
Trying 172.16.1.1...
Connected to server.
Escape character is '^]'.
220 server ESMTP Sendmail 8.9.1a/8.9.1; Mon, 22 Nov 1999
    14:31:36 +1100 (EST)

Interactive testing of this kind has many uses. For example, if we telnet to port 80 on a server, we are usually connected to a web server, where we can issue interactive commands using the Hypertext Transfer Protocol (HTTP). For example, to GET the default index page on a server, we could type get index.html:

Trying 172.16.1.1...
Connected to server.
Escape character is '^]'.
GET index.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>Server</TITLE></HEAD>
<h1>Welcome to server!</h1>

This technique is useful when testing proxy server configurations for new kinds of HTTP clients (for example, a HotJava browser), or the technique can be executed during a script to check whether the web server is active and serving expected content.

Using Remote Access Tools

With the increased use of the Internet for business-to-business and consumer-to-business transactions, securing remote access has become a major issue in the provision of Solaris services. Fortunately, solutions based around the encryption of sessions and authentication of clients have improved the reliability of remote access facilities in a security-conscious operating environment.

Secure Shell (SSH)

Open 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.

SSH makes use of a generic transport layer encryption mechanism over TCP/IP, which uses the popular Blowfish or government-endorsed Triple-DES (Data Encryption Standard) algorithms 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 as follows:

  1. The client connects to a server port requesting a connection (usually port 22, but this can be adapted to suit local conditions).

  2. 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 keys for the traffic of one session were cracked, historic data would still remain encrypted, limiting the utility of any such attack.

  3. 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.

  4. 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).

  5. The client then encrypts the session key using RSA, using both the host and server key, and returns the encrypted key to the server.

  6. The server decrypts the session key and encryption is enabled between the client and server.

  7. If the default authentication mechanism is selected, the client passes the username and password for the server across the secure channel.

It is possible 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 knownhsts.txt 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.

Kerberos

While SSH is an excellent tool for remote access between a single client and multiple servers, maintaining local databases of keys on every client machine is costly in terms of disk space and network traffic. Although some argue that such information should always be distributed across the network, the level of redundancy that SSH requires for installations of 1,000 or more clients is inefficient.

One alternative to using SSH servers as the primary means of authentication across a network is to use a centralized authentication system such as Kerberos, which grew out of the Athena Project at the Massachusetts Institute of Technology (MIT). Kerberos is a network authentication protocol that is designed to provide strong authentication for client/server applications by using secret-key cryptography, which is similar to that provided by SSH. However, the main difference between the two systems is that while authentication is performed by the target server when using SSH, a Kerberos authentication server can provide services to many different servers for a large number of clients. Thus, the many-to-many relationships realized in the Kerberos authentication database make the network authentication process more streamlined and efficient.

Kerberos is also designed to provide authentication to hosts inside and outside a firewall, since many attacks may originate in internal networks that are normally considered trusted. In addition, Release 5 introduced the notion of realms, which are external but trusted networks with authentication being extended beyond the firewall. Another advantage of the Kerberos system is that the protocol has been published and widely publicized. Of course, the greatest advantage for Solaris users is that it’s no longer necessary to download the free implementation from MIT. While Solaris 8 supplied client tools for Kerberos, Solaris 9 now supports Kerberos servers and clients that are compliant with Kerberos Release 5 v1.1. The Kerberos daemon in Solaris is kadmind, which is responsible for running the primary key distribution center (KDC).

Kerberos is based on a certificate granting and validation system called tickets. If a client machine wants to make a connection to a target server, it requests a ticket from a centralized authentication server, which can be physically the same machine as the target server but is logically quite separate. An encrypted ticket is produced by the authentication server that authorizes the client to request a specific service from a specific host, generally for a specific time period. This is similar to a parking ticket machine that grants the drivers of motor vehicles permission to park on a specific street for one or two hours only. Release 5 of Kerberos supports tickets that can be renewed.

When authentication is requested from the authentication server, a session key is created by that server that is based on your password, which it retrieves from your username—a random value that represents the requested service. The session key is like a voucher that the client then sends to a ticket-granting server, which then returns a ticket that can be used to access the target server. Clearly, some overhead is involved in making a request to an authentication server, a ticket-granting server, and a target server. However, the overhead is well worth the effort if important data is at risk of interception.

A significant limitation of Kerberos is that all applications that make use of its authentication services must be “kerberized”—that is, significant changes must be made to the application’s source code for it to make use of Kerberos services.

Kerberos configuration is reasonably straightforward given appropriate network resources. A configuration file (/etc/krb5/krb5.conf) contains entries like this:

[libdefaults]
        default_realm = site.com

[realms]
        site.com = {
                kdc = kerberos1.site.com
                kdc = kerberos2.site.com
                admin_server = kerberos1.site.com
        }

This configuration is for a domain called site.com, which has a primary KDC called kerberos1.site.com and a backup server called kerberos2.site.com. In addition to krb5.conf, several other configuration files are maintained by Kerberos:

  • /var/krb5/principal.db Database of principals

  • /var/krb5/principal.kadm5 Principal management database

  • /etc/krb5/kadm5.acl Access control list for principals

  • /etc/krb5/kadm5.keytab Local key tab

kadmin

The kadmin command is used to manage local Kerberos services, by administering key tabs, principals, and policies. There are two versions of kadmin available: kadmin.local is used only on the master KDC, and does not require authentication, while kadmin, when executed on any other server, requires Kerberos authentication across a secure link. Once logged in, the following prompt is displayed, ready for commands to be entered:

kadmin:

When kadmin starts up, it checks the value of the USER environment variable to determine the principal name. For example, if USER=pwatters, the principal name would be pwatters/admin. Alternatively, the -p option can be passed to kadmin when starting up, followed by the principal name. In addition, if a realm other than the default is to be administered, the realm name must be supplied on the command line after the -r option is passed. The user will be prompted for a password, unless one has been passed on the command line with the -w option. Thus, to start kadmin for the realm site.com with the principal pwatters/admin and the password 6fgj4gsd, the following command would be used:

# kadmin –p pwatters/admin –r site.com –w 6fgj4gsd

The following commands are supported by kadmin:

  • list_requests Displays all kadmin commands.

  • add_principal Adds a new principal.

  • get_privs Displays the Access Control Lists (ACLs) for the current principal.

  • -expire Sets the principal’s effective end date.

  • -pwexpire Sets the principal’s password effective end date.

  • -maxlife Specifies an upper time limit for tickets.

  • -maxrenewlife Specifies an upper time limit for ticket renewal.

  • -policy Sets the policy name.

  • -pw Sets the principal’s password.

  • delete_principal Completely removes a principal.

  • modify_principal Updates the principal’s characteristics.

  • get_principal Displays the principal’s characteristics.

  • list_principals Prints all known principal names.

  • add_policy Attaches a new policy.

  • delete_policy Completely removes a policy.

  • get_policy Displays the characteristics of a policy.

  • list_policy Displays policy names.

  • ktadd Attaches a principal to a key tab.

  • ktadd Removes a principal from a key tab.

kdb5_util

The kdb5_util program is used to manage the Kerberos database files. It accepts the database name as an argument on the command line after the -d option has been passed. One of the following options must also be included to perform a specific action:

  • create Creates a new database.

  • destroy Deletes an existing database.

  • stash Initializes a stash file to store the master key for the database.

  • dump Exports the database to ASCII format.

  • load Imports the database from ASCII format.



Part I: Solaris 9 Operating Environment, Exam I