Last revised: 12 March 2001
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.
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 <[email protected]>.
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:
C-Kermit 7.1 for the client
stunnel 3.13 + the AIX telnet daemon for the server
openssl 0.9.6 for the crypto libraries (needed for building stunnel)
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.
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:
After creating a source directory and untarring the source code into it, I compiled C-Kermit 7.1 using the installation instructions provided for the alpha release . I had to tell make where to find the openssl libs and include files because RedHat stuck them somewhere other than /usr/local/ssl (argh!). I decided to do this by editing the makefile, finding the section headed "linux+openssl", then changing the appropriate lines.
After successfully running "make linux+openssl", I had (among others) a binary executable called "krbmit" in the source directory. This is the security enabled C-Kermit program.
Because the hostname we were going to use for the secure telnet server is not in our DNS, I edited the /etc/hosts file on the Linux client to add an appropriate line pointing the hostname to its IP address. Note that if you are setting up Kermit 95, the hosts file is usually in your Windows directory tree (e.g., C:\WINDOWS\HOSTS or C:\WINNT\SYSTEM32\DRIVERS\ETC\HOSTS).
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
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.
I created the following subdirectories under my openssl install directory (one or more of these may already exist for you):
certs
private
requests
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 |
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.
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 |
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.
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 \ -l /usr/sbin/telnetd |
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 -l parameter identifies the daemon 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.
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.
(/home/ktrustin/cku199/) C-Kermit> set auth ssl verify-file cacert.pem (/home/ktrustin/cku199/) 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.
You mean it's not working perfectly?
Well... We have run into some issues that may or may not trouble anyone else. Here they are, for those who care:
The stunnel server leaves phantom entries in the wtmp file on our RS/6000. The phantom entries show that the person is "still logged in" even though s/he has logged out.
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.
Here are things you can try if you can't get Kermit to connect to the stunnel server:
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 \ -l /usr/sbin/telnetd |
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.
To turn on SSL/TLS debug messages in Kermit, issue the following commands before the SET HOST command:
(/home/ktrustin/cku199/) C-Kermit> set auth ssl debug on (/home/ktrustin/cku199/) C-Kermit> set auth ssl verbose on |
If you suspect that there's something wrong with your certificates, you can turn off certificate checking in Kermit with this command:
(/home/ktrustin/cku199/) C-Kermit> set auth ssl verify no |
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.
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
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
Afterward, make sure that you edit the server certificate as described in Creating and signing the server certificate.
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.
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 |
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:
(/home/ktrustin/cku199/) C-Kermit> set auth ssl verify no (/home/ktrustin/cku199/) C-Kermit> set auth ssl debug on (/home/ktrustin/cku199/) C-Kermit> set auth ssl verb on (/home/ktrustin/cku199/) C-Kermit> set host www.amazon.com https /ssl |
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 <[email protected]>, for allowing me to write this case study on their dime.
Regards,
Kirk Turner-Rustin
[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! |