Back to Home

Freeswitch: the path of least resistance

A bit of lyrics As far as I remember myself in the system administrator's chair (and the total experience has already been approaching 15 years already) · so many questions of office telephony were perceived by me from a line from Californication ...

Freeswitch: the path of least resistance

Some lyrics


As long as I remember myself in the system administrator’s chair (and the total experience has already approached the age of 15), so many issues of office telephony were perceived by me as a line from Californication California RHCP: hard core soft porn. Telephony has always seemed a parallel measurement, I tried not to get into its administration and configuration. More precisely, generally circumventing all these telephone inquiries in a wide arc, throwing off all such tasks to "specially trained people."

However, as often happens, there’s no end to the rope ... After getting a job in a new organization, I became the “happy” administrator of a great bunch of Ericsson digital-to-analog PBX and Cisco 2911 “integrated services router”. More than a hundred analog phones, three dozens of digital Ericsson's and two to three dozen IP phones Cisco and Ericsson. All this splendor was once tuned by those same experts in hard core soft porn, and to this day I can only imagine in general terms. However, be that as it may, what extension is, how conditional and unconditional forwarding is organized, how IVR is arranged, what DID is, and so on, I still had to find out. And I was not enthusiastic about the acquired knowledge (yes, not everything useful is interesting and pleasant). Only a tsiska, after I have mastered the logic of its configuration,

At some point, humility came that telephony was still an integral part of the system administrator's household.

A Sound of Thunder


The organization in which I work moves to another building. Of course, all analog and digital economy remains at the place of eternal registration. Tsiskovsky VoIP in the preparation of 2911 provides 50 lines, and the price tag for cisco telephones is completely inhumane. And either thanks to humility that has already come, or thanks to an innate craving for knowledge, or thanks to a combination of these two factors, I decided that I would raise telephony in a new place myself.

The requirements were simple: cheap, but better for free, and, ideally, to pay extra , provide basic functionality (direct city numbers for employees, IVR, call forwarding, conferences, call transfer), from 150 lines and above. The first word that came to mind was “SIP”, the second “Asterisk”, the third “Google”.

AsteriskNOW has been downloaded and deployed. Stunned stumbled into the web interface. Appreciated once again hardcornsoftporn'ovskim logic telephone operators and again went to google. And accidentally came across the word "FreeSWITCH". New word, new searches. Laudatory odes of stability, ease of configuration (everywhere XML), low resource requirements, plus out-of-the-box operation, plus “people” flawlessly working in a virtual environment with hundreds or even thousands of lines without voice distortion (although developers do not recommend a virtual environment due to the lack of access to the CPU in real time). OK. We try.
We raise the virtual machine under the recommended Debian 8 x64, 1 core 2 GHz, 2 gig RAM, 16 gig disk. We carry out the installation in accordance with the instructions ( thousand) We set up a softphone (I liked 3CX's tyts ).

The softphone has registered. Test calls have gone. Lyapota. Ericsson Dialog 4422 also registered, rings, voice is heard in both directions. Lyapota. The Cisco 7945 was vaccinated with SIP-enabled firmware, and after relatively short dances with SCCP settings, the device also registered and the calls went flawlessly. Lyapota. FreeSWITCH in production!

Stop the lyrics


Initial data:

Ground floor switching equipment:

  1. The switch is owned by MTS, on which a group of ports is allocated to us. From it we take the Internet and we will take SIP-telephony. Traffic tagged vlan4
  2. Our switch, it has a dedicated group of ports to which vlan is assigned. Internet comes from these ports from MTS (port 2 - vlan2), Internet from Miralogic (port 3 - vlan3), SIP from MTS (port 4 - vlan4). Port 1 is also allocated under trunk, the cable goes to the server room of the fourth floor.

Server equipment on the fourth floor:

  1. Switch accepting trunk from the first floor. Port 1 - trunk incoming (from the first floor. Port 2 - trunk outgoing (to the server).
  2. The server is running VMware vSphere 6. On this host is a guest machine with Mikrotik RouterOS, which acts as a gateway and firewall. Also on this host is a guest machine with FreeSWITCH. VSwitch is configured on the host and ports with the corresponding traffic tagging are added: vlan2, vlan3, vlan4.

Telephony via E1 is provided by MTS. From MTS, the SIP trunk was provided for the test.
These settings were sent to me by MTS engineers:

Добрый день!
Реквизиты SIP транка
Порт на коммутаторе 9
Номер 5555555
ip-адрес: 172.16.160.154
маска: 255.255.255.252
шлюз: 172.16.160.153
соединение без регистрации, точка - точка
sip-сервер: 172.16.253.3, port: 5060 UDP
media-сервер: 172.16.253.4, port: 10000 - 30000 UDP
кодеки: G711a/u
протокол передачи DTMF: rfc-2833

The machine with FreeSWITCH has one network interface, network settings:

IP: 172.18.253.1Netmask: 255.255.0.0GW: 172.18.1.254

Flew, Mikrotik


We extinguish the guest machine with Mikrotik and add another network interface, assign it vlan4. We turn on the guest machine, Mikrotik boots up, we see that a new interface has appeared.

Customizable.
Interface settings in Mikrotik
Выводим список имеющихся интерфейсов:
/interface ethernet print

Видим, что свежедобавленный интерфейс это интерфейс с именем ether6
Переименовываем его в if-sip:
/interface ethernet set [ find default-name=ether6 ] name=if-sip

Настраиваем адрес:
/ip address add address=172.16.160.154/30 comment=mts-sip interface=if-sip network=172.16.160.152

Configure routing in Mikrotik
Настраиваем mangle (чтобы трафик маркировался как мы захотим, и чтобы трафик ходил только через нужный нам интерфейс на основе этих меток):
/ip firewall mangle add action=mark-routing chain=prerouting comment="mark sip traffic" new-routing-mark=sip src-address=172.18.253.1

Настраиваем маршрутизацию:
/ip route add comment=mts-sip distance=1 dst-address=172.16.0.0/16 gateway=172.16.160.153 routing-mark=sip

Configure firewall and NAT in Mikrotik
Настраиваем отсутствие фильтрации файерволом (на этом этапе я не боюсь злых хакеров из SIP-транка с PAN-адресов МТС):
/ip firewall filter
add chain=forward comment="allow any to mts-sip" dst-address=172.16.0.0/16 in-interface=if-local out-interface=if-sip src-address=172.18.253.1
add chain=forward comment="allow any from mts-sip" dst-address=172.18.253.1 in-interface=if-sip out-interface=if-local src-address=172.16.0.0/16


Убедитесь, что эти два разрешающих правила расположены в самом верху списка правил. Это снизит нагрузку на файервол.

Для себя я решил, что мой SIP-шлюз будет находиться в локальной сети, чтобы:

  • Не иметь трахомудии с нежеланием отдельных телефонных аппаратов работать со шлюзом, находящимся за NAT.
  • Внутренний трафик в десятки раз превышает исходящий и входящий вместе взятые,
    ни к чему его гонять через Mikrotik.
  • И вообще, настроить один раз шлюз будет дальновидней, чем в дальнейшем воевать с множеством телефонных аппаратов (сотни) с разными прошивками, а то и разных производителей.

По этой причине настраиваем 1:1 NAT.
/ip firewall nat
add action=netmap chain=srcnat comment="source NAT for sip" src-address=172.18.253.1 to-addresses=172.16.160.154
add action=netmap chain=dstnat comment="destination NAT for sip" dst-address=172.16.160.154 to-addresses=172.18.253.1

Если отключали сервисные порты, включаем sip обратно:
/ip firewall service-port set sip ports=5060,5061,5080,5081 disabled=no

We ping the gateway (172.16.160.153), we ping the SIP-gateway (172.16.253.3), we ping the Media-gateway (172.16.253.4). Pings go. Perfectly.

On this the easy and understandable part ended.

Fly, FreeSWITCH


For “going out” we need to do the following things, whose names are alien to the ear of an IT specialist who has not encountered telephony:
  • Indicate which IP addresses and where to use FreeSWITCH to establish connections.
  • Indicate the region code and subscriber number allocated by the operator.
  • Create extension - subscriber number. Out of the box, FreeSWITCH has pre-configured 30 subscriber numbers. We will create another one.
  • Create a gateway. This is not what you thought. A gateway is a named set of settings required to connect to a provided SIP trunk. We will not do this,
    we will change the default gateway settings
  • Configure dialplan. In transliteration, a terrible sounding word. In the correct pronunciation, the sound is even worse. I do not like. In the established spelling and pronunciation of "dialplan". Means a set of scenarios. From this set, depending on the triggered condition, FreeSWITCH performs one or another action. Dialplans are created for outgoing and incoming calls.
  • Configure ACLs for networks and domains where calls are allowed.

Disclaimer : assumes FreeSWITCH is installed in the default folder: / etc / freeswitch

The very first thing we do is change the default password. But again, not because you thought. Although, therefore, too. The password is verified by dialplan, and if the password matches the default, a pause of 10 seconds is inserted before the connection. Therefore, first we change the password.
File: /etc/freeswitch/vars.xml
<X-PRE-PROCESScmd="set"data="default_password=ballsofsteel"/>

Alternatively, if you really like the password “1234”, then you can remove the pause from the dialplan by simply editing the corresponding block.
File: /etc/freeswitch/dialplan/default.xml
<conditionfield="${default_password}"expression="^1234$"break="never"><actionapplication="log"data="Fuck pretense just let's dance"/><actionapplication="log"data="Never Open $${conf_dir}/vars.xml and change default password."/></condition>

IP Address Settings
File: /etc/freeswitch/sip_profiles/external.xml
<paramname="ext-rtp-ip"value="172.16.160.154"/><paramname="ext-sip-ip"value="172.16.160.154"/>

Regional settings
File: /etc/freeswitch/vars.xml
<X-PRE-PROCESScmd="set"data="outbound_caller_name=3435555555"/><X-PRE-PROCESScmd="set"data="outbound_caller_id=3435555555"/><X-PRE-PROCESScmd="set"data="default_areacode=343"/><X-PRE-PROCESScmd="set"data="default_country=RU"/>

Details from the operator
File: /etc/freeswitch/vars.xml
<X-PRE-PROCESScmd="set"data="default_provider=172.16.253.3"/><X-PRE-PROCESScmd="set"data="default_provider_username=3435555555"/><X-PRE-PROCESScmd="set"data="default_provider_password=not-used"/><X-PRE-PROCESScmd="set"data="default_provider_from_domain=172.16.253.3"/><X-PRE-PROCESScmd="set"data="default_provider_register=true"/><X-PRE-PROCESScmd="set"data="default_provider_contact=73435555555"/>

Remark most attentive
Вы, наверное, только что заметили, что значение параметра default_provider_register немного не вяжется с теми настройками, что выдал оператор (соединение без регистрации, точка — точка). Однако, в случае с МТС, регистрация все же понадобилась, без нее не проходили вызовы извне внутрь. При том, что без регистрации вполне можно было звонить изнутри наружу. Эта особенность выпила мне немало крови, прежде, чем я врубился и отловил ее.

Характерным признаком того, что требуется авторизация, является ошибка 407 Proxy Authentication Required.

Отлавливается эта ошибка включением SIP-трассировки:
sofia global siptrace on

Выключается трассировка, соответственно:
sofia global siptrace off

Add a subscriber number (extension)
Create an xml-file with any name in the / etc / freeswitch / directory / default folder . I created a file with a name that matches the number.
File: /etc/freeswitch/directory/default/4545.xml
<include><userid="4545"><params><paramname="password"value="$${default_password}"/><paramname="vm-password"value="4545"/></params><variables><variablename="toll_allow"value="domestic,international,local"/><variablename="accountcode"value="4545"/><variablename="user_context"value="default"/><variablename="effective_caller_id_name"value="Скудицкий М.В."/><variablename="effective_caller_id_number"value="4545"/><variablename="outbound_caller_id_name"value="$${outbound_caller_name}"/><variablename="outbound_caller_id_number"value="$${outbound_caller_id}"/><variablename="callgroup"value="techsupport"/></variables></user></include>

We create a gateway
Most likely, after you have completed the IP address settings and filled in the fields in vars.xml with the details provided by the operator, registration on the operator’s gateway will take place without problems.

But I didn’t succeed “without problems”, because MTS sent the details and did not get the extension number 3435555555. Before I suspected the operator of the setup, I managed to go through a million options for configuring the gateway. However, as a result, the operator created a subscriber number on his SIP-gateway, and everything started up, if not with the default settings, then with close ones. Here is a listing of the mts.xml file , which was obtained by renaming the external.xml file .
File: /etc/freeswitch/directory/default/mts.xml
<include><userid="$${default_provider}"><gateways><gatewayname="$${default_provider}"><paramname="username"value="$${default_provider_username}"/><paramname="password"value="$${default_provider_password}"/><paramname="from-user"value="$${default_provider_username}"/><paramname="from-domain"value="$${default_provider_from_domain}"/><paramname="expire-seconds"value="600"/><paramname="register"value="$${default_provider_register}"><paramname="retry-seconds"value="30"/><paramname="extension"value="$${default_provider_contact}"/><paramname="context"value="public"/></gateway></gateways><params><paramname="password"value="$${default_provider_password}"/></params></user></include>

Now we add permissions to the domain and the network so that our FreeSWITCH does not block attempts to establish connections from the domain and from the operator’s networks. And yes, at this stage, I just as easily resolve everything. My task is to finally call outside the organization.
File: /etc/freeswitch/autoload_configs/acl.conf.xml
You can’t do this
<listname="lan"default="allow"><nodetype="allow"cidr="172.18.0.0/16"/><nodetype="allow"cidr="172.16.0.0/16"/></list><listname="domains"default="allow"><nodetype="allow"domain="172.18.253.1"/><nodetype="allow"domain="172.16.253.3"/><nodetype="allow"cidr="172.16.0.0/16"/><nodetype="allow"cidr="172.18.0.0/16"/></list>

<listname="lan"default="allow"></list><listname="domains"default="deny"><nodetype="allow"cidr="172.16.253.3/32"/></list>

Note!
  1. ACL is intended only for domains and network providers. The domains list should be deny by default . The use of the domain variable should be avoided; instead, the cidr and IP address of the operator's gateway with the / 32 mask should be used . Failure to comply with these basic rules leads to unexpected consequences in the form of attempts to force the provider’s gateway to log in using the user and password for incoming calls (Digest-authorization), to get internal subscriber numbers in the wrong context (for example, external , as a result of switching to authorization by ACL, instead of Digest) and disruption of dialplans, etc.
  2. This is not a firewall. Traffic filtering does not occur. These are access lists for FreeSWITCH services.

Congratulations! You can see what we did (not) succeed.
We start the FreeSWITCH console: We
fs_cli -rRS
reboot xml'ki:
reloadxmlor we press F6.
We reboot ACL: We
reloadacl
reboot the Sofia module responsible for telephone connections:
reload mod_sofia
We look that at us with connections with gateways.
freeswitch@phone> sofia status
Name Type Data State
=================================================================================================
external profile sip:[email protected]:5080 RUNNING (0)
external::172.16.253.3 gateway sip:[email protected] REGED
172.18.253.1 alias internal ALIASED
internal profile sip:[email protected]:5060 RUNNING (0)
=================================================================================================
2 profiles 1 alias

Nice. Registration on the operator’s gateway was successful.
We look at the details:
sofia status gateway 172.16.253.3
freeswitch@phone> sofia status gateway 172.16.253.3
==============================================================
Name 172.16.253.3
Profile external
Scheme Digest
Realm 172.16.253.3
Username 3432788299
Password yes
From <sip:[email protected]>
Contact <sip:[email protected]:5080;transport=udp;gw=172.16.253.3>
Exten 73435555555
To sip:[email protected]
Proxy sip:172.16.253.3
Context public
Expires 600
Freq 600
Ping 0
PingFreq 0
PingTime 0.00
PingState 0/0/0
State REGED
Status UP
Uptime 3932s
CallsIN 1
CallsOUT 1
FailedCallsIN 0
FailedCallsOUT 0
==============================================================

It was up to the small.

Dialplans
For calls to the outside, we create the mts.xml file from scratch, all other files in the / etc / freeswitch / dialplan / default folder can be renamed with a change of extension / moved to another location / bang .
File: /etc/freeswitch/dialplan/default/mts.xml
<include><extensionname="outbound-city-call"><conditionfield="${toll_allow}"expression="local"/><conditionfield="destination_number"expression="^(\d{7})$"><actionapplication="set"data="effective_caller_id_number=${outbound_caller_id_number}"/><actionapplication="set"data="effective_caller_id_name=${outbound_caller_id_name}"/><actionapplication="bridge"data="sofia/gateway/${default_gateway}/8${default_areacode}$1"/></condition></extension><extensionname="outbound-country.cellular-call"><conditionfield="${toll_allow}"expression="domestic"/><conditionfield="destination_number"expression="^8(\d{10})$"><actionapplication="set"data="effective_caller_id_number=${outbound_caller_id_number}"/><actionapplication="set"data="effective_caller_id_name=${outbound_caller_id_name}"/><actionapplication="bridge"data="sofia/gateway/${default_gateway}/8$1"/></condition></extension><extensionname="outbound-international-call"><conditionfield="${toll_allow}"expression="international"/><conditionfield="destination_number"expression="^(810\d+)$"><actionapplication="set"data="effective_caller_id_number=${outbound_caller_id_number}"/><actionapplication="set"data="effective_caller_id_name=${outbound_caller_id_name}"/><actionapplication="bridge"data="sofia/gateway/${default_gateway}/810$1"/></condition></extension></include>

For calls from outside to inside, create the mts_inbound.xml file in the / etc / freeswitch / dialplan / public folder . The rest in this folder, by analogy above, can be renamed to * .bck or * .noload
File: /etc/freeswitch/dialplan/public/mts_inbound.xml
<include><extensionname="public_did"><conditionfield="destination_number"expression="^(73435555555)$"><actionapplication="set"data="domain_name=$${domain}"/><actionapplication="transfer"data="4545 XML default"/></condition></extension></include>

Well. Crossed fingers, check.

We start the FreeSWITCH console again:
fs_cli -rRS
Restart xml:
reloadxmlor press F6.
Restart the dialplan module responsible for telephone connections:
reload mod_dialplan_xml
Try dialing from the inside out. We try dialing from the outside to the inside. We joyfully repeat the test “one-time, two-two”, we are convinced that the sound goes in both directions. Check the passage of the end lights in both directions.

We are happy to have joined soft porn.

PS: I deliberately avoided deciphering the meaning of certain edits. Partly, because the names of the parameters and system variables speak very well for themselves. Partly, in order not to turn the turbo-launch of telephony into a mess with the excuses of each bunch.

PPS: The writing of this text was dictated by the horror of the fact that I could not find an intelligible manual with integrated text, where the same task would be solved: as simple as possible, as quickly as possible to raise telephony with point-to-point authorization. The abundance of documentation for some reason is not accompanied by an abundance of discussions and living examples. Or it just so happened that I finished reading everything faster than I google the “same example” that would work for me. One way or another, let it be a cheat sheet for me and my colleagues for the future.

Read Next