Skype for Business and Lync Subnet Pexip Location Policy

This policy server provides a way to nominate a Pexip location appropriate for the subnet to which Lync and Skype users belong. This policy is enhances a deployment where you have a centralised Lync or Skype Front End Pool to which users are homed but you want to have Pexip host the media for VMR and gateway calls locally.

For example if I am in the Sydney office, my Skype client is registered to the Singapore SFB Front End Pool (FEP) and there are conference nodes allocated to the Sydney Pexip location. The FEP is configured with a static domain route sending SIP INVITES to the Pexip conference nodes in the Singapore location. Here is where the smarts of the policy server comes in.

The Singapore location is configured with the MSSIP policy server (detailed in this post). The policy server allows a CSV file to be uploaded that contains IPv4 subnets and the Pexip locations that should be nominated for media when Skype calls from those subnets reach Pexip.

When a Skype or Lync user places a call that reaches the Singapore Pexip location, the conference node in Singapore will send a participant location request to the policy server. The policy server will inspect the parameters of the call, specifically the protocol=mssipand ms-subnet={subnet} values. It will then look up the user’s subnet in the CSV file and allocate the primary and two overflow locations for media. The media for the Skype call will then be hosted by the resultant location.

The format of this CSV file should be in the form of:

Note: CSV should not include the heading row.


1. Install the Pexip Reverse Proxy (details

2. Update and secure the RP by following Andreas’ instructions:

3. Install the policy server

Download and install the policy server

Install pip, virtualenv and python dev packages:

sudo apt-get install python-pip python-dev
sudo pip install virtualenv

Download the policy files and create the virtual python environment:

git clone --branch mssip-only
cd /home/pexip/pexsubnet/
virtualenv policyenv

Activate the virtual environment:

source policyenv/bin/activate

Install the bits we need to run this example:

pip install -r requirements.txt

Verify that the policy server runs via CLI to ensure that all requirements are met.


You should see: * Running on (Press CTRL+C to quit)

Configure IPTABLES

The policy server responds to URL based requests. As such when the policy python code is run we need it to listen for requests on a TCP port. Given this article describes installing the policy on the Pexip Ubuntu image with Nginx already installed, we can make use of Nginx. The policy will be host by WSGI which is an interface between Nginx and the python application. This also means that the image can still provide the dual function of a Reverse Proxy for conference nodes and the policy server.

Nginx will listen to TCP port 443 to provide the conference node proxy fuction so we need to nominate another port for the policy server. In this example we will use TCP port 8443.

Lets allow port 8443 in the IPTABLES firewall config:

sudo nano /etc/iptables/rules.v4

Add this line to the config:

-A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 8443 -j ACCEPT

Reload the the IPTABLES configuration:

sudo iptables-restore < /etc/iptables/rules.v4

Testing policy with WSGI

Now lets test that the policy server runs within the WSGI framework. We can do this by creating another virtual session using screen so that we can run the policy server in one session and interact with it from another session.

Start a screen session:


The terminal will refresh with a new session. Now lets invoke the virtual environment and start the policy server:

source policyenv/bin/activate
uwsgi --socket --protocol=http -w wsgi

You will see a bunch of text appear. The server is running and listening on TCP port 8443.

Now go back to your original session by holding down the Control key and pressing a followed by d.

In the original session, enter:

curl --insecure -X GET -H "Content-type: application/json" -H "Accept: application/json" "http://localhost:8443/policy/v1/participant/location?protocol=mssip&ms-subnet="

This will simulate a policy request from a conference node. You should see the following result:

 "policy.reason.matched": "Sending to location locations[0]",
 "result": {
 "location": "Sydney",
 "primary_overflow_location": "Melbourne",
 "secondary_overflow_location": "Singapore"
 "status": "success"

This result is given because the CSV provided out of the box contains he parameters int the table at the top of this post.

Now lets return to the session where we have the policy server running, stop it and exit the session:

screen -r


Install policy as a service

Copy upstart script (policy service)

sudo cp /home/pexip/pexsubnet/policy.conf /etc/init/

Nginx configuration

Secure the policy server by creating a username and password (replace exampleuser with your desired username):

sudo apt-get install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd exampleuser

New password:
Re-type new password:
Adding password for user exampleuser

Configure Nginx to point to the policy server:

sudo nano /etc/nginx/sites-enabled/pexapp

Add the parts between Policy server START and Policy server END. Change the server_name value to your local FQDN and ip address:

# Redirect HTTP to HTTPS
server {
    listen 80;
    return 301 https://$host$request_uri;
################## Policy server START ###############################
server {
    listen 8443 ssl;

    ssl_certificate ssl/pexip.pem;
    ssl_certificate_key ssl/pexip.pem;
    ssl_session_timeout 5m;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!DH:!EDH;
    ssl_prefer_server_ciphers on;

    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location / {
        auth_basic “Restricted";
        auth_basic_user_file /etc/nginx/.htpasswd;
        include uwsgi_params;
        uwsgi_pass unix:/home/pexip/pexsubnet/policy.sock;
#################Policy server END #########################################
server {
    listen 443 ssl;

    include /etc/nginx/includes/pex-rewrites.conf;
    include /etc/nginx/includes/pex-ldap.conf;

    ssl_certificate ssl/pexip.pem;
    ssl_certificate_key ssl/pexip.pem;
    ssl_session_timeout 5m;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!DH:!EDH;
    ssl_prefer_server_ciphers on;

    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;

    # Redirect from web root to /webrtc
    location / {
        return 301 /webapp;

Reboot the PR:

sudo reboot

Test the policy using a browser:


Policy server controls:

sudo start policy
sudo stop policy
sudo restart policy

Upload a new locations.csv

Browse to the policy server root: https://{your-policy-IP}:8443

Click Get Active CSV to download the example
Click Get Active CSV to download the example


Note, you will need to ensure that the RP has a valid certificate. See:

For free public certificate using Letsencrypt see



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s