Difference between revisions of "Multi-tenant"

From FreeSWITCH Wiki
Jump to: navigation, search
(Directory)
(Directory)
Line 20: Line 20:
 
First, lets start by building the directory.  under conf/directory, you'll notice a default.xml and default/ folder.  Copy both of these to company-a.com.xml, and company-a.com, respectively.  The names of the files and folder are arbitrary, but it makes sense to name them to match the domain you are creating.  The configuration I desired was for each domain to receive and send calls to it's own external gateways via upstream ITSPs, with a unique account per domain.  If you just need a single gateway for all domains, define it in an xml file in conf/directory.
 
First, lets start by building the directory.  under conf/directory, you'll notice a default.xml and default/ folder.  Copy both of these to company-a.com.xml, and company-a.com, respectively.  The names of the files and folder are arbitrary, but it makes sense to name them to match the domain you are creating.  The configuration I desired was for each domain to receive and send calls to it's own external gateways via upstream ITSPs, with a unique account per domain.  If you just need a single gateway for all domains, define it in an xml file in conf/directory.
  
/directory/company-a.xml:
+
===/directory/company-a.xml:===
 
<pre>
 
<pre>
 
<include>
 
<include>

Revision as of 05:39, 7 November 2008

This document is under construction, and should not be trusted until this text is removed

Contents

Introduction

The ability to host multiple clients on a single installation of FreeSWITCH greatly increases the ability of FreeSWITCH to be used in a multi-tenant scenario, such as a multi-tenant building served by a single FreeSWITCH instance, or commercial service providers.

The configuration for running FreeSWITCH in a multi-tenant configuration is actually very easy. SIP Domains are the key. Separating each tenant into it's own domain using SIP domains offers the advantage of being able to reuse the same dialplan for every tenant. Exceptions to this are when some tenants have an IVR as their front end, and some tenants map DIDs directly to extensions.

Disclaimer: FreeSWITCH is a VERY flexible platform, and with that flexibility, you get many ways to achieve the same task. At some point best practices will emerge, but this is the brute force method I used.

SIP Domain Background

To understand the concept of SIP routing, the analogy is email addresses. Consider the email address joe.smith@company-a.com. This address is composed of two parts: the user id, on the left of the @, and the domain name, on the right of the @. The Internet DNS system has a simple but effective way of determining how to get email addressed to user Joe Smith, at company-a.com. It involves asking the DNS hierarchy for a list of host names that will accept mail for company-a.com. DNS responds with a list of host names that will accept the mail. The machines do not have to live in the company-a.com namespace. Any machine that has a valid MX (mail exchanger) record for company-a.com is acceptable to send mail to. The sending host then starts at the top of the list, and starts trying to connect to the hosts, one by one, until one responds. There are more intricate details, but this level of explanation will do. SIP domains do not have DNS MX records, as those are reserved for internet mail. DNS SRV records server the same purpose. SRV records can be used for routing multi-protocol data around the internet. For more information on DNS SRV and SIP, refer to RFC 3263

The best way to document the configuration of domains is to dive right into the XML config files. The configuration shown below uses the stock XML default configuration, with domain support added. Several sections of the default dialplan can be ripped out, because they are not needed. Documented is a basic, no frills multi-tenant system with each tenant(domain) determined from where the call originated. Inbound calls are routed directly to extensions with a 1:1 mapping.

Files to edit

We will break down the configuration into three sections: Directory, Inbound, and Outbound call routing.

Directory

First, lets start by building the directory. under conf/directory, you'll notice a default.xml and default/ folder. Copy both of these to company-a.com.xml, and company-a.com, respectively. The names of the files and folder are arbitrary, but it makes sense to name them to match the domain you are creating. The configuration I desired was for each domain to receive and send calls to it's own external gateways via upstream ITSPs, with a unique account per domain. If you just need a single gateway for all domains, define it in an xml file in conf/directory.

/directory/company-a.xml:

<include>
  
  <domain name="servercorps.com">
  
    <params>
      <param name="dial-string" value="{presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}"/>
    </params>

    <variables>
      <variable name="record_stereo" value="true"/>
<!-- 
Defines the area code for this customers local calling area.
You can also define this per user, or per site, since some 
companies' are in different area codes 
-->
      <variable name="area_code" value="251"/>
      <variable name="transfer_fallback_extension" value="operator"/>
<!-- 
define the outbound gateway to for dialing outside the domain 
defined per domain to allow different gateways for every domain
-->
      <variable name="outbound_gateway" value="servercorps.com-outbound"/>
    </variables>

    
    
    <user id="%ALUSERNAME%">
              

    <gateways>
        <gateway name="servercorps.com-outbound">
               <!--/// account username *required* ///-->
               <param name="username" value="uername"/>
               <!--/// auth realm: *optional* same as gateway name, if blank ///-->
               <param name="realm" value="outbound.vitelity.net"/>
               <!--/// account password *required* ///-->
               <param name="password" value="password"/>

               <!--/// proxy host: *optional* same as realm, if blank ///-->
               <param name="proxy" value="outbound.vitelity.net"/>
               <!--/// expire in seconds: *optional* 3600, if blank ///-->
               <param name="expire-seconds" value="3600"/>
	       <param name="retry_seconds" value="60"/>
                <param name="register" value="true"/>
		<param name="ping" value="25"/>

        </gateway>
	
        <gateway name="servercorps.com-inbound">
               <!--/// account username *required* ///-->
               <param name="username" value="username"/>
               <!--/// auth realm: *optional* same as gateway name, if blank ///-->
               <param name="realm" value="servercorps.com" />
               <!--/// account password *required* ///-->
               <param name="password" value="password"/>
               
               <!--/// proxy host: *optional* same as realm, if blank ///-->
               <param name="proxy" value="inbound18.vitelity.net"/>
               <!--/// expire in seconds: *optional* 3600, if blank ///-->
               <param name="expire-seconds" value="3600" />
	       <param name="retry_seconds" value="60"/>
	       <param name="ping" value="25"/>
               <param name="context" value="inbound"/>
               <param name="register" value="true"/>

        </gateway>
    </gateways>
  
  
    </user>
    
    <X-PRE-PROCESS cmd="include" data="servercorps.com/*.xml"/>

  </domain>
  
</include>