[Users] [Fwd: [Serdev] TLS status update]

Klaus Darilion klaus.mailinglists at pernau.at
Mon Jan 30 14:39:18 CET 2006


FYI

klaus

-------- Original Message --------
Subject: [Serdev] TLS status update
Date: Mon, 30 Jan 2006 11:50:26 +0100
From: Jan Janak <jan at iptel.org>
To: serdev at iptel.org

Hello,

here is an interim update on the state of the TLS code:

Current status
--------------

There is a new module called TLS in the cvs repository. The module
attempts to merge the TLS code from experimental cvs module (maintained
by Cesc) and Andrei's implementation, to get the best of both.
Furthermore the module contains some new functions for script based
certificate verification.

The TLS module is much more stable than the original implementation. The
original (experimental) code works only when there are no simultaneous
TLS connections/attempts. The original code would either crash or block
SER in seconds under heavy load so it is not really suitable for
production use.

The code in TLS module is much more stable, it contains several fixes
(icluding fix of openssl) and does not seem to crash even under load
Unfortunately we discovered a problem during testing of TLS code
which can lead to SER being blocked for the duration of tls_send_timeout
interval. After that time it would recover. Andrei can probably
elaborate more on this issue, but as far as I know there is no easy way
to fix it.

In conclusion the TLS code in the tls module is more stable than the
original code from experimental but is not yet ready for production
deployments (unless you can risk SER being blocked for some time).

Installation
------------

To use the module you need to patch SER with tls-core.patch. The patch
is in tls module directory. After applying the patch compile SER with
TLS=1 appended to the make command. This is a temporary inconvenience,
we are working on eliminating the need for the patch.

TLS select functions
--------------------
The current HEAD SER version contains a mechanism which we internaly
call the "select" framework. The select framework makes it possible to
register functions from modules which can extract pieces of information
from the SIP message, transports or IP datagrams. Select functions are
denoted by @ character in the configuration file. The name of the select
consists of tokens (optionally followed by a number in square brackes)
and denoted by ., for example:

@contact[2].uri.params.transport

Would return the value of transport URI parameter from the second
Contact URI in the SIP message.

TLS module makes use of this mechanism and contains several functions
that can be used to retrieve TLS related information in the
configuration script. Currently implemented are the following functions:

@tls -- String description of the TLS layer
@tls.version -- Protocol version being used
@tls.desc -- The same as @tls
@tls.cipher -- Cipher name being used
@tls.cipher.bits -- Number of bits used for encryption
@tls.peer -- Peer certificate subject common name
@tls.me -- Local certificate subject common name
@tls.peer.subject -- same as @tls.peer
@tls.peer.issuer -- Peer certificate issuer common name
@tls.peer.verified -- True if peer cert has been verified
@tls.{peer,my}.version -- Peer/local certificate version
@tls.{peer,my}.sn -- Peer/local certificate number
@tls.{peer,my}.not_before -- Certificate validity start
@tls.{peer,my}.not_after -- Certificate validity end
@tls.{peer,my}.email -- Email address from subj alternative name
@tls.{peer,my}.host -- DNS anme from subj alternative name
@tls.{peer,my}.uri -- URI from subj alternative name
@tls.{peer,my}.ip -- IP address from subj alternative name
@tls.{peer,my}.{subj,issuer}.locality -- locality component
@tls.{peer,my}.{subj,issuer}.country -- Issuer/subject country
@tls.{peer,my}.{subj,issuer}.state - Issuer/subject state
@tls.{peer,my}.{subj,issuer}.organization -- Subject/issuer
        organization
@tls.{peer,my}.{subj,issuer}.unit - Subject/issuer organizational
        unit
	
I will send details description of the functions in a separate email.

SSL certificate based authentication
------------------------------------

The functions can be used to implement SSL certificate based
authentication in the configuration script:

if (proto == TLS && @tls.peer != "Bob") {
      sl_reply("403", "Forbidden");
      break;
}

This will reject any request received through TLS unless the client
provides a client certificate which has subject common name set to
"Bob".

Select @tls is useful for storing information about the TLS connection
(the string can be stored in accounting table, for example, appended to
the outgoing message as a header, and so on).

Multi-domain configuration
--------------------------

The original (experimental) code contained the support for multi-domain
configuration. This mechanism was extended a little bit in the tls
module. In addition to server based TLS domains there is also
preliminary support for TLS client domains. TLS client domains are used
when SER attempts to connect to a remote party using TLS. This makes it
possible to configure different TLS client certificates for different
destinations.

In addition to that almost all TLS parameters can be now set on
per-domain basis. This includes:
- Certificate file
- Private key file
- Enable/disable certificate verification
- Certificate verification depth
- CA file
- Request/do not request certificate from peer
- Cipher list
- TLS method

TLS domains are identified using IP and port, this is the destination IP
and port of the TLS connections, in server TLS domains this must be one
of the IP and port configured through listen directives. In TLS client
domains this is the IP and port of the remote peer.

There is always one default server domain and one default client domain.
These are used when no matching server/client domain can be found for
IP/port pair.

TLS domains are configured through modparams, most tls modparams accept
the parameter value with the following syntax:
<ip>:<port>=<value.

If no IP and port has been specified then the parameters of the default
domain are set:

modparam("tls", "method", "1.2.3.4:5090=SSLv23")
modparam("tls", "verify_certificate", "1")
modparam("tls", "require_certificate", "0")
modparam("tls", "private_key", "/usr/local/etc/ser/alice_prik.key")
modparam("tls", "private_key", "1.2.3.4:5090=key.pem")
modparam("tls", "ca_list", "/usr/local/etc/ser/rootca.cert.pem")
modparam("tls", "certificate", "/usr/local/etc/ser/alice_cert.crt")
modparam("tls", "handshake_timeout", 120)
modparam("tls", "send_timeout", 120)
modparam("tls", "tls_log", 2)

This configuration is somewhat suboptimal and may change yet. Currently
there is no possibility to configure TLS client domains (it will be
added soon).

Example configuration
---------------------

Here is a configuration example which demonstrates a couple of
interesting things that can be done with the TLS module, XMLRPC
management interface and new serctl tools. This configuration file
snippet makes it possible to run serctl remotely. It uses the XMLRPC
procotol which is encrypted using TLS. Futhermore TLS certificate
authentication is used so only people having a correct client
certificate are allowed to execute the kill command (this command will
stop ser):

loadmodule "./modules/tls/tls.so"
loadmodule "./modules/sl/sl.so"
loadmodule "./modules/xmlrpc/xmlrpc.so"

listen=tls:1.2.3.4:5061

modparam("tls", "method", "SSLv23")
modparam("tls", "verify_certificate", "1")
modparam("tls", "require_certificate", "0")
modparam("tls", "private_key", "/usr/local/etc/ser/alice_prik.key")
modparam("tls", "ca_list", "/usr/local/etc/ser/rootca.cert.pem")
modparam("tls", "certificate", "/usr/local/etc/ser/alice_cert.crt")

route {
     if (proto == TLS && (method == "POST" || method == "GET")) {
         create_via(); # XMLRPC requests do not contain via, create it

         if (!@tls.peer.verified) {
             # Client did not provide certificate or it is not valid
	    xmlrpc_reply("400", "Unauthorized");
	    break;
         }

         if (@xmlrpc.method == "core.kill") {
              # Make sure the client has the permission to execute the 
command
              if (@tls.peer != "SER-Killer") {
	         xmlrpc_reply("400", "Access to core.kill denied");
	         break;
	    }
         }

         dispatch_rpc();
         break;
     }
}

To be done
----------

There is still few things that are not yet done:

- @Cesc: Do we need the function set as verify_callback ? As far as
   I know there is an internal representation in openssl. If we need it
   then where do we get the verify_depth from (it can be different in
   different domains)

- @Cesc: A couple of openssl parameters have different values, could you
   check that nothing important is missing ?

- Currently only keys without passhprase would work, because SER has
   no controlling terminal anymore when executing mod_init and child_init
   module functions (this is where private keys are loaded)
   Is this feature or bug ? Should we have support for private keys
   protected by passphrase (requires human intervention when starting ser)

- The modparam syntax needs changes to support client domains

- TLS can block SER

- Support for revocation lists

- Should we generate SER CA in a script (possibly called from package
   pre-init scripts) ? How do we make management of thousands of client
   certificates easy ?

      Jan.

_______________________________________________
Serdev mailing list
Serdev at iptel.org
http://mail.iptel.org/mailman/listinfo/serdev






More information about the Users mailing list