OpenSIPS#

OpenSIPS is an open-source SIP signaling server for routing calls between SIP devices, PBX systems, and service providers.

This guide explains how to connect OpenSIPS 4.0 to DIDWW SIP Trunking for inbound and outbound calling. It covers configuring DIDWW inbound and outbound SIP trunks, assigning DID numbers, and routing calls between DIDWW and a user agent behind OpenSIPS.

The inbound configuration supports Static Endpoint and Dynamic Registration trunks. The outbound configuration uses SIP digest authentication. No database is required.

Important

OpenSIPS handles SIP signaling only in this configuration. A user agent is required to handle call media. Add the user agent’s public RTP address to the allowed RTP addresses of the DIDWW inbound and outbound trunks.


1. Configure inbound voice trunk#

Configure an Inbound SIP Trunk in the DIDWW User Panel to send incoming calls from your DIDWW numbers to OpenSIPS. Select the delivery method that matches your OpenSIPS deployment.

Before you begin#

Step 1: Create New Inbound SIP trunk#

  1. In the DIDWW User Panel, go to Voice > Inbound Trunks.

  2. Click Create New > SIP Trunk.

Creating a new inbound SIP trunk

Creating a new inbound SIP trunk.#

Step 2: Configure general SIP trunk settings#

In the Create Inbound SIP Trunk form, enter the settings for the selected trunk type.

  1. Enter a descriptive Name for the trunk (e.g., OpenSIPS).

  2. Select Static Endpoint as the trunk Type.

  3. In Host, enter the public IP address of the OpenSIPS server or a domain name that resolves to it.

  4. Select UDP as the signaling Transport and enter 5060 as the Port. These values must match the OpenSIPS listening socket.

  5. Set User Part of R-URI to {DID}. This placeholder inserts the called DID in E.164 format into the user part of the Request-URI.

  6. Leave Preferred Server at Auto unless calls must originate from a specific Point of Presence.

Configuring a Static Endpoint inbound SIP trunk for OpenSIPS

Static Endpoint trunk settings.#

  1. Enter a descriptive Name for the trunk (e.g., OpenSIPS).

  2. Select Dynamic Registration as the trunk Type.

  3. Configure the remaining media and signaling settings required by your deployment.

Configuring Dynamic Registration and Use DID in R-URI for OpenSIPS

Dynamic Registration trunk settings.#

For either trunk type, open Media & DTMF and configure the following:

  1. Enter the user agent’s public RTP address in Allowed RTP IP Addresses. OpenSIPS does not relay RTP in this configuration.

  2. Enable Force Symmetric RTP if the user agent is behind NAT.

Important

Keep Allowed RTP IP Addresses configured when using Force Symmetric RTP to restrict accepted media sources. Leaving the address list empty allows RTP from any source.

Configuring codecs and allowed RTP addresses for the user agent

Inbound trunk media settings.#

Step 3: Click Create and Save Inbound SIP Trunk Configuration#

When all required fields in the Create Inbound SIP Trunk form are filled, click Create to save the trunk.

Note

For advanced SIP trunk configuration, see Advanced Inbound SIP Trunk documentation.

Saving the OpenSIPS Static Endpoint inbound SIP trunk

Creating the Static Endpoint inbound SIP trunk.#

Saving the OpenSIPS Dynamic Registration inbound SIP trunk

Creating the Dynamic Registration inbound SIP trunk.#

Step 4: Copy Inbound Trunk Credentials (Dynamic Registration Only)#

For a Dynamic Registration trunk, open the created trunk and copy its generated username, password, and registration endpoint. You will use these values when you register the inbound trunk. Static Endpoint trunks do not use registration credentials.

Note

The example registers with sip.didww.com. A regional endpoint such as ams.sip.didww.com registers the trunk with a specific location. OpenSIPS takes the registration digest realm from the registrar’s challenge.

Viewing generated Dynamic Registration credentials and endpoints

Dynamic Registration credentials and endpoints.#

Step 5: Assign inbound SIP trunk to your DID numbers#

After creating the Inbound SIP Trunk for OpenSIPS, assign it to the DID number(s) that will deliver incoming calls to OpenSIPS.

  1. In the DIDWW User Panel, go to Phone Numbers > My Numbers.

  2. Select the DID number(s) you want to assign to the inbound SIP trunk.

  3. At the bottom of the page, click Batch Actions > Update Trunks.

Selecting DID numbers and Update Trunks from the Batch Actions menu

Selecting Update Trunks from the Batch Actions menu.#

  1. From the dropdown menu, choose the OpenSIPS SIP trunk created in Step 3.

  2. Click Confirm to apply the changes.

Assigning the OpenSIPS inbound SIP trunk to DID numbers

Assigning the newly created SIP trunk to the selected DID(s).#


2. Configure outbound voice trunk#

Configure an Outbound SIP Trunk in the DIDWW User Panel to allow OpenSIPS to place outbound calls through DIDWW. This trunk provides the SIP credentials and routing settings required for outbound calls to external phone numbers.

Before you begin#

Access to DIDWW Outbound Trunks is required for making outbound calls. See Get access to outbound trunks.

Step 1: Create New Outbound SIP Trunk#

  1. In the DIDWW User Panel, go to Voice > Outbound Trunks.

  2. Click Create New.

Creating a new outbound SIP trunk

Creating a new outbound SIP trunk.#

Step 2: Configure Authentication#

  1. Update the Friendly Name (e.g., OpenSIPS).

  2. Keep the default Credentials & IP-Based authentication method selected. The SIP digest credentials will be provided after the trunk is created.

  3. Leave Tech Prefix empty for this example.

  4. In Allowed SIP IP addresses, enter the public IP address or subnet from which OpenSIPS will send outbound SIP traffic.

  5. In Allowed RTP IP addresses, enter the public address from which the user agent will send RTP.

  6. Configure Allowed CLI(s) and the other termination settings required by your deployment.

Note

At least one Allowed SIP IP address is required. The trunk accepts up to 60 SIP addresses or subnets. If you configure a Tech Prefix, the outgoing Request-URI must include it before the dialed number.

Configuring authentication and allowed SIP and RTP addresses for OpenSIPS

Outbound trunk authentication settings.#

Important

The caller ID must match the value set by uac_replace_from() in the OpenSIPS outbound route. A call can pass digest authentication and still be rejected by the trunk’s CLI or destination settings.

Step 3: Click Create and Save Outbound SIP Trunk Configuration#

When all required fields in the Create Outbound SIP Trunk form are filled, click Create to save the trunk.

Note

For advanced outbound SIP trunk configuration, see Outbound SIP Trunk Guide.

Saving the OpenSIPS outbound SIP trunk

Creating the outbound SIP trunk.#

Note

Check that the trunk’s Status is enabled before testing calls. Reaching the rolling 24-hour limit disables the trunk, blocks new calls, and disconnects active calls shortly afterward. Review usage before enabling the trunk again.

Step 4: View Outbound Trunk Credentials#

After the outbound trunk is created, you can view its credentials by selecting the key icon in the Credentials column on the Outbound Trunks page.

  1. Go to Voice > Outbound Trunks.

  2. Locate your outbound trunk and click the key icon in the Credentials column.

Selecting the credentials icon for the OpenSIPS outbound trunk

Opening the OpenSIPS outbound trunk credentials.#

  1. The trunk credentials will appear, showing the Username and Password (click the eye icon to reveal the password).

  2. Copy and securely store the credentials, and choose an outbound endpoint from Host(s). You will use them when you configure outbound routing.

Viewing the OpenSIPS outbound trunk credentials and hostnames

OpenSIPS outbound trunk credentials and hostnames.#

The example uses ams.eu.out.didww.com. See Outbound SIP information for regional endpoints, DNS SRV failover, and BGP Anycast.

Important

The outbound digest authentication realm is out.didww.com for all DIDWW outbound endpoints. Use this value in the uac_auth credential, even when calls are sent to a regional hostname or any.out.didww.com.

Note

If an outbound password is exposed, regenerate it in the DIDWW User Panel. Regenerating the password invalidates the previous value immediately. Update the OpenSIPS credential and restart the proxy to use the new value.


3. Configure OpenSIPS#

Configure OpenSIPS to use the DIDWW trunks created in Part 1 and Part 2. The script routes calls between DIDWW and one user agent and authenticates outbound calls without a database.

The examples use /etc/opensips/opensips.cfg and the module directory for an x86-64 installation. They use UDP on port 5060. Replace the example addresses, caller ID, and uppercase credential placeholders with the values for your deployment.

Note

For general information about the script and its routing model, see the official Types of routes and Core Parameters documentation.

Before you begin#

  • OpenSIPS 4.0 is required.

  • Install opensips-auth-modules to provide the uac_auth module for outbound digest authentication.

  • If you use a Dynamic Registration inbound trunk, install OpenSIPS CLI to manage the registration.

Step 1: Configure the OpenSIPS script#

The same OpenSIPS script supports Static Endpoint and Dynamic Registration trunks. Dynamic Registration additionally requires the registration in Step 3.

The following blocks build /etc/opensips/opensips.cfg in order. Back up the current file, then replace its contents with the global parameters, module settings, and routing blocks below.

The examples use the following deployment values. Replace them consistently before loading the configuration.

Value in this guide

Replace with

203.0.113.10

The public address through which DIDWW can reach OpenSIPS.

192.168.1.20

The address of the user agent behind OpenSIPS.

1000

The user agent extension that receives incoming calls.

442079460000

A caller ID permitted by the outbound trunk’s CLI settings.

ams.eu.out.didww.com

The outbound endpoint selected from the trunk’s credentials.

OUTBOUND_USERNAME and OUTBOUND_PASSWORD

The outbound trunk credentials.

INBOUND_USERNAME and INBOUND_PASSWORD

The Dynamic Registration trunk credentials used when you register the inbound trunk.

1.1 Configure the listening socket and advertised address#

Begin the file with the global parameters:

log_level=3
stderror_enabled=yes
syslog_enabled=no
udp_workers=4

socket=udp:0.0.0.0:5060
advertised_address="203.0.113.10"

Set advertised_address to the public address of the proxy or the NAT device in front of it. This is normally the same address configured in the outbound trunk authentication settings.

The process writes logs to standard error at info level. Use this output when verifying calls.

Important

The advertised address must be reachable by DIDWW. OpenSIPS uses it in Via and Record-Route headers. With the wildcard socket in this example, leaving it unset can advertise 0.0.0.0 and prevent an ACK from reaching the proxy. A call may connect and then disconnect after approximately 30 seconds. Adding rport does not correct the address used to route this request.

1.2 Load the required modules and credentials#

Add the module settings below the global parameters:

mpath="/usr/lib/x86_64-linux-gnu/opensips/modules/"

loadmodule "proto_udp.so"
loadmodule "signaling.so"
loadmodule "sl.so"
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)

loadmodule "rr.so"
modparam("rr", "append_fromtag", 1)

loadmodule "maxfwd.so"
loadmodule "sipmsgops.so"

loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)

loadmodule "uac_auth.so"
modparam("uac_auth", "credential", "OUTBOUND_USERNAME:out.didww.com:OUTBOUND_PASSWORD")

loadmodule "uac.so"
modparam("uac", "restore_mode", "none")

loadmodule "uac_registrant.so"
modparam("uac_registrant", "hash_size", 2)
modparam("uac_registrant", "timer_interval", 30)

Set mpath to the module directory for your installation. The example uses the x86-64 directory.

Replace OUTBOUND_USERNAME and OUTBOUND_PASSWORD with the outbound trunk credentials. Keep out.didww.com as the digest realm. Inbound registration credentials are supplied separately in Step 3.

The FIFO path is the default used by opensips-cli. The registration timer runs every 30 seconds. With the 60-second expiry in Step 3, the proxy refreshes the registration every 30 seconds to help keep the NAT mapping active.

Note

Keep the following settings from the tested configuration:

  • loadmodule "proto_udp.so" is required in the tested build even though a separate module file is not present. Omitting it causes no transport protocol loaded at startup.

  • append_fromtag must be 1 for uac_auth(), including when restore_mode is none.

  • The tested build logs ERROR:uac:mod_init: Can't load dlg API while checking for the dialog API. It can continue without that API. Check subsequent output to confirm whether startup succeeded.

1.3 Configure the DIDWW ACL#

Open the main route with the request checks and DIDWW source-address match:

route {

    if (!mf_process_maxfwd_header(10)) {
        send_reply(483, "Too Many Hops");
        exit;
    }

    if (has_totag()) {
        if (is_method("ACK") && t_check_trans()) {
            t_relay();
            exit;
        }
        if (!loose_route()) {
            send_reply(404, "Not here");
            exit;
        }
        route(RELAY);
        exit;
    }

    if (is_method("CANCEL")) {
        if (t_check_trans())
            t_relay();
        exit;
    }

    if (is_method("OPTIONS")) {
        send_reply(200, "OK");
        exit;
    }

    if (!is_method("INVITE")) {
        send_reply(405, "Method Not Allowed");
        exit;
    }

    t_check_trans();
    record_route();

    if ($si =~ "^46\.19\.(2(08|09|1[0-5]))\." || $si =~ "^185\.238\.17[2-5]\.") {

The source-address expressions cover 46.19.208.0/21 and 185.238.172.0/22. These ranges contain the published DIDWW IPv4 signaling addresses used by the tested configuration.

Important

Allow the DIDWW sources for the selected trunk type and failover locations. With Preferred Server set to Auto, calls can arrive from different DIDWW Points of Presence. See Technical Specifications for the signaling addresses and network requirements.

The example opens an IPv4 socket only. An IPv6 deployment requires additional socket and source-address configuration.

1.4 Configure inbound routing#

Continue inside the DIDWW branch opened in the previous block:

        xlog("L_INFO", "inbound from carrier $si ruri=$ru from=$fu callid=$ci\n");
        $ru = "sip:1000@192.168.1.20:5060";
        route(RELAY);
        exit;
    }

Replace the URI with the extension, address, and port of the user agent behind OpenSIPS. The xlog line records incoming requests for call testing.

Important

This example rewrites the Request-URI for every incoming call and sends all DIDs to one destination. Keep the unconditional rewrite when using this setup. Routing by called number requires a separate configuration and confirmation of the Request-URI delivered by your trunk.

To serve several DIDs and route calls by the called number, use a Static Endpoint trunk. DIDWW builds the Request-URI from User Part of R-URI, so the number is included in the request line. Dynamic Registration trunks cannot be distinguished by DIDWW source address because calls arrive from the same DIDWW ranges. Separating them requires individual registration sockets and routing based on the inbound socket, which is outside this guide.

1.5 Configure outbound routing and digest authentication#

Below the DIDWW branch, add the user-agent match and outbound routing:

    if ($si == "192.168.1.20") {
        add_local_rport();
        uac_replace_from("", "sip:442079460000@ams.eu.out.didww.com");
        $ru = "sip:" + $rU + "@ams.eu.out.didww.com";
        t_on_failure("CARRIER_AUTH");
        route(RELAY);
        exit;
    }

    send_reply(403, "Forbidden");
    exit;
}

route[RELAY] {
    if (!t_relay())
        sl_reply_error();
    exit;
}

failure_route[CARRIER_AUTH] {
    if (t_was_cancelled())
        exit;

    if (t_check_status("401|407")) {
        if (uac_auth()) {
            t_relay();
            exit;
        }
        xlog("L_ERR", "uac_auth() failed for callid=$ci\n");
    }
}

Replace 192.168.1.20 with the user agent’s address. Replace 442079460000 with the permitted caller ID and ams.eu.out.didww.com with the selected outbound endpoint in both URIs.

The digest realm in the module settings remains out.didww.com regardless of the outbound endpoint.

Note

  • add_local_rport() adds rport to relayed requests so responses can return to the source port used by a NAT device.

  • uac_replace_from() takes two arguments in OpenSIPS 4.0. The first is the display name, which is empty in this example.

  • DIDWW can challenge an outbound INVITE with 401 and WWW-Authenticate. The failure route handles both 401 and 407 responses.

Important

DIDWW checks the caller ID written by uac_replace_from() against CLI Settings. A successful digest exchange does not override caller ID restrictions. With On CLI Mismatch set to Reject Call, an unlisted caller ID causes the call to fail.

1.6 Add rport to locally generated requests#

Add a local route for requests generated by OpenSIPS, including registration:

local_route {
    add_local_rport();
}

The outbound route’s add_local_rport() applies to relayed requests. This local route also adds rport to REGISTER requests generated by the proxy. Without it, a NAT device that changes the source port can prevent registration responses from returning.

Step 2: Load the configuration#

Check that the configuration parses:

opensips -C -f /etc/opensips/opensips.cfg

Important

config file ok, exiting... confirms that the script parses. This check does not initialize the modules. Start OpenSIPS and review the startup output as well.

Start OpenSIPS in the foreground:

opensips -F -f /etc/opensips/opensips.cfg

Leave OpenSIPS running. If you use a Dynamic Registration trunk, open another terminal and complete Step 3.

Step 3: Register the inbound trunk#

Complete this step for a Dynamic Registration trunk. Skip it for a Static Endpoint trunk.

Submit the registration through the management interface:

opensips-cli -x mi uac_registrant:upsert \
    aor="sip:INBOUND_USERNAME@sip.didww.com" \
    contact="sip:INBOUND_USERNAME@203.0.113.10:5060" \
    registrar="sip:sip.didww.com" \
    proxy="" \
    third_party_registrant="" \
    username="INBOUND_USERNAME" \
    password="INBOUND_PASSWORD" \
    binding_params="" \
    expiry=60 \
    forced_socket="" \
    cluster_shtag="" \
    state=0

Replace the username and password with the inbound trunk credentials. Use the selected registration endpoint for the address-of-record domain and registrar. Set the contact address to the public address and port through which DIDWW can reach OpenSIPS.

All 12 parameters are required, including those with empty values. Missing parameters return Invalid params (Too few or too many parameters). Incorrect parameter names return Invalid params (Named parameters do not match).

Important

An OK response confirms that the registration record was accepted. Run opensips-cli -x mi uac_registrant:list and check the state field to confirm registration:

  • REGISTERED_STATE indicates a successful registration.

  • NOT_REGISTERED_STATE can appear until the registration timer processes the record, which may take up to 30 seconds.

  • WRONG_CREDENTIALS_STATE indicates rejected credentials.

The registration is supplied at runtime through the management interface, so this setup does not require a database. The short expiry and registration timer help maintain the inbound NAT mapping.

Important

The registration record is created at runtime and is not stored in a database. Submit the registration command again after restarting OpenSIPS.

Step 4: Verify the configuration#

Check

Action

Expected result

Listening socket

Review the startup output.

A Listening on block includes udp: 0.0.0.0 [0.0.0.0]:5060.

Dynamic Registration

Run opensips-cli -x mi uac_registrant:list.

The state field shows REGISTERED_STATE.

Inbound calling

Call a DID assigned to the inbound trunk.

The process output includes the inbound xlog message from inbound routing.

Outbound calling

Place a call from the user agent.

The SIP trace shows a 401 challenge, a second INVITE with authentication, and a 200 OK response.

Check the user agent as well to confirm that incoming calls are received and audio works in both directions.

Common issues#

Calls disconnect after approximately 30 seconds

Check advertised_address. An unreachable address in Record-Route prevents DIDWW from delivering the ACK. The user agent retransmits 200 OK until the call times out. See listening socket and advertised address.

An inbound call does not reach the user agent

Check for the inbound xlog message. If it is missing, confirm that the request reached OpenSIPS and that its source matched the DIDWW ACL. For Dynamic Registration, check the registration state as well.

If the message is present, check the destination URI and the user agent’s reachability. Keep the unconditional Request-URI rewrite from inbound routing.

OpenSIPS rejects inbound calls with 403 Forbidden

Compare the request’s $si source address with the DIDWW ACL. Check the published addresses for the trunk type and its failover locations.

The inbound trunk does not register

Allow up to 30 seconds for the registration timer to process the record. If registration still fails, check the state:

  • REGISTER_TIMEOUT_STATE indicates that no response was received. Check the network path and the local route used to add rport behind NAT.

  • WRONG_CREDENTIALS_STATE indicates rejected credentials.

  • REGISTRAR_ERROR_STATE indicates another error from the registrar.

Outbound calls fail after successful authentication

Check the caller ID set by uac_replace_from() against Allowed CLI(s) and On CLI Mismatch. Then check Destination Dialing Settings and the trunk’s Status. Reaching the 24-hour limit automatically disables the trunk.

OpenSIPS does not answer an outbound 401 challenge

Check that the outbound credential uses out.didww.com as its realm. A credential stored under a regional hostname will not match the challenge. The failure route logs uac_auth() failed when authentication cannot be completed. See module settings and credentials.

Outbound calls receive no response behind NAT

Confirm that the outbound branch includes add_local_rport(). This allows responses to return to the source port used by NAT. See outbound routing.

OpenSIPS reports no transport protocol loaded

Keep loadmodule "proto_udp.so" in the module settings. It is required by the tested build even though a separate module file is not present.

OpenSIPS reports an append_fromtag initialization error

Keep modparam("rr", "append_fromtag", 1) in the module settings. The tested configuration requires it when using uac_auth(), including with restore_mode set to none.

OpenSIPS logs Can’t load dlg API at startup

The tested build can continue after ERROR:uac:mod_init: Can't load dlg API. Review the following log messages and confirm that the proxy is listening. Do not treat this message alone as proof that startup failed.

For more information about OpenSIPS scripting, see the official Types of routes and Core Parameters documentation.