[ Previous ] [ Next ] [ Index ] [ C-Kermit Home ] [ Kermit Home ]

Case Study: Secure Telnet Using C-Kermit 7.1 With Stunnel

Kirk Turner-Rustin, Ohio Wesleyan University

Rev 0.98

Last revised: 16 March 2001

This is a summary of the steps taken at Ohio Wesleyan University to setup secure telnet communication between C-Kermit 7.1 and a telnet daemon wrapped with stunnel. Notes are also included relevant to using Kermit 95 for the client.


Table of Contents
1. Disclaimer
2. Feedback
3. Background
4. Building the Kermit client
5. Setting up the stunnel server
5.1. Building and installing the server
5.2. Creating an RSA certificate signed by our own CA
6. Making the connection
6.1. Starting the secure telnet service
6.2. Connecting from Kermit
7. Remaining Problems
8. Troubleshooting
9. Acknowledgements

1. Disclaimer

In order to protect my employer, I must state that if you try anything that is described in this document, you do so at your own risk. In no way do I or anyone else at Ohio Wesleyan University offer any protection or guarantee as to the suitability of this document or its contents for any use whatsoever. Also, I am not connected in any way with The Kermit Project at Columbia University, other than the fact that I work at a school which has licensed and uses their excellent Kermit product.


2. Feedback

If you have questions about anything described herein and how it worked or didn't work at Ohio Wesleyan, or if you have other feedback about this document (especially corrections to my mistakes), I welcome hearing from you at .


3. Background

I was assigned the job of finding a way of encrypting the telnet traffic between campus staff, who were using Kermit for a telnet client, and our administrative database server, an IBM RS/6000 model F50 running AIX 4.3.

I consulted the excellent security document which the Kermit Project has posted on their web site. [1] This document confirmed that the latest Kermit (both C-Kermit 7.1 and Kermit 95 1.1.21) would handle SSL/TLS telnet connections on the client end. For the server side, I settled on stunnel, a program which can wrap arbitrary TCP connections inside SSL/TLS without requiring any changes to the daemons themselves.

The actual combination that ended up working was:

Here's how we got these pieces to talk to each other on our platform. Note that the IP addresses and hostnames used in this document are bogus. Also note that while what follows is specific to C-Kermit 7.1, the same client side procedures were tested with the Kermit 95 1.1.21 beta and will work with Kermit 95 1.1.21 when it becomes publicly available.


4. Building the Kermit client

I built the C-Kermit 7.1 alpha from source on an x86 PC running RedHat Linux 6.1 (kernel 2.2.12-20). Note that none of the prebuilt binaries has security features built-in. You have to build your own using OpenSSL. If you don't have OpenSSL on your client box already, get it now, build it and install it to a suitable location (e.g., /usr/local/ssl).

Here are some specific notes about what I did:


5. Setting up the stunnel server

5.1. Building and installing the server

Here's what I did to build and install the server on our platform:

  • Downloaded the stunnel-3.13.tar.gz package. You can get it here.

  • I had already downloaded and built OpenSSL on this server for an earlier project, so I didn't need to do so again. If you don't have it, you should get it and build it now using the instructions in the included INSTALL file.

  • You can configure stunnel to use tcp wrapper libraries to control access based on entries in /etc/hosts.allow and /etc/hosts.deny. If you want to do this (as we did), you'll need to build tcp wrappers (if you don't use it already) and put the libwrap.a library and tcpd.h header files somewhere where your compiler can find them. You can get the tcp wrappers source here. Note that users of AIX 4.3 will want the IPv6 version. I had placed libwrap.a in /usr/lib and tcpd.h in /usr/include.

  • I ungzipped and untarred the stunnel source package in /usr/local/src/stunnel on the server.

  • I configured, built, and installed stunnel using the instructions in the INSTALL document included with the source. I used the following options with the configure command:

                    --with-ssl=/usr/local/ssl
                    --prefix=/usr/local/stunnel
                    

    The first option points to the server directory where I put the openssl crypto libs, and the second specifies where the stunnel program should be installed.


5.2. Creating an RSA certificate signed by our own CA

After struggling with trying to understand various documents purported to tell me how to create these certificates properly, I've decided that I'm SSL learning impaired (a.k.a., "certifiable"). The steps below are what have finally worked for me after much help from Jeffrey Altman and some trial and error. This is probably not the best way to do this, and most certainly isn't the only way. If you know little or nothing about certificates, you may want to read the section on certificates in the Kermit Project security document.

As far as I understand it, a certificate signed by a trusted entity (called a certificate authority or CA) sits on the server. The client has a "root" certificate from the CA which was created with the same key that the CA used to sign the server certificate. At the start of the secure connection, the server and client will compare certificates so that the client can verify that the server is who it claims to be. You create all of these doo-dads using the openssl tools.

Kermit can run with or without certificates and still take advantage of the encrypted telnet communication. The stunnel program, as far as I know, must have a server certificate available in order to run. For that reason, when you build stunnel, a server certificate is created for testing purposes, but you shouldn't employ that test certificate for actual everyday use.

We decided to act as our own certificate authority for purposes of setting up the connection between Kermit and stunnel. Here's what I did to create both the signed certificate for the server and the CA "root" certificate for the client.


5.2.1. Preparing to create certificates

  • I created the following subdirectories under my openssl install directory (one or more of these may already exist for you):

                certs
                private
                requests
                


5.2.2. Creating the CA "root" certificate

  • I changed to our openssl install directory and issued the following commands as root:
        # cd /usr/local/ssl
        # openssl req -x509 -newkey rsa:1024 -days 365 -nodes \
    	-keyout private/cakey.pem -out certs/cacert.pem
                
    Note that the private key generated with the above command (private/cakey.pem) will not be encrypted. This is necessary for stunnel because it has no way to obtain a password from the user. Make sure that the key file and its directory are protected with appropriate file permissions.

  • I answered the certificate request dialog questions. I answered "Certificate Authority" when asked for an "Organizational Unit Name" here and used a different answer when I created the server certificate, below. The answers you give to at least one of these questions must differ from the ones you give when you create the server certificate. Otherwise, it will appear that the server certificate has been signed by itself. In that event, Kermit will (appropriately) tell you that the server certificate's signature is invalid and reject the certificate with a warning. Also, make sure that you use the hostname of the stunnel server in answer to the "Common Name" question.

  • The file certs/cacert.pem is the CA "root" certificate. I copied this file to a suitable directory on the Kermit client PC (/usr/lib/openssl/certs in my case, since RedHat set things up that way). You'll refer to this file and its directory later when you crank up secure telnet on the client.


5.2.3. Creating and signing the server certificate

  • I created a certificate signing request (CSR) with this command (as root):
        # openssl req -newkey rsa:1024 -nodes \
    	-keyout private/stunnel-key.pem \
    	-out requests/stunnel-req.pem
                
    Once again, the key generated with the above command is not encrypted.

  • Again, I answered the certificate request dialog questions. This time I answered "Information Systems" when asked for an "Organizational Unit Name", but anything will do as long as it's different from the answer you gave for the CA "root" certificate, above. Again, I used the stunnel server hostname for the "Common Name".

  • I signed the CSR to create the server certificate using this command (as root):
        # openssl x509 -req -in requests/stunnel-req.pem \
    	-CA certs/cacert.pem -CAkey private/cakey.pem \
    	-out certs/stunnel.pem -days 365 -CAserial ca.srl \
    	-CAcreateserial
                

  • Important step: I edited the certs/stunnel.pem file and prepended the contents of private/stunnel-key.pem to it. Make sure that you leave a blank line between the private key block and certificate block in the resulting stunnel.pem. If you don't do this, the stunnel service won't run.


6. Making the connection

6.1. Starting the secure telnet service

Stunnel can be run as a stand-alone daemon or it can be run from inetd.conf. The former method is preferred as it uses less memory on heavy load and is faster (SSL doesn't have to be initialized on every connection). Also, the stand-alone daemon method is the only one of the two that supports session cache, and you can still rely on tcp wrappers to monitor connections if you built stunnel with libwrap support.

We chose to run stunnel as a stand-alone daemon.

I started the service with the following commands (as root):
    # cd /usr/local/stunnel/sbin
    # ./stunnel -d 992 -N telnets \
	-p /usr/local/ssl/certs/stunnel.pem \
	-r localhost:telnet
	

This tells stunnel to listen on port 992 for connection from an SSL/TLS enabled client. You could use any port number you want as long as you use a matching port number when you connect from the Kermit client. Port 992 is the Internet Assigned Numbers Authority standard port for telnets (telnet over SSL/TLS), so you could certainly add it to /etc/services on the server box and use "telnets" instead of a port number here.

The -r parameter identifies the host and service port that will receive the unencrypted traffic after a secure connection is successfully negotiated. The -p parameter identifies the server certificate. The -N parameter tells stunnel to use the name 'telnets' as the service name for purposes of controlling access via /etc/hosts.allow and /etc/hosts.deny. You can use any name you wish as long as you use it both here and in /etc/hosts.allow or /etc/hosts.deny.

I also added a comparable command line to the rc.local file on the server so that the secure telnet service would be automatically restored in the event of a server reboot.


6.2. Connecting from Kermit

I started C-Kermit 7.1 on the client PC and issued the following commands. I've broken the second command into two lines at the trailing backslash for readability -- you do not need the trailing backslash in this command.
    C-Kermit> set auth ssl verify-file cacert.pem
    C-Kermit> set host /connect myhost.mydomain.edu telnets /ssl-telnet
	

where "myhost.mydomain.edu" is the hostname of the server host which is running the secure telnet daemon.

That's it! If you're using Kermit 95, then once you're connected you should see the string TELNET:SSL at the right side of the Kermit 95 status line. To use TLS instead of SSL for either client, just substitute 'tls' for 'ssl' in the above commands.


7. Remaining Problems

You mean it didn't work perfectly the first time?

Well... We did run into some problems that may be specific to our server platform and, therefore, may not trouble anyone else. Here they are, along with solutions if any, for those who care:

Problem:

More often than not, the Kermit client would not shutdown after logging out of the secure telnet session. In these cases, the user would have to use Kermit to hangup the network connection, then quit.

Solution:

At the time, we were running the server as follows:
    # ./stunnel -d 992 -N telnets \
	-p /usr/local/ssl/certs/stunnel.pem
	-l /usr/sbin/telnetd
	

Note particularly the last line. The -l parameter starts a new copy of telnetd and passes the unencrypted telnet stream to it. We changed this to the following:
    # ./stunnel -d 992 -N telnets \
	-p /usr/local/ssl/certs/stunnel.pem
	-r localhost:telnet
	
which passes the unencrypted traffic to the existing telnet service port rather than starting a new instance of the daemon. This change fixed our problem and is the method used in the server setup steps, above.

Problem:

The stunnel wrapped telnet daemon would leave phantom entries in the wtmp file on our RS/6000. The phantom entries claimed that the user was "still logged in" even though s/he had logged out.

Solution:

This problem went away when we changed the way we ran the secure telnet service. See the first problem, above.

Problem:

The stunnel server has the side effect of hiding the IP address and/or hostname of the client machine from the daemon that receives the unencrypted TCP stream. For example, telnetd thinks that the connection is coming from "localhost" (which in a way it is) instead of my client box. Therefore, when I attempt to view such information on the server machine (e.g., with the who command), I see "localhost" instead of the client hostname or IP. This has goobered up some of our reports that track telnet logins.

Note that stunnel does have a parameter -T that allows it to run in transparent proxy mode, whereby it is able to pass the client IP address/hostname to the receiving daemon, but this was written specifically for use with Linux kernels on the server.

Solution:

None at present.


8. Troubleshooting

Here are things you can try if you can't get Kermit to connect to the stunnel server:

8.1. Turn on debugging messages on the server side.
8.2. Turn on debugging messages on the client side.
8.3. Turn off certificate checking on the client side.
8.4. Make sure that the server's hostname is in your DNS or in the client's hosts file.
8.5. Add extensions to your certificate.
8.6. Make sure that you used a different subject line for the CA "root" certificate and the server CSR.
8.7. Try connecting to the stunnel server with openssl on the client.
8.8. Try connecting from the Kermit client to a secure http site.

8.1. Turn on debugging messages on the server side.

You can use the following commands as root (adjusting the paths to suit your situation):
# cd /usr/local/stunnel
# kill -HUP `cat ./var/run/stunnel.telnetd.pid`
# ./sbin/stunnel -f -D 7 -d 992 -N telnets \
    -p /usr/local/ssl/certs/stunnel.pem \
    -r localhost:telnet
	    

The -f parameter forces stunnel to run in the foreground instead of writing its errors to syslogd. The -D 7 parameter asks stunnel to give you debugging output at a certain level of detail.

8.2. Turn on debugging messages on the client side.

To turn on SSL/TLS debug messages in Kermit, issue the following commands before the SET HOST command:
    C-Kermit> set auth ssl debug on
    C-Kermit> set auth ssl verbose on
	    

8.3. Turn off certificate checking on the client side.

If you suspect that there's something wrong with your certificates, you can turn off certificate checking in Kermit with this command:
    C-Kermit> set auth ssl verify no
	    

8.4. Make sure that the server's hostname is in your DNS or in the client's hosts file.

Whatever you use as the "Common Name" of your server when you create the server certificate (stunnel.pem), that same string must be in your DNS or an appropriate hosts file (e.g., /etc/hosts) on the client and should point to your server's IP address. (See Building the Kermit client.) Note that in one very specific context (testing Kermit 95 under Win4Lin on a Linux client), I had trouble with my hosts file because I had multiple hostnames on the same line. In that case, the hostname that I used to create the server certificate had to be the first name on the line. I don't know whether this is a problem in other contexts.

8.5. Add extensions to your certificate.

If, after following the steps I've given above, you try to use an IP address instead of a hostname in your SET HOST command, you will get a 'NO IP IN CERT' error from Kermit. If you want to have the option of using either an IP address or a hostname with the SET HOST command, you need to add x509 extensions to your server certificate. Again, there are other and probably better ways to do this, but here's how I did it:

  • In the OpenSSL directory on your stunnel server (/usr/local/ssl for us), create a file containing the following line:


    subjectAltName = IP:192.68.123.123,DNS:myhost.mydomain.edu

    where 192.68.123.123 is the IP address of the stunnel server box and myhost.mydomain.edu is its hostname.

  • When you issue the openssl command to sign your CSR, (see Creating and signing the server certificate) add the following parameter to the end of the command line:


    -extfile extfilename

    where extfilename is the name you gave to the file you just created.

  • Afterward, make sure that you edit the server certificate as described in Creating and signing the server certificate.

You should now be able to connect to the server using either its IP address or hostname with the SET HOST command.

8.6. Make sure that you used a different subject line for the CA "root" certificate and the server CSR.

If Kermit starts up with the following message: "Warning: server has a self-signed certificate continue? (Y/N)", then you used identical answers when building both your CA "root" certificate and your server CSR. (See Creating the CA "root" certificate.)Try using a different string for, say, the "Organizational Unit Name" when you build one or the other.

8.7. Try connecting to the stunnel server with openssl on the client.

If you want to verify that your stunnel server is capable of negotiating a secure connection with the openssl libs you're using on the client, try running the following openssl command on the client: [2]
    % openssl s_client -connect 192.68.123.123:992 \
	-debug -CAfile cacert.pem
	    
where 192.68.123.123 is the IP address of the stunnel host. You can, of course, use hostname:telnets instead of the IP:992 syntax if you care to, assuming you've set up your services and hosts files properly. You won't get any telnet communication this way, but you should be able to see whether secure connection can be established with your server as you've configured it. To stop openssl, just press Ctrl+C.

8.8. Try connecting from the Kermit client to a secure http site.

If you want to verify that Kermit as you've configured it can negotiate secure connection with a different server, try connecting to a secure http site. You can use these commands at the Kermit prompt:
    C-Kermit> set auth ssl verify no
    C-Kermit> set auth ssl debug on
    C-Kermit> set auth ssl verb on
    C-Kermit> set host www.amazon.com https /ssl
	    
If the connection is successful, you will see the SSL handshaking messages, including an [SSL - OK], then be returned to the Kermit prompt. To close the connection, use the "close" command at the Kermit prompt.


9. Acknowledgements

I can't say enough about the help we received from The Kermit Project via our academic site-license support contract. [3] Specifically, I would not have been able to get this working at all without the patient and generous help of Jeffrey Altman, Senior Software Designer with the Project. (But please don't bother him with questions about this document!) Most of the troubleshooting tips, above, are suggestions he made to help us. Having access to the Kermit 95 1.1.21 beta for testing was also nice.

Also, I'm grateful to Ohio Wesleyan University, particularly the Director of Administrative Computing, John Topping , for allowing me to write this case study on their dime.

Regards,

Kirk Turner-Rustin

Notes

[1]

The link points to the security document pertaining to C-Kermit 7.1, which is in alpha as I write this. The security document for C-Kermit 7.0 is here.

[2]

If you're trying to setup Kermit 95, openssl.exe should be in your Kermit install directory.

[3]

Read more about Kermit tech support here. And buy the Kermit manuals!

[ Top ] [ Previous ] [ Next ] [ Index ] [ C-Kermit Home ] [ Kermit Home ]


C-Kermit 7.1 / Columbia University / kermit@columbia.edu / 16 March 2001