Multiple Companies
About
Note: There is also some useful information on the Multi-tenant page, which needs merging.
This is HOWTO to make one FreeSWITCH server act as a multi-tenant system for two or more companies, each with its own domain/users and independent dialplans.
Basically, we want to have one FS server provide phone services to several separate companies, as if we are a VoIP provider. Let's start with two companies and give both companies the same two users (1000 for company-a and 1000 for company-b). These companies should be completely independent of each other, their identically-numbered extensions should not overlap or have anything to do with each other, and each company (and all of it's users/extensions) should have independent dialplans.
Click here to expand Table of Contents
- 1 Enabling Multiple Domains
- 2 Creating the Files and Directories
- 3 Setting Up the SIP Profile
- 4 Creating a Dialplan for Each Domain
- 4.1 Usage
- 5 Gotchas
- 6 See also
Enabling Multiple Domains
This is from the SIP Profiles section of Multi-tenant:
Edit conf/sip_profiles/internal.xml
to comment the params "force-register-domain" and "force-register-db-domain":
<!--
These are enabled to make the default config work better out of the box.
If you need more than ONE domain you **MUST DISABLE** these options.
-->
<!--all inbound reg will look in this domain for the users -->
<param name="force-register-domain" value="$${domain}"/>
<!--all inbound reg will stored in the db using this domain -->
<param name="force-register-db-domain" value="$${domain}"/>
Update 2011-12-23
File conf/sip_profiles/internal.xml should have its newest option, "force-subscription-domain" (present as of FS git date 2011-12-23), also commented out. Current correct setting:
<!--all inbound reg will look in this domain for the users -->
<!--<param name="force-register-domain" value="$${domain}"/>-->
<!--force the domain in subscriptions to this value -->
<!--<param name="force-subscription-domain" value="$${domain}"/>-->
<!--all inbound reg will stored in the db using this domain -->
<!--<param name="force-register-db-domain" value="$${domain}"/>-->
Creating the Files and Directories
Assuming FreeSWITCH is installed in /usr/local/freeswitch/
, cd there and create the files and directories:
$ cp conf/directory/default.xml conf/directory/company-a.org.xml
$ cp conf/directory/default.xml conf/directory/company-b.org.xml
$ cp -a conf/directory/default conf/directory/company-a.org
$ cp -a conf/directory/default conf/directory/company-b.org
/usr/local/freeswitch/conf/directory
now should look like this:
$ ls -l
total 24
drwxr-xr-x 3 diego diego 4096 2009-09-23 04:30 company-a.org
-rw-r--r-- 1 diego diego 2656 2009-09-29 22:21 company-a.org.xml
drwxr-xr-x 3 diego diego 4096 2009-09-23 04:30 company-b.org
-rw-r--r-- 1 diego diego 2656 2009-09-29 22:21 company-b.org.xml
drwxr-xr-x 3 diego diego 4096 2009-09-23 04:30 default
-rw-r--r-- 1 diego diego 2656 2009-09-23 04:30 default.xml
$
Let's edit the files now:
conf/directory/company-a.org.xml
<include>
<!--the domain or ip (the right hand side of the @ in the addr-->
<domain name="company-a.org">
<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"/>
<variable name="default_gateway" value="$${default_provider}"/>
<variable name="default_areacode" value="$${default_areacode}"/>
<variable name="transfer_fallback_extension" value="operator"/>
<variable name="user_context" value="company-a.org"/>
</variables>
<groups>
<group name="company-a.org">
<users>
<X-PRE-PROCESS cmd="include" data="company-a.org/*.xml"/>
</users>
</group>
</groups>
</domain>
</include>
Notice the lines into which "company-a.org" has been inserted. Do the same for company-b below, and extend to however many other companies are to be hosted on this FreeSWITCH server.
conf/directory/company-b.org.xml
<include>
<!--the domain or ip (the right hand side of the @ in the addr-->
<domain name="company-b.org">
<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"/>
<variable name="default_gateway" value="$${default_provider}"/>
<variable name="default_areacode" value="$${default_areacode}"/>
<variable name="transfer_fallback_extension" value="operator"/>
<variable name="user_context" value="company-b.org"/>
</variables>
<groups>
<group name="company-b.org">
<users>
<X-PRE-PROCESS cmd="include" data="company-b.org/*.xml"/>
</users>
</group>
</groups>
</domain>
</include>
Adding Users to the Directories
Now let's create the users in the newly created directories: For example, add two users, one in conf/directory/company-a.org
and another one in conf/directory/company-b.org
, something like this:
conf/directory/company-a.org/1000.xml
<include>
<user id="1000">
<params>
<param name="password" value="$${default_password}"/>
<param name="vm-password" value="1000"/>
</params>
<variables>
<variable name="toll_allow" value="domestic,international,local"/>
<variable name="accountcode" value="1000"/>
<!--<variable name="user_context" value="default"/>-->
<variable name="effective_caller_id_name" value="Extension 1000"/>
<variable name="effective_caller_id_number" value="1000"/>
<variable name="outbound_caller_id_name" value="$${outbound_caller_name}"/>
<variable name="outbound_caller_id_number" value="$${outbound_caller_id}"/>
<variable name="callgroup" value="techsupport"/>
</variables>
</user>
</include>
conf/directory/company-b.org/1000.xml
<include>
<user id="1000">
<params>
<param name="password" value="$${default_password}"/>
<param name="vm-password" value="1000"/>
</params>
<variables>
<variable name="toll_allow" value="domestic,international,local"/>
<variable name="accountcode" value="1000"/>
<!--<variable name="user_context" value="default"/>-->
<variable name="effective_caller_id_name" value="Extension 1000"/>
<variable name="effective_caller_id_number" value="1000"/>
<variable name="outbound_caller_id_name" value="$${outbound_caller_name}"/>
<variable name="outbound_caller_id_number" value="$${outbound_caller_id}"/>
<variable name="callgroup" value="techsupport"/>
</variables>
</user>
</include>
- NOTE: Delete or comment-out the
user_context
option line inside all the extension (user)*.xml
files and instead put that option line inside the master XML file for each domain (i.e., theconf/directory/company-a.org.xml
file and also theconf/directory/company-b.org.xml
file), as doing so will save time by obviating specification ofuser_context
inside every extension (user) file subsequently created underconf/directory/company-a.org/
orconf/directory/company-b.org/
.
Setting Up the SIP Profile
Comment force-register-domain
and force-register-db-domain
from the profile, it should look like this:
conf/sip_profiles/internal.xml
<!--<param name="force-register-domain" value="$${domain}"/>-->
<!--<param name="force-register-db-domain" value="$${domain}"/>-->
<!--<param name="force-subscription-domain" value="$${domain}"/>-->
Creating a Dialplan for Each Domain
You could copy conf/dialplan/default.xml
to conf/dialplan/company-a.org.xml
and conf/dialplan/company-b.org.xml
and edit the context on each to match the context from the users/directories.
conf/dialplan/company-a.org.xml
<include>
<context name="company-a.org">
<!-- your extensions here -->
</context>
</include>
conf/dialplan/company-b.org.xml
<include>
<context name="company-b.org">
<!-- your extensions here -->
</context>
</include>
Usage
Now if the 1000@company-a.org user tries to dial a extension, it should look into the company-a.org context/dialplan and if 1000@company-b.org tries to dial it should look into the company-b.org context/dialplan. Bow to the power of FreeSWITCH!
Gotchas
As I painfully found and noted [(old wiki) here] I just relearned the same thing, painfully, a different way. The domain established in vars.xml must not be the same as any of the tenant's domains you're hosting; otherwise, that tenant's domain will not work while all the others will. Yes, maddening.
<X-PRE-PROCESS cmd="set" data="domain=boxen.mydom.net"/>
present in vars.xml file must be different from all other tenant's domains!
See also
Comments:
if you are using this, please be care and DO NOT put the address or domains you are using in the acl.conf.xml or you ACL any where. this makes it to your endpoints dont really auth, and thereby causing the user_context to not be honored, and instead dumping them into the context defined inside of the sofia profile that the devices register against Posted by akp at Apr 29, 2020 14:41 |
---|