Build an IMS using OpenSIPS 3.5 – S-CSCF (Part 1)

The main focus of the OpenSIPS 3.5 development plan is to facilitate and provide the tools required to build robust, production-ready, industry-grade IMS solutions. To this goal we have been working on new features and functionalities in OpenSIPS 3.5 that aim to simplify the IMS development process while still provide the required specifications.

This post is the first one among a series of articles that describe how to build an IMS solution using OpenSIPS 3.5. It focuses on the S-CSCF (Serving – Call Session Control Function) component of an IMS setup, and presents the new features we have developed for it, such as:

  • Asynchronous Diameter queries
  • AKA authentication
  • Miscellaneous enhancements

Throughout this article we will describing what these new feature do, and what they bring to the table.

Asynchronous Diameter queries

The Diameter protocol plays an important role at the core of EPS (Evolved Packet Switching/3G networks) and LTE (Long Term Evolution/4G networks) technologies. Specifically, for an IMS S-CSCF, it is being used to communicate with the HSS (Home Subscriber Server) and/or an SLF (Subscription Locator Function) to find out the location of a user. Specifications of this communication are described in ETSI TS 129 229 as the Cx/Dx Interface, which describes the Diameter messages exchanges that need to happen for every user actions (such as registration, de-registration or calling, etc).

Since every action may require one, or a series of multiple Diameter request-answer queries, optimizing them became a priority – that is why we enhanced OpenSIPS 3.5 with asynchronous capabilities for running Diameter queries. This means that a process that is handling a request will no longer block its execution waiting for a Diameter answer for a given command, but rather release it to handle other requests, increasing the overall throughput of the solution.

In terms of usage, the asynchronous dm_send_request function receives the same arguments as its synchronous sibling, it only needs to adapt to the asynchronous way of handling requests. A classic example would be the s-CSCF running a SAR (Server-Assignment-Request) command when a user registers, which may look like this:

route {
...
$var(payload) = "[
{ \"Session-Id\": \"scscf.ims.mnc001.mcc001.3gppnetwork.org;"+$Ts+"."+$Tsm+";"+$pp+"\" },
{ \"Origin-Host\": \"scscf.ims.mnc001.mcc001.3gppnetwork.org\" },
{ \"Origin-Realm\": \"ims.mnc001.mcc001.3gppnetwork.org\" },
{ \"Destination-Realm\": \"ims.mnc001.mcc001.3gppnetwork.org\" },
{ \"Vendor-Specific-Application-Id\": [{\"Vendor-Id\": 10415},
{\"Auth-Application-Id\": 16777216}]},
{ \"Auth-Session-State\": 1 },
{ \"User-Name\": \""+$fU+"@"+$fd+"\" },
{ \"Public-Identity\": \""+$fu+"\" },
{ \"Server-Assignment-Type\": 1 },
{ \"User-Data-Already-Available\": 0},
{ \"Server-Name\": \"sip:scscf.ims.mnc001.mcc001.3gppnetwork.org:6060\" }
]";

if (!async(loadmodule "auth_aka.so"
modparam("auth_aka", "default_av_mgm", "diameter")
loadmodule "aka_av_diameter.so"
modparam("aka_av_diameter", "realm",
"scscf.ims.mnc001.mcc001.3gppnetwork.org")
modparam("aka_av_diameter", "aaa_url",
"diameter:/etc/opensips/freeDiameter.conf;extra-avps-file:/etc/opensips/scscf.dictionary")dm_send_request(16777216, 301, $var(payload), $var(rpl_avps)), dm_resume_sar))
t_reply(500, "Internal Error");
exit;
...
}

route[dm_resume_sar]
{
if ($rc) {
# all good - we successfully assigned the server to the User
append_to_reply("Service-Route: <sip:orig@scscf.ims.mnc001.mcc001.3gppnetwork.org:6060;lr>\r\n");
append_to_reply("P-Associated-URI: <$fu>\r\n");
append_to_reply("Path: $hdr(Path)\r\n");
t_reply(200, "OK");
}
}

AKA Authentication

While IMS allows subscribers to authenticate to the IMS engine using different authentication mechanisms (i.e. plain Digest-Authentication, NASS-Bundle, Early-IMS-Security, etc), ETSI TS 129 229 specifications indicate IMS-AKA as a requirement. And since OpenSIPS did not have support for it in previous versions, we had to implement it from scratch.

This is how the new AUTH_AKA module appeared, to allow OpenSIPS to authenticate subscribers using the AKA (Authentication and Key Agreement) mechanisms defined in RFC 3310. This mechanism aims to provide mutual authentication between an UE and the IMS engine by using a set of AVs (authentication vectors) that are exchanged between UE, HSS and CSCF over a different (control) channel than (data) SIP. Once retrieved by the S-CSCF, they are being used in the digest authentication process.

Since AVs should be exchanged over separate channels, we decided the module should be agnostic to the fetching method. Thus, it does not explicitly do any fetching of AVs, but simply provides an interface for other modules to do it and fed them to the authentication process. When a new AV is needed for a challenge, it asks one of the AV Manager modules (that implement its interface) for it. It’s the manager’s job to fetch the AV (over whatever channel it implements) and push it back to the auth_aka module to continue the digest process.

The new AKA_AV_DIAMETER is an example of such a AV manager module that fetches the AVs using the Cx Diameter interface and feeds them back to the auth_aka module through its interface. In the future, other managers can be developed, for example to fetch the AVs through HTTP/2 queries, as required by the 5G Service-Based Architectures specs in ETSI TS 123 501.

The auth_aka module works in both synchronous and asynchronous ways, however, to optimize resource consumption, you should always use the asynchronous mode. The AV manager modules (i.e. aka_av_diameter) should also be prepared to work in asynchronous mode when fetching the AVs, otherwise the whole process will fallback to synchronous mode.

The usage of the auth_aka and aka_av_diameter modules in scripts should be as simple any other authentication methods in OpenSIPS: load the module, and if you cannot authenticate the user, you challenge it for a the secret. A simple usage would look like:

loadmodule "aaa_diameter.so" # makes the Diameter queries
loadmodule "auth_aka.so" # authenticates using AKA
loadmodule "aka_av_diameter.so" # fetches AVs over diameter

modparam("auth_aka", "default_av_mgm", "diameter")
modparam("aka_av_diameter", "realm",
"scscf.ims.mnc001.mcc001.3gppnetwork.org")
modparam("aka_av_diameter", "aaa_url",
"diameter:/etc/opensips/freeDiameter.conf;extra-avps-file:/etc/opensips/scscf.dictionary")

While the AUTH_AKA module supports both AKAv1 and AKAv2 algorithms, along with its (hash) variants, due to limited testing environment, only AKAv1-MD5 algorithm has been tested so far. However, starting with ETSI TS 129 229 V17.2.0(2022-07), AKAv1 method is recommended only for backwards compatibility, and AKAv2 (RFC 4196) should be used instead. Thus, AKAv2 will soon be tested and adjusted accordingly.

Miscellaneous enhancements

In order to provide full IMS solutions, some minor enhancements had to be developed as well. For example, since the AVs exchanged between the S-CSCF and HSS contain binary information, we were unable to specify them in a JSON format. Thus, we created an extra layer of encoding between the way we provision the Diameter query, and the diameter engine which builds the command, allowing us to use arbitrary binary data in communication with the HSS. This means that in the script you can provide binary data in JSON by encoding it in hexa format – the module will internally detect it, based on its AVP’s description in the extra AVPs file and convert it to the required format in the Diameter request. Similarly, binary values can be retrieved in the script.

Additionally, IP addresses must be binary encoded in their network format – support for converting them from plain IP strings to network has been developed as well.

Conclusion

Using the new features described throughout the article, as well as previously existing ones, one can build a fully working S-CSCF component in IMS. All you need to do is put all of them together in a script that implements your personal requirements. In the future, we are planning to provide ourselves a solution that wraps up all these features in a script, that can be easily shipped for you to test. We will update you once it is available.

Most of the work was done with the help of the OpenSIPS community through the OpenSIPS IMS Working Group, whom we would like to thank for their contribution.

We will be presenting all our work during our anual OpenSIPS Summit 2024 event, this time taking place on 14-17 of May 2024 in Valencia, Spain. Make sure you do not miss it!

Leave a comment