В начале этого лета в России произошли изменения в тарифах на рассылку SMS-сообщений. Правила игры изменились, цены выросли на порядок. Кто бы мог подумать, что такое может произойти с технологией, которая уже более 20 лет существует в нашей обыденной жизни. По моему мнению, «большая тройка» решила, что отправка SMS стала использоваться только в корпоративных целях (физики давно мигрировали в различные интернет-мессенджеры), следовательно, на ней можно хорошенько заработать, не боясь потерять пользовательскую симпатию. В статье представлен вариант отказа от подобных сервисов в сторону Asterisk на примере Hotspot, когда на указанный номер телефона поступает звонок и диктор сообщает пароль доступа. Тарифы отличные, расходы минимальные, работаем дальше.

▍ Введение


21 июля в курируемом мной проекте перестала работать рассылка SMS-сообщений, содержащих пароль для доступа к общедоступному Wi-Fi, организованному в интересах международной компании Coffee Cup, имеющей как собственные бары формата «кофе с собой» в разных городах, так и дилеров по всей России и в странах СНГ. Все технические подробности о том, как это было изначально сделано, можно посмотреть здесь. Для рассылки самих сообщений в силу лёгкости решения, гибкости и удобства администрирования были задействованы сторонние ресурсы, счета на которых в июле стремительно обнулились. Что, собственно говоря, произошло, стало понятно после общения с технической поддержкой:

Переписка
Я: у меня перестали отправляться смс. С ошибкой «незарегистрированный sender id».

Поддержка №1: На XXX и XXX отправка возможна только от платных имён с абонентской платой 2 000 руб./мес за каждого оператора. Если нужна временная отправка от общего имени на данных операторов в ближайшее время, есть тариф около 16 руб. за SMS на XXX и 20,30 руб. на XXX.


Или вот такой:

Я: Ищу простой способ отправки SMS, без лишних заморочек. Подойдёт любой исходящий номер.

Поддержка №2: Без регистрации и абонентской платы можно отправлять сообщения от общих имён операторов, но по повышенному тарифу (XXX: 18 руб. за SMS, XXX: 20,30 руб. за SMS). К сожалению, такая заградительная цена — ограничение, наложенное операторами.


Действительно, если поискать информацию на сайтах операторов сотовой связи, то можно увидеть примерно то же самое:


▍ Технические варианты уведомления пользователей


Называть такие тарифы заградительными весьма уместно. Пришло время искать другие решения.

Отправка SMS через собственные модемы (ведь некоторые бары оборудованы таковыми, как, например, на фото из заголовка) отпала сразу. Причины следующие:
  • потенциальные проблемы и танцы с бубнами при отправке сообщений через устройства различных производителей, моделей, прошивок,
  • потенциальные проблемы с зависаниями устройств,
  • сложность централизованного администрирования территориально-распределённого оборудования,
  • высокие риски быть заблокированными со стороны сотовых операторов, которые знают толк не только в том, как заработать, но и как вычислить таких, как мы, и ввести против нас и не только различные ограничения.
Другим вариантом замены отправки SMS является доставка кодов доступа посредством интернет-мессенджеров. Тоже не подходит: во-первых, спорная легитимность идентификации пользователей таким образом, во-вторых, при подключении к Hotspot интернет появляется только после ввода отправленного пароля, а значит пользователям нужно отключаться от Wi-Fi, возвращаться в сеть передачи данных своего мобильного оператора, и только после этого подобные уведомления будут доставлены. Всё это надо ещё донести до людей, поэтому сразу нет.

Третий вариант — это задействование возможностей открытого программного обеспечения Asterisk, когда на номер пользователя поступает автоматизированный звонок, и необходимо в качестве пароля указать последние цифры звонящего номера. Сейчас много где так организовано. Этот способ имеет преимущество — отсутствие длительности разговора, ведь после поднятия трубки АТС самостоятельно разрывает соединение. Однако имеются другие накладные расходы – необходим определённый пул арендуемых номеров (и желательно большой), который стоит денег. Например, аренда одного городского номера выходит порядка 350 рублей в месяц. Если использовать вместо арендуемых номеров обычные модемы – минусы такого решения рассмотрены выше.

Четвёртый вариант — использование Asterisk, когда на номер пользователя поступает автоматизированный звонок, и робот голосом сообщает пароль. Корпоративный арендуемый номер у компании Coffee Сup уже был, тарификация посекундная, следовательно, накладные затраты должны быть адекватными. Как это всё интегрировать в имеющуюся инфраструктуру (с учётом того, что сеть за эти годы значительно подросла), подробно рассмотрим ниже. Непосредственно общая настройка АТС к рассматриваемой теме не относится, поэтому концентрироваться на ней не будем.

▍ Hotspot с идентификацией пользователей посредством Asterisk


Изначально проект казался более сложным, чем вышел на самом деле, благодаря гибкости имеющихся решений и используемого программного обеспечения. Казалось, что нужна будет интеграция с API, например, от Google, по переводу текста в голос для работы диктора. Однако это избыточно, ведь Asterisk имеет на борту заготовленные звуковые файлы различного содержания, в том числе подходящие для нашего проекта. Общая схема следующая: пользователь подключается к Hotspot, получает приглашение на ввод номера телефона, который посредством HTTP GET передаётся на сервер АТС, где обрабатывается и формируется задание для Asterisk. Ответом на запрос является пароль доступа к Hotspot. После этого осуществляется звонок на номер пользователя, при котором проигрываются необходимые аудиозаписи с кодом доступа. Далее в рефакторинг не лезем, всё работает по старой схеме. Для начала подготовим аудиофайлы для Asterisk. Скорее всего, они не будут предустановлены:

ls /usr/share/asterisk/sounds/
apt-cache search asterisk | grep sounds-ru
apt install asterisk-core-sounds-ru asterisk-core-sounds-ru-gsm asterisk-core-sounds-ru-wav asterisk-core-sounds-ru-g722 -y
ls –l /usr/share/asterisk/sounds/ru/

В нашем проекте пароль доступа к Hotspot представляет четырёхзначное число. Здесь лежат звуки пауз, например, длительностью в 1 секунду: /usr/share/asterisk/sounds/ru/silence/1. Здесь имеются записи произношения диктором цифр: /usr/share/asterisk/sounds/ru/digits/0. Кстати, на борту представлен простой и удобный способ записи собственных сообщений. Для этого внесём изменения в имеющийся диалплан:

# nano /etc/asterisk/extensions.conf
[test-record]
exten => _1000,1,Wait(2)
exten => _1000,n,Record(/tmp/sound${EXTEN:2}:wav)
exten => _1000,n,Wait(1)
exten => _1000,n,Playback(/tmp/sound${EXTEN:2})
exten => _1000,n,Wait(2)
exten -> _1000,n,Hangup()

Укажем данный extension нужному endpoint:

# nano /etc/asterisk/pjsip.conf
 [3002]
type=endpoint
context=test-record
# systemctl restart asterisk

Звоним с указанного endpoint на номер 1000, говорим что-нибудь, после чего слышим произнесённое, а качественная запись голоса будет сохранена в файле /tmp/sound00.wav. Чтобы инициировать звонок от имени АТС, можно использовать либо CLI, либо командный файл. Пример работы посредством консоли представлен ниже:

/usr/sbin/asterisk -rx "channel originate pjsip/3001/3002 application playback /var/lib/asterisk/sounds/custom/sound00"
/usr/sbin/asterisk -rx "channel originate pjsip/+71111111111@siplink-74992222222 application playback /var/lib/asterisk/sounds/custom/sound00"

Кстати, вместо проигрывания звуковых файлов может быть использовано встроенное в Asterisk приложение, которое умеет произносить цифры (для озвучивания чисел есть другое приложение) однако придётся позаниматься русификацией:

channel originate pjsip/3001/3002 application saynumber 123

В проекте вместо CLI использовался командный файл. Чтобы инициировать звонок на номер +71111111111, подготавливаем:

# nano /var/spool/asterisk/tmp/test.call
Channel: PJSIP/+71111111111@siplink-74992222222
Application: Playback
Data: /var/lib/asterisk/sounds/custom/sound00

Чтобы воспроизвести несколько файлов, их нужно перечислить через амперсанд. Копируем командный файл в нужное место, и АТС сразу выполнит полученные инструкции:

cp /var/spool/asterisk/tmp/test.call /var/spool/asterisk/outgoing/test.call

Приведу пример используемого extension:

# nano /etc/asterisk/extensions.conf
[siplink-out-74992222222]
exten => _XXXX,1,Dial(PJSIP/${EXTEN})
exten => _+X.,1,Dial(PJSIP/${FILTER(+0-9,${EXTEN})}@siplink-74992222222)

Здесь хочу порекомендовать провайдера IP-телефонии Siplink — профессиональные ребята. Давно пользуюсь их услугами, приятно работать: хорошая поддержка, адекватные тарифы.

На этом настройка Asterisk заканчивается, осталось доработать веб-сервер и RouterOS. В скрипте для работы Hotspot удалим использование API сторонних сервисов и добавим следующее:

:local SITE pbx.tratata.ru;
:local PORT 443;
:local APIKEY 0123456789;
…
local pass ([/tool fetch url="https://$SITE:$PORT/\?secret=$APIKEY&msisdn=$uname" output=user as-value]->"data")

Пароль пользователя и командный файл для Asterisk будем генерировать прямо на АТС. Для этого настроим любой веб-сервер, активируем HTTPS. Как это сделать, упускаем, инструкций более чем достаточно. Подготовим index.php:

<?php
$api = '0123456789';
$key_from_get = trim(htmlspecialchars($_GET["secret"]));
$dir = '/usr/share/asterisk/sounds/ru';
$silence = "$dir/silence/1";
$sip1 = "@siplink-74992222222";
$sip2 = trim(htmlspecialchars($_GET["msisdn"]));
$fileWeb = 'file.txt';
$fileAsterisk = 'file2.txt';

if ( $key_from_get === $api AND strlen("$sip2") === 10 AND ctype_digit("$sip2") ) {
    $pas1d = random_int(0, 9);
    $pas2d = random_int(0, 9);
    $pas3d = random_int(0, 9);
    $pas4d = random_int(0, 9);
    echo "$pas1d$pas2d$pas3d$pas4d";
    $myfile = fopen("$fileWeb", "w");
    $txt = "Channel: PJSIP/+7$sip2$sip1\n";
    fwrite($myfile, $txt);
    $txt = "Application: Playback\n";
    fwrite($myfile, $txt);
    $txt = "Data: $silence&$dir/digits/$pas1d&$silence&$dir/digits/$pas2d&$silence&$dir/digits/$pas3d&$silence&$dir/digits/$pas4d\n";
    fwrite($myfile, $txt);
    fclose($myfile);
    rename("$fileWeb", "$fileAsterisk");
}
?>

Веб-сервер получает номер пользователя, генерирует ему пароль доступа, возвращает его в качестве ответа и подготавливает соответствующее задание для АТС. Непосредственный перенос файла в папку Asterisk выполняет bash-скрипт. Такая прослойка сделана для возможности прикручивания допов на будущее, работает стабильно. PHP-cкрипт валидирует и проверяет длину и состав номера пользователя, при звонке сам подставляет телефонный код +7, чтобы отсутствовала возможность списывать деньги со счёта посредством звонков, например, на Марс. Здесь необходимо отметить, что используемый скрипт RouterOS содержит проверку и блокировку множественных однотипных запросов:

#Cheks user from spam
:local sendtest yes;
:foreach i in=[/ip firewall address-list print as-value where list=spam_cheks_list] do={
:if (($i->"address")=$uname) do={
		:set $sendtest no;
}
}
:if ($sendtest=yes) do={
/ip firewall address-list add list=spam_cheks_list address=$uname timeout=00:05:00; 
…
}

JavaScript на странице Hotspot никакой реальной защиты не добавляет, а только помогает пользователю не ошибиться при наборе цифр. На страницу добавлено уведомление о том, что поступит звонок от робота с арендуемого нами корпоративного номера:


Готово! Получаем приятную стоимость одного такого звонка в 20-30 копеек, что даже дешевле, чем отправка SMS по «старым» доиюльским ценам:


▍ Заключение


В статье мы рассмотрели доработку Hotspot до идентификации пользователей посредством звонка от Asterisk и диктовки пароля с целью миграции от SMS-gateway-шлюзов из-за значительного удорожания их сервисов. Минусом такой организации является то, что на время приёма звонка сотовый телефон посетителя отключается от Wi-Fi, что не такая уж и проблема, так как при повторном подключении имеется возможность выбрать «У меня уже есть код». Решение рабочее, следующая точка отказа – борьба большой тройки с IP-телефонией, как уже некоторые начинают делать, безразборчиво блокируя подобные входящие вызовы, ссылаясь на противодействие мошенничеству. Как видно из кода, несложно всё доработать на использование пула номеров и идентификацию посредством ввода последних цифр звонящего номера, без длительности разговора и списания денег. Полученное решение достаточно гибкое, много что можно нарастить. Моё личное мнение: Open-source Software — сила, особенно в очумелых руках.

Telegram-канал с полезностями и уютный чат

Комментарии (40)


  1. progchip666
    17.11.2022 12:37
    +5

    В начале этого лета в России произошли изменения в тарифах на рассылку SMS-сообщений. Правила игры изменились, цены выросли на порядок.

    Осталось дождаться когда наконец вырастут тарифы на распространение Телефонного Спама, который уже превзошёл не только все разумные, но и неразумные пределы.


    1. olegtsss Автор
      17.11.2022 16:15

      Мигрируют в мессенджеры!


  1. khegay
    17.11.2022 12:49
    +1

    А можно было бы сделать в другую сторону: при подключении, показывается короткий код: 123. Дальше, пользователю поступает звонок и нужно ввести этот код.


    1. Stanislavvv
      17.11.2022 13:46
      +1

      Это сложнее и, вероятно, дороже... Одно дело получить из формочки циферки и пнуть в базу, другое - настраивать свой сервер с астериском, где потом настраивать распознавание циферок, посылание их в сервис (опять же свой) с номером телефона, который и пошлёт в базу.
      К тому же, человек может тупить при звонке дольше, чем слушать цифры, что опять же сказывается на стоимости.


    1. olegtsss Автор
      17.11.2022 16:17
      +2

      Проиграем с длительностью разговора. Так она у нас условно фиксирована (10 секунд примерно), а так придется ставить таймер секунд на 30. Ну и соответственно - это будет дороже.


      1. ner0
        17.11.2022 22:39

        а международные платные номера отфильтровываются?


        1. olegtsss Автор
          18.11.2022 03:37

          Да, на серверной стороне.


    1. TimsTims
      17.11.2022 22:50

      Ужасная идея. Наверное самая худшая). Самая простая user-friendly: Попросить пользователя самому сделать прозвон по нужному номеру.

      Плюсы: Не нужно совершать вызов на "левый" номер, если пользователь в нём ошибся. Не нужно пользователю запоминать пин код. Не нужно тратиться на смс. Не нужно тратиться на исходящий вызов.


      1. olegtsss Автор
        18.11.2022 03:40

         О каком user-friendly вы пишите? "Попросить пользователя самому сделать прозвон по нужному номеру" -> это как раз наоборот, не user-friendly:
        1) страх, что вызов стоит денег
        2) убийство корпоративного номера для приема рабочих звонков


        1. rexen
          18.11.2022 10:05

          1) страх, что вызов стоит денег

          Ну так уведомить юзера, что его вызов будет бесплатен (как - это уже второй вопрос)


          1. olegtsss Автор
            18.11.2022 15:31

            Уведомить - не решает проблему страха пользователя.


        1. TimsTims
          18.11.2022 10:47

          страх, что вызов стоит денег

          Говорим, что вызов бесплатный.

          корпоративного номера для приема рабочих звонков

          Корпоративный номер не относится к проблеме "user-friendly", но тем не менее, не обязательно ведь использовать телефон приёмной. Можно отдельную сим-карту купить, и только смотреть входящие вызовы, все вызовы сбрасывать.

          О каком user-friendly вы пишите

          О самом лучшем варианте из возможных, в условиях низких ресурсов и необходимости в идентификации.


      1. sdnv
        18.11.2022 14:07

        Хм, идея
        Можно взять номер 8-800-*
        Но опять же - непонятно как к этому отнесутся юзеры. Звонить еще кому-то...


  1. aax
    17.11.2022 12:49
    +2

    На мой взгляд, по меньшей мере на перспективу, нужно не искать новые "костыли"(и понятно что временные), а решать проблему в корне, т.е. добиваться отмены законодательных требований на авторизацию в публичном хот-споте. Тем более, что и "товарищ майор" понимает, что таким способом серьезных людей, если что не вычислить. А вот неудобства и физические и этического плана налицо для большинства людей.


    1. miarh
      17.11.2022 12:57
      +2

      Не реально. Кто добиваться то будет? Голос малого бизнеса и по более важным вопросам не слышат, а для крупного бизнеса - это не затраты. Про фан ид уже кто только не сказал, и люди на стадионы не ходят - но пятиться назад нпша система не может.
      Для себя решаю договором с провайдером. Деньги не большие, но зато рисков нет - вот к ним идите.


      1. olegtsss Автор
        17.11.2022 16:18

        Это не техническая сторона вопроса.


        1. miarh
          17.11.2022 19:38

          Да, но технические задачи всегда вытекают из требований бизнеса. Как в статье - подорожали смс - делаем голосом.


  1. selivanov_pavel
    17.11.2022 13:02
    +2

    Плохо, что теперь система стала недоступна слабослышащим и не владеющим русским языком пользователям.


    1. olegtsss Автор
      17.11.2022 16:19

      Можно прикрутить выбор нескольких языков.


  1. RekGRpth
    17.11.2022 13:31
    +2

    дак можно же сделать вообще без смс и звонков (положительной длительностью): пользователь вводит свой номер телефона и отправляет форму, а потом сам звонит на указанный провайдером номер телефона, где ему в предответе (т.е. фактически трубка не снята) провайдер отвечает, что услуга активирована


    1. McCoder
      17.11.2022 15:02

      CallerId можно подделать, поэтому не безопасно просить позвонить по номеру.


      1. olegtsss Автор
        17.11.2022 16:27

        Ну так себе "можно". Нужно подключение АТС к ТФОП.


    1. olegtsss Автор
      17.11.2022 16:23
      +1

      Я бы не сам не звонил. Не понятно, сколько стоит звонок, может очень дорого, специально обманывают. Другое дело принять входящий вызов. И у нас по ТЗ в аренде один городской корпоративный номер, он и раздает всем коды.


    1. vassabi
      17.11.2022 21:18

      а может в обратную сторону сделать - вводите свой номер на сайте, потом вам звонят и сразу сбрасывают, а на сайте просят ввести последние 3-4 цифры набравшего вас номера ? (а арендовать 5-10 номеров вместо 1000, чтобы возможность угадать была небольшой. 100 номеров - если в кафе ходят студенты)


      1. olegtsss Автор
        18.11.2022 03:46
        +1

        Так можно, там в коде не много что поправить надо. Только заранее нужно посчитать экономику. Аренда 5 номеров - это 2500 р. в месяц (хотя 5 - это очень мало, так как угадать не составит труда, зная хотя бы один, можно просто перечислять свой номер, типа +71111111111, +71111111112 ... и раз за разом вводить известный номер, попадете в точку менее, чем за минуту). 2500 р это 8000 регистраций на Hotspot.


        1. Ainvain
          19.11.2022 13:54

          Я думал, что для такого способа авторизации используют сторонние сервисы, у которых тысячи номеров. Кинул запрос на API, получил последние цифры номера, который позвонит клиенту, сравнил с вводом клиента. Теоретически для такого сервиса стоимость одного запроса может быть очень низкой. По первым ссылкам в гугле максимум 20 копеек за звонок.


          1. olegtsss Автор
            19.11.2022 15:34

            Дополнительная точка отказа при приблизительно равных финансовых затратах.


  1. Stanislavvv
    17.11.2022 13:47
    +1

    Лучше сделать, чтоб требовалось ввести последние цифры номера, с которого звонили. Глухим точно поможет.


    1. olegtsss Автор
      17.11.2022 16:25

      Об этом я писал в статье. Минус такого решения - нужен пул номеров. Аренда каждого стоит денег. А так там минимальные изменения по коду будут.


  1. Westus
    17.11.2022 16:50

    Конкретно для кафе проще сделать монитор с QR кодом. Камерой щелк и авторизован. На мониторе появляется новый код для следующего пользователя.


    1. olegtsss Автор
      17.11.2022 17:08
      +3

      Требование гос. регулятора вы так не выполните. (рассмотрены в первой части статьи)


  1. kik_krsk
    17.11.2022 18:33

    Можно сделать окно с вводом номера клиента, а потом его попросить позвонить по номеру и сбросить. При звонке закончить авторизацию на стороне астериска


    1. olegtsss Автор
      17.11.2022 18:40
      +1

      Пользователь должен совершить вызов. И его сомнения, платно ли это. И номер по ТЗ является общим корпоративным, на который звонят по разным вопросам.


  1. FlashHaos
    18.11.2022 10:04
    +1

    Спасибо, я хоть наконец понял, почему от удобных смс все переходят на эти раздражающие звонки.

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


    1. serafims
      18.11.2022 14:07

      Ну ту скорее цена исходит из того, что СМС - это, получается, как телеграмма в почтовом мире. Быстро, имеет, хоть и минимальную, юридическую значимость, но при этом цена не соизмерима с объемом информации (весом посылки).


      1. olegtsss Автор
        18.11.2022 15:37

        Я думаю, что операторы либо таким образом прикрутили себе дополнительный способ зарабатывать на юридических лицах, не опасаясь за "физическую" клиенто-ориентированность. Либо уже так накладно стало содержать и обслуживать оборудование SMS шлюзов.


  1. vviz
    18.11.2022 22:06

    А вот такая мысль - во многих кафе есть информационные мониторы - клиент вводит в форме номер телефона и на монитор выводится последние четыре цифры номера и пинкод доступа.


    1. olegtsss Автор
      19.11.2022 08:08

      Так вы не подтвердите, что номер телефона принадлежит гостю, как требует регулятор.


  1. Seganda
    19.11.2022 08:08

    Молодец изобрел велосипед, которому 10 лет)

    Не знаю как вы, а я давно использую вообще бесплатный вариант (практически) сам клиент делает гудок на номер с которого его сразу же скидывает, после чего происходит его регистрация в рейд сервере с окном авторизации в 3 минуты (за столько он должен авторизоваться после гудка, либо делать новый гудок)

    Все. Затрат нет. Возможных проблем с недозвоном итд тоже нет.


    1. olegtsss Автор
      19.11.2022 08:09

      Обсудили выше в комментариях уже несколько раз.