Saturday, 19 March 2011

Connecting to UniVerse over SSL


As I wrote in my last post, I have been writing a custom secure terminal emulator for connecting to a client system running UniVerse. This entails using an encrypted telnet connection over SSL, a feature that is available through the UniVerse telnet service on Windows or the uvtelnetd daemon on UNIX.

Whether you roll your own emulator – and my reasons for my doing so are specific to this client – or use a standard emulator that supports the encrypted communication such as WinTegrate, actually setting up the server end of the connection is relatively straight forward. If you don't want to have to learn about certificates and encryption here is a step-by-step quick guide to get you up and running.

Still Running TELNET?

First off, why should you be using SSL? Simply, if you are accessing your system over a regular TELNET connection, whether for administration tasks or to access text based legacy applications -  it is open to the world – or at least to anyone on your network – to listen in. Network sniffers are easy to find (man tcpdump) and genuinely useful for developers engaged in supporting network protocols, and so listening in on a communication between a client and server is simple enough.

TELNET was clearly designed in the days before people were concerned about network security and did not have auditors breathing down their necks asking why plain text passwords were being sent over the wire. Anything you type over a regular TELNET connection is plainly visible – even your credentials.  And that should be a cause for concern.

Using Telnet over SSL

The preferred mechanism for talking to UniVerse from a terminal style connection is to run TELNET over SSL. This uses  the standard TELNET protocol and all the negotiations involved, so retaining compatibility with existing software, but the data passed between client and server is encrypted. Moreover, you can add endpoint verification at each end of the connection to ensure that both client and server are who they say they are.

Enabling Telnet over SSL

There are a number of steps that need to be followed before you can connect to UniVerse using TELNET over SSL. These can be performed using the administration client or, if that is not available or you just don’t like it (understandably), UniVerse Basic has a set of tools for working with certificates and for accessing security contexts and so I have scragged together a simple Basic program that can do this for you:  download it from here.

This is provided as a self-instsalling program so to use this:
  • Create an installation file as a type 19 directory, preferably called inst.bp.
  • Copy the downloaded installation file into that directory, compile and run.
  • It will create two files, one named blutil.bp and the other blstd.bp.
  • The program is named BUILD_SSL and is written to the blutil.bp file.

e.g. on sensible PICK flavour:

>CREATE.FILE inst.bp 1,1 1,1,19
(copy the  setup_ssl.uvexe using Windows explorer, ftp etc. into the inst.bp directory.
>BASIC inst.bp setup_ssl.uvexe
>RUN inst.bp setup_ssl.uvexe
>SETUP_SSL
 
The SSL layer is based on certificates used to authenticate the server and to provide the encryption keys: it can also make use of client side certificates to verify the identities of the clients. So the first steps involve creating the necessary certificates and then attaching these to the UniVerse telnet service.
The steps to do this are:
  • Create a certificate request.
  • Create or assign a certificate.
  • Create a security context
  • Attach the security context to the service.
  • Enable the service
The SETUP_SSL program will walk you through the first four of these stages.

Step 1. Creating a Certificate Request

Certificates may be generated in-house or, for additional security, by a trusted third party such as VeriSign depending on the level of trust that is required. If your only requirement is to encrypt the communication so it cannot easily be snooped, an in-house self-signed certificate may well be all you need, and can be used in the first instance for testing anyway.

Regardless of where the certificate originates, its life begins with a certificate request. This encodes details about the organization and the preferred certificate format. You can use a regular tool to create the request, but this – and the other certificate functions – is now available as a set of UniVerse functions anyway so it is just as easy to use those.

I’m going to assume that you will be using the SETUP_SSL program, but the prompts generally follow the same form as the UniVerse admin client.

The certificate request is encoded into a file, conventionally given a csr suffix. There are no standard naming conventions here so to keep everything simple I suggest using the name of the server for the root of the file name, and the following suffixes:
csrcertificaterequest
cercertificate
pvtprivate key
pubpublic key

You also have some choices to make regarding the format of the certificate, although in some cases this will be dependent on your certificate authority or other provider.




The screen above (you can click to show full size) shows a typical certificate request, one that you can use as a template for your certificates. Note the Common Name in this case refers to the name of the server, since that is what will be identified using this certificate, and not the name of the company. The organization  unit and email are both optional.


Once accepted this will create the three files – the request, private and public key files – in the nominated directory, here c:\ssl. Obviously if you are running on UNIX you will need to substitute equivalent UNIX paths.


Step 2 Creating the Certificate

Once you have defined your request, you can either go ahead and create the certificate yourself if that is sufficient, or send it to a third party trusted authority to create the certificate on your behalf – for a fee. If you can generate the certificate yourself, this is simply a matter of determining the length of time for which it will be valid and supplying the request and private key files you created in the first step:


Step 3 Creating the Security Context

So far so good – you have a certificate that can be used to identify you and the keys required to unlock it. But the certificate alone does not contain the necessary information to dictate how it will be used in the context of securing the SSL connection. That is the job of the Security Context Record, or SCR.

The security contexts are held in a UniVerse account and I suggest holding these in either a dedicated account or in the uv account: it does not make any difference as far as the ability to access accounts is concerned, it just has to live somewhere that UniVerse can find it. Frankly I don’t know why Rocket designed it this way and did not just make it part of the uv account like the key store.



Each  SCR is held as a separate record in the &SECUCTX& file, and so needs to have a unique record key. The SCR binds together the certificate you created earlier, the private key required to access it and the authority that it will confer on a UniVerse service. Needless to say, the &SECUCTX& file is itself encrypted.

There are three levels at which you can choose to apply the authentication.

No Client Authentication. In this mode, the the server will send its certificate to the client to begin the encryption process, but it does not request a return certificate from that client. This may well still be sufficient for your needs – if your only requirement is to encrypt the data in transit, this will meet that requirement.

Client Authentication in GENEROUS mode (see Auth Type in the figure above). The client will send its certificate to the server, which will check the validity of the certificate but does not verify the identity of the client itself. rocket suggests that this should only be used for testing and development.

Client Authentication in STRICT mode. Here the client will send its certificate and the server must verify the identify of the client against the list of trusted names along with other details in the certificate. You will need to create a certificate for each client that will identify the client to the server using the Common Name entry: a list of these ‘trusted peers’ is maintained as part of the security context. This will of course involve a major administrative effort both in setting this up and in keeping the record up to date as new clients are added, especially where your user community runs to hundreds if not thousands of users.


Step 4. Assigning the Security Context to a Service

Once the security context has been created, the last piece for the UniVerse side is to attach that to one or more of the UniVerse services. For telnet over SSL this will be the uvtelnetd service, and the same context can also be applied to help secure other connections, such as UniObjects.

The attachment is made through a file named .unisecurity. This is a text file that is created in the unishared directory – until you run this it is not created by default so there is no point looking for it.

The .unisecurity file binds together the name of the service with the account holding the SCR and the name of the SCR record itself. It also contains the password to the SCR in plain text which is not the best idea but that is how it is.



Step 5. Starting on Windows

On Windows, that is all you need to do: your TELNET access to UniVerse is provided through the UniVerse telnet service whether you are running over SSL or not, so the service is good to go. You may need to unblock port 992 on your firewall. Find an emulator that supports Telnet over SSL and connect on port 922: notice the difference in the logon banner.




Remember that limited period evaluation copies of WinTegrate are available for download from the Rocket website if you wish to test out the SSL connection and the other WinTegrate features.


Step 6. Enabling the uvtelnetd service on UNIX

On UNIX you have a little more pain, as you will need to specifically enable the uvtelnetd service.  There are two approaches: for those flavours of UNIX that use inetd or xinetd and for Solaris that doesn’t.

The first step in both cases is to define the uvtelnetd service in the /etc/services file. You will need to add or modify the entry for the telnets service on port 992 so that it is connected to the UniVerse telnet daemon and not to any pre-existing telnet service. The /etc/services file is relatively similar across all UNIX flavours and you may find a line that reads:
telnets 992/tcp # telnet protocol over TLS/SSL

This should be modified, or a new line added, to specify the path to the uvtelnetd binary and any startup flags: for your first test you may wish to enable detailed logging through the –d3 flag:
telnets 992/tcp no-wait/uv../bin/uvtelnetd –d3

On Linux and most UNIX, including older versions of Solaris, the service should be configured through the xinted or inetd configuration files respectively.

On most Linux, the xinetd.conf file is populated using individual entries in the xinetd.d directory, so you will need to create a new entry for telnets similar to the one below:
# This is the configuration for the tcp telnets service.

service telnets
{
        disable = no
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/uv/bin/uvtelnetd
        server_args     = -d3
        log_on_failure  += USERID
}

On Solaris 10 the inetd configuration has been replaced with the service control management. This uses an XML based definition of each service (a “manifest”) that is imported into a services repository using the service configuration commands. The intent is to provide a single model for controlling all of the different types of service available.

The best starting point is therefore to take the existing telnet service definition as a template and modify it to build the telnets definition. You should find this in the /var/svc/manifest/network directory. Copy this to create the telnets.xml file and modify it as below:

service_bundle type='manifest' name='SUNWtnetr:telnets'> 

<service 
        name='network/telnets' 
        type='service' 
        version='1'> 

        <create_default_instance enabled='false' /> 

        <restarter> 
                <service_fmri value='svc:/network/inetd:default' /> 
        </restarter> 

        <exec_method 
                type='method' 
                name='inetd_start' 
                exec='/opt/universe/bin/uvtelnetd -d3' 
                timeout_seconds='0'> 
                <method_context> 
                lt;method_credential user='root' group='root' /> 
                </method_context> 
        </exec_method> 

        <exec_method 
                type='method' 
                name='inetd_disable' 
                exec=':kill' 
                timeout_seconds='0'> 
        </exec_method> 

        <property_group name='inetd' type='framework'> 
                <stability value='Evolving' /> 
                <propval name='name' type='astring' value='telnets' /> 
                <propval name='endpoint_type' type='astring' value='stream' /> 
                <propval name='proto' type='astring' value='tcp6' /> 
                <propval name='wait' type='boolean' value='false' /> 
                <propval name='isrpc' type='boolean' value='false' /> 
        </property_group> 

        <stability value='Unstable' /> 

        <template> 
                <common_name> 
                        <loctext xml:lang='C'> Telnets server </loctext> 
                </common_name> 
                <description> 
                        <loctext xml:lang='C'> 
                          UniVerse Telnet over SSL. 
                        </loctext> 
                </description> 
                <documentation>                        
                </documentation> 
        </template> 
</service> 

</service_bundle> 

To install this as a service you will need to call upon the service controller /usr/sbin/svccfg to validate and import the manifest into the services repository. Note that in common with most UNIX commands, this performs its operations silently unless an error is encountered.

# /usr/sbin/svccfg 
svc:> validate telnets.xml 
svc:> import telnets.xml

Finally you will need to enable the service before it can be launched:
# /usr/sbin/svcadm enable telnets

You can test this by listing the currently installed services using the svcs command:
# svcs | grep teln 
online         Dec_30   svc:/network/telnet/tcp6:default 
online         13:46:51 svc:/network/telnets:default
You should now be able to connect to the uvtelnetd service by using a terminal emulator that supports telnet over SSL and connecting on port 992. Note that the first time you connect to the service there may be a delay of up to a minute: this Is not the case for subsequent connections.

2 comments:

Matthew said...

Hi Brian,
Thanks for the writeup! I set all this up early last year - took me a full day to work through it all. Now I've come back to re-visit it on our development server and Rocket no longer provide any documentation for uvtelnetd in the 11.1 manuals! So you will have saved me many hours of searching through my notes and scratching my head.

GOvind Shankar aka "rueben" said...

Hi Brian,

THanks for the writeup. Very helpful. I have an issue though with the implementation if uvtelent, and was wondering if you could assit or shed some light towards a direction that I can pursue to figure out the resolution.
I am running UniVers 10.3.6 on AIX 5.3.12.After I enabled uvtelnet (telnets), I am unable to identify which IP address the sessions are originating from. The "who" command on AIX shows the username that is connected, however the IP address associated is showing up as 0.0.0.0. Any ideas how I can get to see the originating IP address?