Setup a secure SMPP Server
This how-to will guide you through all the steps of setting up a complete and fully functional secure SMS Center. An SMS Center accepts incoming SMPP connections and routes SMS messages through different providers using either GSM, HTTP or SMPP.
An SMS aggregator or SMSC works by finding the most cost-effective route for its customers. Alternatively it can make sense to setup an SMSC to combine multiple low volume streams and have a central log and/or gateway directly to an SMS provider.
This how-to shows just one way to setup an SMSC using the SMS Server. It’s intended as a starting point to show you some of the SMS Server capabilities and its incredible versatility. If you have some specific setup in mind but don’t want to bother with the details of configuring the SMS Server please contact us. We can help you setup your project as well.
This SMS Center has the following features:
- Secure incoming and outgoing connections using TLS
- Any number of incoming SMPP connections
- Any number or type of outgoing SMS channels
- Supports Unicode and Multipart messages
- Does not store customer passwords
- Highly customizable
- Easy troubleshooting through comprehensive logging
Overview
The basics of setting up an SMS Server configuration is about channels and triggers. The channels either connect to the outside world or allow the outside world to connect to the SMS Server. The triggers allow you to react to any events. Triggers are tiny scripts that fire automatically on new messages or when a message changes state. In most cases the SMS Server can generate the script and you will not need to program anything.
In this how-to you will learn the following things.
- Setup and configure the SMS Server
- Create an SMPP Server channel
- Connect for the first time
- Store SMPP Server users
- Create an SMPP Server bind trigger
- Manage connected SMPP clients
- Accept message and subtract credits
- Connect to the SMS provider
- Forward SMS and delivery reports
- Testing bind and forward
- Route back from the SMS provider
Setup and configure the SMS Server
To setup the SMS center and start testing you will only need the SMS Server trial version. It’s recommended to have a (local) instance of SQL Server Express available.
Ideally you would have a tiny SMPP client and SMPP server to test with. Of course you could also have the SMS Server connect to itself but having these tools separate keeps your SMS Server configuration more organized.
The SMPP Simulator from our freeware page is a great SMPP server for testing. As an SMPP client you can use the any one of the sample projects in the SMS Component. For convenience you can download the full, runnable, GUI sample project here. Please note that this sample will only run on a PC that has either the SMPP simulator or the SMS Server already present.
Following this how-to requires a basic understanding of SQL and VBScript. No programming is required.
Installation
Follow these instructions to setup up the SMS Server. For this how-to please use the following settings:
- Configure the SMS Server as ‘stand-alone‘ or ‘server‘
- Connect to an existing SQL Server instance
- Use database authentication
- Run the service as the Local System user
- Other settings are not important for this how-to and can be left on their defaults
Create an SMPP Server Channel
Once the SMS Server is installed and configured please start up the SMS Server Manager and follow these instructions to create a new SMPP Server channel. Make sure to modify the settings in the Server page, General Settings page and Advanced Settings page as follows.
In the Server page:
- Use the port number 2776. We’ll use the non-default port because this channel will be secure
- Allow both IPv4 and IPv6 connections
- Listen on all available IP ports
- Select a certificate from the local machine store
If you don’t have a certificate available please follow these steps on how to configure a self-signed certificate. The certificate is required to be able to allow secure connections.
In the General Settings page:
- Uncheck ‘Always accept any bind request‘ and ‘Always accept any incoming SMS‘
With unchecking those options you will have generate triggers that will automatically verify bind request and new messages. A bind request is an SMPP term for user login.
In the Advanced Settings page:
In this page make sure to check the ‘Store SHA1 of password‘ setting. With this setting the SMS Server will never store the password of a client. Instead it will generate a hash of the password using the SHA1 algorithm and store that instead. We’ll create and store user credentials in next section below.
You can leave the other settings to their default values. After clicking ‘Finish’ you should see the SMPP Server channel in the channel overview.
Connect for the first time
With the SMPP Server channel created you can use any secure SMPP client to connect to this channel. Like, for instance, the SMPP client demo that we’ve taken from the Auron SMS Component samples.
An SMPP connection is setup in two steps:
- Setup a secure connection
- Send a BIND request
The bind request in the SMS Server is just another message type. And like any message type you can create triggers that fire on a new message. This is how we’ll handle the bind requests for incoming clients.
To use the SMPP client demo to connect to the SMPP Server channel please follow these steps:
- Open ‘demo.exe‘
- Click on ‘SMS via SMPP‘ to open the SMPP client
- Server should be ‘Localhost‘ and server port should be 2776
- SystemID and password can be anything since no combination should work at this stage
- Click on ‘Connect‘. The connect button will first connect and automatically try to bind.
When clicking on ‘Connect’ you should see the new message of type ‘SMPP Server Bind‘ appear in the manager. You can open this message by double-clicking.
Your screen should now look like this:
This screenshot shows the Auron SMS Component demo with it’s SMPP client on the right side. The SMPP client was just used to connect to the SMPP Server and in the bottom of this dialog you can see that the bind has timed out.
Center-left of the screenshot shows the SMS Server manager with the SMPP Server bind request message open in a new dialog. Since we still need to handle this message the bind on the client has timed out.
SMPP Server Bind messages are only visible in the ‘All‘ view of the SMS Server manager.
Storing SMPP Server users
Now that we have the SMPP Server channel running we’ll need to authenticate users. Before we can authenticate users we need to know where the user data is stored.
Since every business has their own way of storing customer information the SMS Server does not provide another way of storing it. Instead it is encouraged to connect into your own back-end system so only your own business rules apply and there is no redundancy of information.
For this how-to we’ll quickly setup a table in SQL server that will hold our user data. Please open the SQL Server Management Studio and run this SQL script:
CREATE DATABASE AuIntegration
GO
USE AuIntegration
GO
CREATE TABLE SmppServerUsers
(
SystemID NVARCHAR(16) PRIMARY KEY
, PasswordHash NVARCHAR(40)
, Credits INT
)
This script will create the SmppServerUsers table that we’ll use to store the user data for this example. We use the credits field in a later step.
Creating SMPP Server Users
Please run the following script to insert two test users who both start with 100 credits:
USE AuIntegration
GO
INSERT INTO SmppServerUsers (SystemID, PasswordHash, Credits) VALUES
(N'Test1', CONVERT(NVARCHAR(40), HASHBYTES('SHA1', N'Pwd1'), 2), 100)
, (N'Test2', CONVERT(NVARCHAR(40), HASHBYTES('SHA1', N'Pwd2'), 2), 100)
This statement stores the user passwords as an ‘SHA1‘ hash. If you would rather store the passwords in plain text you will need to go back to the previous step and uncheck ‘Store SHA1 of Password‘.
The advantage of storing the password as an SHA1 hash is that we don’t store the actual password but just some random looking string of text.
In this statement we’re using the built-in T-SQL function ‘HASHBYTES‘ to produce a hash from a Unicode string. The built-in function ‘CONVERT‘ converts this binary hash value to a HEX string. For example: The hash of the string ‘Pwd1’ will look like this: DC215545BA63D605FBCD647A9555270F566D918B
Technical note: If you use MySQL or with PHP or some other programming language or database please note that the SHA1 hash should be of the Unicode (UTF-16 LE) version of the password string.
Create SMPP Server Bind trigger
Find more information about triggers and how to create triggers in the SMS Server here.
Next we’ll need to create an SMPP Server Bind trigger.
Note: Like all generated triggers, this is just a template. You can configure common functionality in the template wizard. After creating the trigger you can completely customize the trigger by editing the trigger and changing the script behind it.
In this case we’ll name the trigger ‘BIND‘ with the description ‘Smpp server bind‘. In the ‘Select Channels‘ page you will have to select the ‘SMPP Server‘ channel. On the SystemID Lookup page you can specify a data source for looking up user data. Leave this empty to allow anyone access to your SMPP Server. Select a data source and a table here to limit access to the users in that table.
In this case we’ll connect to our local database and make use of the table from the previous step. You can click on the database icon to pop-up a dialog that will help you construct the connection string and test the database connection.
After creating this trigger enable it by checking the box in front of it. In the manager it should look like this:
Test the SMPP server bind trigger
The SMPP Server bind trigger will now automatically process messages of the ‘SMPP Server Bind’ type. This mean that you will now be able to log into the SMPP Server.
You can try it again by using the SMPP client demo to connect to the localhost again. For clarity the SMPP Server Bind message from the previous attempt was deleted.
It should now look like this:
In this screenshot you will see the SMPP client demo in the background with the SMS Server manager before it. The dialog up front shows the trace details of the SMPP Server Bind message.
To view the SMPP Server bind message trace details:
- Double click on the ‘Smpp Server Bind’ message
- Click on the ‘Trace‘ tab.
The trace now shows that the ‘BIND’ trigger was successful with the result ‘Bind accepted’.
Manage connected SMPP clients
To see that you’re connected go back to the ‘Channel view‘ in the SMS Server manager. You can get there by clicking on ‘Channels‘ in the ‘Configuration‘ node of the tree view on the left.
You will see a small ‘1’ next to the ‘online’ indication of the SMPP Server channel:
This number will increase for every client session that is currently connected to the SMPP Server.
You can find more detailed information by looking at the ‘Manage SMPP Clients‘ page of the SMPP Server channel properties. You can get there in the following steps:
- Open the ‘Channels’ view in the SMS Server manager
- Open the channel properties by clicking the ‘pencil‘ icon on the right of the SMPP Server channel.
- Click on the page ‘Manage SMPP clients‘
This page will show all clients connected to this channel. In this case it’s only the local host connection. Since both IPv4 and IPv6 are enabled by default the client has connected using IPv6. The default bind type is ‘Transceiver‘ which means that the client wants to both send and receive SMS messages.
Accept messages and subtract credits
You may have noticed that it is still impossible to send SMS messages to our SMPP channel. If you connect through the SMPP Client demo and send an SMS you will automatically disconnect after a couple of seconds. This is because we’re not yet accepting any incoming SMS messages.
To accept the incoming message we’ll need to create an ‘SMPP Server Acknowledge SMS‘ trigger. This trigger can be configured to do two things:
- Subtract one credit from the user
- Acknowledge the SMS (or reject if the user has no more credits)
Note: Like all generated triggers, this is just a template. You can configure common functionality in the template wizard. After creating the trigger you can completely customize the trigger by editing the trigger and changing the script behind it.
You can create the trigger from the triggers view. Create a new trigger by clicking on the green ‘Plus‘ icon.
In this case we name the trigger ‘ACK‘ with the description ‘Smpp server acknowledge‘. In the ‘Select channels‘ page select the ‘SMPP Server‘ channel.
The ‘Credits Lookup‘ page specifies where you want to lookup credit information. Leave this empty to just always accept any incoming message. Select a data source here to automatically subtract credits when the user has credits. The message is rejected with a ‘negative acknowledge’ status if the user has no more credits.
In this case we’ll connect to our local database and make use of the SmppServerUsers table we created previously. You can click on the database icon to pop-up a dialog that will help you construct the connection string and test the database connection.
In the SMS Server manager your trigger view now looks like this:
Connect to the SMS provider
In this case we’ll only create 1. An SMPP channel. However, it could have been any type of SMS channel like HTTP or GSM as well.
An SMPP channel is convenient for this test case because it’s easy to set it up to connect to either the test and demonstration gateway or with the SMPP Simulator.
If you create a new SMPP client channel in the SMS Server and keep the default settings you will automatically connect to the test and demonstration gateway.
In this case we’ll name this channel ‘SMPP1‘ with the description ‘SMPP Channel‘. So we’ll end-up with these two channels in the SMS Server:
Where the SMPP Server channel (SMPP_SERVER1) is the channel that our clients connect to. The SMPP client channel (SMPP1) is the channel that we is are going to forward their messages to.
Forward SMS and delivery reports
Forwarding an SMS that enters our system from the SMPP_SERVER1 channel to the outgoing SMPP1 channel happens with another trigger. For this we’ll use the ‘Forward trigger template‘.
We’ll call this trigger ‘FWD‘ with the description ‘Forward‘.
In the ‘Select Channels‘ we have to select the ‘From‘ channel and the ‘To‘ channel. This should be ‘SMPP_SERVER1‘ and ‘SMPP1‘ respectively.
In the ‘Forwarded Message‘ page you can leave the defaults in place. That means that the ToAddress of the new SMS will be set to the ToAddress of the original SMS and the Body of the new SMS will be set to the Body of the original SMS.
About delivery reports
An SMS provider sends a delivery report when an SMS reaches its final status. Ideally this status will be ‘Delivered’. When there are problems delivering the SMS the delivery report may say ‘Rejected’. In the SMPP protocol the delivery report is always just an SMS message with an extra status flag set which makes it a delivery report.
To receive a delivery report the original SMS should request a delivery report. This is another status flag that you can set on any outgoing SMS message.
The SMS provider (SMPP Server) will only send delivery reports to SMPP clients. An SMPP client will never send a delivery report to an SMPP Server.
Forward delivery reports
The next step is to automatically forward delivery reports.
Forwarding a delivery report is a two step process:
- Receive and apply the delivery report on the outgoing channel
- Create a new delivery report on the SMPP Server channel
Both of these steps are handled by triggers in the SMS Server.
First create the ‘Apply Delivery Report‘ trigger.
This trigger will automatically set the status of the original SMS to either ‘DELIVERED‘ or ‘NOTDELIVERED‘ depending on the delivery status in the delivery report. We’ll call this trigger ‘APPLYDLR‘ with the description ‘Apply delivery report‘.
You will have to create this trigger once for each outgoing SMS channel (GSM or SMPP). In the ‘Select Channels‘ page you can select a couple of channels at the same time. This covers the situation where you have multiple channels to the same provider that may receive each-others delivery reports. This is rarely the case.
Finally create the ‘SMPP Server Forward Delivery Reports‘ trigger.
This trigger acts on the message status change when a delivery report is applied. Therefore you will need to create three versions of this trigger to handle each SMS status.
Create this trigger for status:
- DELIVERED (Call this one FWDDLR)
- NOTDELIVERED (Call this one FWDDLR2)
- NOREPORT (Call this one FWDDLR3)
Testing bind and forward
Now that you have all of the trigger in place the triggers view in the SMS Server manager should look like this:
You can now send an SMS message to your SMPP channel with the SMPP client demo and you will see that it’s automatically forwarded. Looking at the SMS view in the SMS Server manager that should look like this:
The latest message is on top. So to read all of the events in order please read from bottom to top.
From bottom to top you will see the following messages:
- The original incoming message on channel ‘SMPP Server Channel‘
- The resulting forwarded message on channel ‘SMPP Channel‘
- The delivery report on the ‘SMPP Channel‘ which put the original message in state ‘Delivered‘
- The delivery report that was sent to the originator on the ‘SMPP Server Channel‘ as a result of the original message going to state ‘Delivered‘
Route back from the SMS provider
In this how-to we want to route messages that originate from our SMS provider to our SMPP users.
The channel ‘SMPP1‘ is connected to our provider and the channel ‘SMPP_SERVER1‘ is the channel that our users connect to.
So what we need to know is which SMS, arriving at ‘SMPP1‘, should go to which user connected to ‘SMPP_SERVER1‘.
The easy way to do this is to look at the ‘ToAddress‘. This is the recipient phone number of the SMS.
This means that we will have to store a recipient number for each SMPP Server user. In that case we’ll just refer to this recipient number to find out how to route a new SMS.
Update the SMPP users information
Now it’s time to extend the SmppServerUsers table to include a recipient number.
Open the SQL Server Management Studio and connect to your SMPP users database. Run the following SQL Script to add a new column called ‘AddressRange‘.
USE AuIntegration
GO
ALTER TABLE SmppServerUsers ADD AddressRange NVARCHAR(40)
GO
In the address range column we’ll store the recipient number for each user.
Execute this script to add an address range to the existing test users in the SmppServerUsers table.
USE AuIntegration
GO
UPDATE SmppServerUsers SET AddressRange = '+31699887766' WHERE SystemID = N'Test1'
UPDATE SmppServerUsers SET AddressRange = '+31688776655' WHERE SystemID = N'Test2'
GO
Create a new forward trigger
We’ll now add a new forwarding trigger from a template. Only in this case we will have to edit the trigger afterwards.
The first steps are familiar. Open the the ‘triggers view’ in the SMS Server Manager and click the green ‘plus’ icon to add a new trigger from a template. Select ‘Forward Trigger Template (VBScript)‘ and click OK.
Call this trigger ‘RECVFWD‘ with the description ‘Forward‘. In this case the ‘From‘ channel should be ‘SMPP1‘ and the ‘To‘ channel should be ‘SMPP_SERVER1‘. Keep the default settings in the ‘Forwarded Message‘ page.
Edit the forward trigger
We now need to edit the forward trigger so it will know which user on the SMPP_SERVER1 channel needs to receive the forwarded message.
To edit the ‘RECVFWD‘ trigger click on the ‘Pencil‘ button to the right of the trigger. Next select the ‘VBScript‘ tab.
In this dialog click on the ‘Pencil‘ button right next to the script path. This will open an editor with the generated forward script.
To make this script work for our purpose we just need to make a small change. The trigger should set the ‘BillingID‘ property of the message to the right ‘SystemID‘ value from the SmppServerUsers table.
This is the first change:
' // ========================================================================
' // Forward
' // ------------------------------------------------------------------------
' // Automatically forward this message
' // ========================================================================
Function Forward(objMessageIn, objMessageDB)
Log ">> Forward"
' -- Find the billing ID
' Add this block until the line that starts with ' ---
sBillingID = FindBillingID(objMessageIn, objMessageDB)
If sBillingID = "" Then
objMessageIn.AddTrace "Could not find a matching address range"
objMessageIn.StatusID = g_objConstants.MESSAGESTATUS_FAILED
Log "<< Forward"
Exit Function
End If
' ---
' forward SMS message
Set objMessageOut = objMessageDB.Create("SMS")
objMessageOut.AddTrace("Forward message from channel: [" & _
objMessageIn.ChannelID & "]")
' -- Set the billing ID; copy this next line
objMessageOut.BillingID = sBillingID
objMessageOut.ConversationID = objMessageIn.ID
objMessageOut.ChannelID = "SMPP_SERVER1"
' ... - rest of the function
This is the first part of the ‘Forward‘ function in the ‘RECVFWD‘ script. It needs two small changes.
- Copy and insert the first block of code that starts with ‘ — Find the billing ID’ and ends with ‘ —‘
- Insert the single line after ‘ — Set the billing ID; copy this next line’
- Make sure that they are positioned correctly in relation to the existing code
The last change is this:
Function FindBillingID(objMessageIn, objMessageDB)
FindBillingID = ""
' In this case the address range should be an exact match with the to address.
sQ = "SELECT SystemID FROM AuIntegration.dbo.SmppServerUsers WHERE AddressRange='" & _
objMessageIn.ToAddress & "'"
Set objRs = objMessageDb.AdoConnection.Execute(sQ)
If Not objRs.EOF Then
FindBillingID = objRs("SystemID")
End If
End Function
Copy this entire block of code into the script right after the line ‘End Function‘ of the forward function.
Now save the script file by clicking File -> Save
Finally
Your final setup should have 8 different triggers that determine the behavior of your SMSC.
This is what the triggers view show look like:
You have now configure your very own SMS Center!
All of these triggers can be freely modified to customize the behavior to your specific requirements.