Guide to configure TLS

1,183 views
Skip to first unread message

Jonas Borjesson

unread,
Jan 22, 2012, 11:45:20 PM1/22/12
to mobicent...@googlegroups.com
Hey,

I spent way too much time trying to configure the sip container to use
TLS and since there is absolutely nothing in the documentation I was
fumbling for quite some time. As it turns out, it was a simple
copy-paste error (and my original attempt actually did work) but even
so, some information of how to configure the container and how to
verify that it actually works would have been quite nice. Therefore, I
wrote the following "quickstart" and hopefully it will save time for
someone else. Please comment!


= Configuring TLS =

In order to configure TLS you will have to obtain a public/private
key, a X.509 certificate, add those to the Java keystore and
optionally add certificates from a known CA (certicate authority). The
entire process can be confusing but in order to get a basic setup for
testing purposes up and running with minimal effort, this section
starts off with a simple Quickstart. However, for production
environment you need to obtain an officially signed certificate from a
known CA and that process is outlined in section XXX.

== Quickstart – Server side authentication ==

This section shows how to create a self signed certificate, how to add
that to the Java keystore and how to configure the SIP Servlet
Container to make use of this configuration. Note, this section should
only be used in a development environment and the main reason for this
quickstart section is to get you going right away as well as get you
comfortable with generating keys and certificates and adding them to
the Java keystore.

At a high-level, we will execute the following three steps:
1. Generate a public/private key pair and a self signed certificate
and add those to the Java keystore.
2. Configure the SIP Servlet Container to load our certificate from
the keystore.
3. Test!

=== Step 1 – Generate certificate ===

Generating a new key-pair and a certificate can be done in a few
different ways with a few different tools but here we will just use
the java keytool that comes with the JDK. Simple issue the following
command, which will generate a new public and private key, generate a
self-signed certificate and add it all to the Java keystore:

keytool -genkeypair -alias myserver -keyalg RSA -keysize 1024 -keypass
secret -validity 365 -storetype jks -keystore myserver.jks -storepass
secret -v -dname "CN=James Smith, OU=Engineering, O=My Company, L=My
City, S=My State, C=US"

A few things to point out:

-keystore specifies which keystore we should use/update. If the
keystore doesn't exist, a new one will be created for one. In the
above example, we named the keystore “myserver.jks” and it will be
saved in the current directory

-keypass and -storepass should be chosen wisely since with bad
passwords you won't have much protection anyway. Also, normally you
should never passwords on the command prompt, it is too easy for other
people to steal. If you leave these two options out, the keytool
command will ask you for it.

-keyalg specifies which algorithm to use when generating the keys and
the keysize how long those keys should be.

Note: the command -genkeypair is new in JDK 6 and was previously named
-genkey. The keytool in JDK 6 has some improvements over the previous
versions so it is recommended to use it instead.

See more about the Java keytool here:
http://docs.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html

=== Step 2 – Configure the SIP Servlet Container ===

The SIP Servlet Container relies on the JAIN SIP stack to support it
with TLS capabilities. As such, it is the JAIN SIP stack that we need
to configure to have it read our certificate we added to the key
store. The various configuration options are described in the javadoc
of the SipStackImpl [link] class but for this quickstart, we will be
using the following ones:

javax.net.ssl.keyStore – the filename and location of the keystore to use.
javax.net.ssl.keyStorePassword – the password to the keystore.
gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE – which type of authentication
we will require of the client.

The configuration options are JVM parameters and you will have to add
these to the command line when you start the server:

./bin/run.sh -Djavax.net.ssl.keyStorePassword=mysecret
-Dgov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE=Disabled
-Djavax.net.ssl.keyStore=/path/to/your/keystore/myserver.jks

Once the server is up, we are ready to verify that we can get a TLS
connection using the certificate we previously added in Step 1.

Note: for this first part of the quickstart we will not require a
certificate from the client since this involves more configuration.
This is controlled by the gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE
parameter.

=== Step 3 – Test! ===

To verify your setup there are a few different tools that you can use.
openssl is an open source SSL toolkit and contains a generic SSL/TLS test client
SIPp – an open source SIP load testing tool that is capable of using
TLS. However, it requires some additional steps that we have not
addressed in the first parf of this quickstart so therefore we willl
not be using SIPp.
Using your favorite SIP client. Most SIP clients out there are capable
of establishing a TLS connection but you will have to consult its
documentation of how to configure TLS.

Using openssl:

Assuming that your server is running on localhost and is listening for
TLS on port 5081 the command would be:

openssl s_client -host 127.0.0.1 -port 5081

If you are successful you should see an output from openssl displaying
information about the server certificate (which should be the one we
generated in Step 1). If there are any issues with the setup, openssl
is pretty good about giving out information about what it thinks is
wrong.

Tip: if you add the following JVM parameter as well you will get a lot
of useful debug information:
-Djavax.net.debug=ssl

== Quickstart – require client certificate ==

In the first quickstart we generated a public and private key along
with a self-signed certificate and added them all into the Java
keystore. The server was then configured to use this information and
when a client connected, our certificate was served up to the client.
However, normally, the client and the server would like to verify each
others certificate to make sure they both trust each other and if not,
either of them will terminate the connection. In the first part of the
quickstart, the server did not require the client to present a
certificate when connecting (remember that we set the
gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE to disabled) so let's do that
now.

At a high-level, these are the tasks we need to execute:
generate a public/private key pair for the client along with a certificate.
The server need to add the client certificate to its keystore as a
trusted certificate.
Start the server with client authenticating enabled.

=== Step 1 – Generate client certificate ===

We will use the Java keytool for this step in the same we did for for
the server side in the previous quikstart. The command is exactly the
same and the only difference is that we store the information in a new
keystore called “myclient.jks”.

keytool -genkeypair -alias myclient -keyalg RSA -keysize 1024 -keypass
secret -validity 365 -storetype jks -keystore myclient.jks -storepass
secret -v -dname "CN=John Doe, OU=Engineering, O=Some Work, L=Some
City, S=Some State, C=US"

We have now generated a new keystore containing the clients
authentication information. However, the server needs to import the
client certificate into its trusted keystore so we need to extract the
certificate out of the client key store. This can also be done using
the Java keytool.

keytool -exportcert -alias myclient -file client.cert -keystore
myclient.jks -storepass secret -rfc

The certificate is saved in file “client.cert” and we will use this
file in the next step.

=== Step 2 – add the client certificate to the server trust store ===

When the client connects to the server, the server can require that
the client presents a certificate of its own. If the certificate is
trusted, the client connection is accepted. In order to import a
trusted certificate use the keytook “importcert” command:

keytool -importcert -file client.cert -storepass secret -keystore
myserver.jks -trustcacerts

=== Step 3 – Re-configure the server ==

Simply change the gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE from
“Disabled” to “Enabled” and start the server again.

=== Step 4 – Test ===

We will once again use openssl to verify our setup but now that the
client will be forced to present a certificate as well, we do need the
certificate's private key as well. The private key is embedded into
the keystore and was generated when we issued the “kenkeypair”
keytool-command. Unfortunately, the keytool does not have an option
for exporting the private key so we will have to write a small java
program to extract it for us. Luckily, it is not a lot of code:

[http://stackoverflow.com/questions/150167/how-do-i-list-export-private-keys-from-a-keystore]

Simply compile it:

javac DumpPrivateKey.java

and then use it to extract the private key:

java DumpPrivateKey myclient.jks secret myclient > clientprivate.key

Now that we have the private key of the client we can use openssl to
verify the setup again:

openssl s_client -host 127.0.0.1 -port 5081 -cert client.cert
-certform PEM -key clientprivate.key

If all goes well you should successfully establish a connection and
openssl will dump information about the certificate exchange.

== Production setup ==

TODO

Jonas Borjesson

unread,
Jan 22, 2012, 11:50:28 PM1/22/12
to mobicent...@googlegroups.com
Btw, here are two links to the best information about configuring a
keystore that I managed to find.

http://www.informit.com/articles/article.aspx?p=407886
http://docs.codehaus.org/display/JETTY/How+to+configure+SSL

/Jonas

Bartosz Baranowski

unread,
Jan 23, 2012, 4:01:43 AM1/23/12
to mobicent...@googlegroups.com
Very much appreciated contribution. Possibly this should be included in MSS docs? JD?
Bartosz Baranowski
JBoss R & D
==================================
Word of criticism meant to improve is always step forward.

Vilius Panevėžys

unread,
Jan 23, 2012, 4:09:05 AM1/23/12
to mobicent...@googlegroups.com
Yeah, great piece of documentation! I love that you've resisted HTML and
did a clean and simple plain text mark-up, which is the most portable
format. :)


--
Vilius Panevėžys
Elitnet

Jonas Borjesson

unread,
Jan 23, 2012, 12:34:17 PM1/23/12
to mobicent...@googlegroups.com
Cool, thanks guys. Yeah, I spoke with Jean and once people have given
me feedback on this email I will turn it into docbook and supply a
patch. Just wanted to get a first feel from the community as well.
Also, I would like to add the last section about how to set it up for
production. I personally don't like documentation that isn't complete
and has entries such as "there are plenty of documents out on the
internet explaining this so ask Google" - docs are important! (albeit
boring to write)

Once I have received some more feedback I'll spend some time
re-writing it to fit the language of the official documentation and if
anyone feel like helping out proof reading I would very much
appreciate it.

/Jonas

2012/1/23 Vilius Panevėžys <vil...@elitnet.lt>:

Ibrahima Gaye

unread,
Jan 23, 2012, 1:29:54 PM1/23/12
to mobicent...@googlegroups.com
" if
anyone feel like helping out proof reading I would very much
appreciate it. "
a volunteer here :)
------
Ibrahim

Jonas Borjesson

unread,
Feb 5, 2012, 7:43:55 PM2/5/12
to mobicent...@googlegroups.com
Hey guys,

So, finally found some time to add another small section regarding
production setup and turn the whole thing into docbook etc. I have
been trying to follow the convention regarding listings, variable
names etc etc but I'm sure I missed something...

Also, Jean suggested to split out the previous section regarding SIP
Servlet Application Security and merge it with my TLS section and move
both of them into a chapter of their own, called Security, which is
what I have done. For easy read, I have attached the html version of
that chapter (along with the css but no images) to this email but you
will also find the patch attached

/Jonas


2012/1/23 Ibrahima Gaye <ibrahi...@gmail.com>:

chapter_7_security.tar.gz
chapter_7_security.diff

Bartosz Baranowski

unread,
Feb 6, 2012, 2:51:49 PM2/6/12
to mobicent...@googlegroups.com
Nice. Greatly appreciated! This should save some google search time :)

Bartosz Baranowski
JBoss R & D
==================================
Word of criticism meant to improve is always step forward.


Jean Deruelle

unread,
Feb 7, 2012, 8:06:59 AM2/7/12
to mobicent...@googlegroups.com
Thanks Jonas,

Great work, that is greatly appreciated !
I created an issue here http://code.google.com/p/mobicents/issues/detail?id=3082 to include your changes and review them.

Jean

Ivelin Ivanov

unread,
Feb 7, 2012, 2:13:31 PM2/7/12
to mobicent...@googlegroups.com
Thanks, Jonas! Good quality document contributions are rare and most welcome.

Ivelin

Asbjorn Grandt

unread,
Feb 20, 2012, 8:11:33 AM2/20/12
to mobicent...@googlegroups.com
Does this enable the initiation of a TLS connection when contacting a
SIP server?

If so, how is that done?

I need to talk to a Microsoft OCS/Lync server, and it requires all
communication to be TLS encrypted.

I previously asked about the same setup, where the topic were the NTLM
authentication. That is fairly trivial to do it seems. Setting up the
SipServlet container to initiate a connection inside TLS are
unfortunately not very easy to figure out.

Cheers

Jean Deruelle

unread,
Feb 20, 2012, 10:48:28 AM2/20/12
to mobicent...@googlegroups.com
Hey Asbjorn,

Yes it does. Make sure you to use SIPS URIs and transport TLS when sending the request out after you have setup the certificates accordingly.
I didn't have time to review the documentation contribution fro Jonas yet but you can find the diff here as an attachment http://groups.google.com/group/mobicents-public/msg/dcccd3c5bdb93a24 that gives you step by step information. Feel free to comment on the contribution if there is anything missing.

If you get the NTLM setup and OCS/Lync interop to work on it, it would be very interesting for the community as well to document the process if you would care to do that :-)

Thanks
Jean

Jonas Borjesson

unread,
Feb 21, 2012, 12:22:27 AM2/21/12
to mobicent...@googlegroups.com
Yep, should work just fine. In your case you probably want to enable
client certificate validation as well, something I didn't add to that
guide so feel free to add that. The only thing you really need to do
is to add the public certificate from your Microsoft OCS/Lync server
and then change the gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE to Enabled
(note, seems to be case sensitive) and it should work just fine.

/Jonas

Reply all
Reply to author
Forward
0 new messages