TLS module (new)

Keywords: 2.0.x | Book | tls

There is a new module called TLS in the cvs repositoryi. 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 SERi 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 wayto 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).

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 URIi 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
      
@tls
   String description of the TLS connection currently being used.
   Example:
   AES256-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA1
  
@tls.version
   The version of TLS procotol being used for the actual connection
   Example:
   if (@tls.version == "SSLv2") ...
@tls.desc
   Same as @tls
@tls.cipher
   Name of the cipher being used in the current TLS connection.
 
   Example:
   'AES256-SHA'
  
@tls.cipher.bits
   Number of encryption bits used by the current TLS connection.
@tls.peer
   Common name of the peer certificate subject.
   Example:
   if (@tls.peer == "Bob") ...
@tls.me
   The local (server for inboud, client for outbound TLS connections)
   certificate subject Common Name
@tls.peer.subject
   same as @tls.peer (just alias for completeness)
@tls.peer.issuer
   The common name of peer certificate issuer.
@tls.peer.verified
   True if peer provided a certificate and the certificate has been
   successfuly verified. False if there was no peer certificate or it
   has not been verified.
@tls.{peer,my}.version
   Peer/local certificate version
@tls.{peer,my}.sn
   Peer/local certificate serial number assigned by the certificate
   authority
@tls.{peer,my}.not_before
   Certificate validity start
   Format: 'Jun 17 15:03:20 2005 GMT'
@tls.{peer,my}.not_after
   Certificate validity end (format is same as in @tls.peer.not_before)
@tls.{peer,my}.email
   Email address component from the subject alternative name.
@tls.{peer,my}.host
   DNS name from the certificate subject alternative name.
@tls.{peer,my}.uri
   URI from certificate subject alternative name.
@tls.{peer,my}.ip
   IP address from certificate subject alternative name.
@tls.{peer,my}.{subj,issuer}.locality
   Certificate subject/issuer locality.
@tls.{peer,my}.{subj,issuer}.country
   Certificate subject/issuer country name.
@tls.{peer,my}.{subj,issuer}.state
   Certificate subject/issuer state code.
@tls.{peer,my}.{subj,issuer}.organization
   Certificate subject/issuer organization name.
  
@tls.{peer,my}.{subj,issuer}.unit
   Certificate subject/issuer organizational unit.

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/seri/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 serctli 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;
    }
}
Home |  Recent changes |  Search |  Glossary |  Sitemap |  Login