company_banner

Свой личный SMS-шлюз. Часть 1 – цели, задачи, сборка и тестирование

  • Tutorial


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

Начнем мы статью с вопроса – для чего отправлять SMS, ведь на дворе 2021 год? Да, мы уже привыкли к различным мессенджерам, уведомлениям в чат-боты, но SMS до сих пор обладает наиболее гарантированным уровнем доставки. Нет зависимости от наличия интернета и сообщение поступит даже в сети 2G и при слабом сигнале и на устройство без доступа к интернет. Таким образом, если планируется отправлять сообщения, которые гарантированно должны быть доставлены и критичны к времени доставки, то SMS – это возможно лучший выбор.

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

Где можно применять это решение?


Самое простое и очевидное применение – отправка уведомлений. Мы отслеживаем доступность различных сервисов и хотим знать о любых сбоях. Применение в системе умного дома позволит нам быть в курсе всех произошедших событиях. Да, многие IoT устройства умного дома оборудованы разъемом под сим-карту и могут сами отправлять SMS, но в этом случае на каждое устройство нужна отдельная сим-карта.
Мы можем проводить двухэтапную аутентификацию пользователей или производить валидацию введенного номера телефона. Регистрировать пользователей по номеру телефона, без необходимости создания логина и пароля. Отправлять сообщения о формировании заказа, отправке, получении, изменении баланса.

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

Стоит обратить особое внимание – так как мы рассматриваем в статье вариант создания шлюза, то это позволяет отправлять сообщения сразу со всех описанных сервисов используя всего одно устройство.

Плюсы и минусы собственного шлюза


Как и любое решение, собственный шлюз обладает рядом достоинств и недостатков.
Мы не будем рассматривать плюсы с точки зрения точного сравнения с платными сервисами ввиду разного уровня получаемой услуги. Я приведу наиболее явные и вы сможете решить на сколько каждый пункт критичен именно для вас.

Плюс

  • Очень низкая цена за отправленное сообщение в районе 5 копеек за сообщение (при отправке 1000), против 2.65₽ на коммерческих шлюзах

Минусы

  • Отсутствует возможность задать имя – в качестве отправителя будет номер телефона, а не «Baton.ru», например. Но есть способ как решить это красиво и мы рассмотрим это в статье.
  • Отправка сообщения не чаще чем 1 раз в 10 секунд. Решается увеличением количества модемов.
  • Нет защиты от сбоев как на аппаратном, так и программном уровне. Объективности ради стоит отметить, что платные шлюзы тоже примерно раз в неделю сообщают о проблемах с доставкой определенным операторам. Мой опыт использования такого шлюза показывает всего один сбой за более чем 12 месяцев.

Итак, мы определили, что нам ожидать от собственного шлюза и мы готовы начать.

Устанавливаем Gammu, подключаем модемы


В качестве аппаратного ядра системы я буду использовать Orange Pi PC с Armbian просто потому, что он у меня есть и ничем не занят. Свою версию вы можете сделать на основе RPi, компьютера/сервера на Linux и даже виртуальной машины с проброшенными внутрь USB-портами – это не имеет особого значения, главное мы будем использовать Linux.

Для общения с модемами я буду использовать Gammu – очень мощный продукт позволяет общаться не только с классическими модемами, но и использовать телефоны в качестве модемов. Также этот продукт избавит нас от необходимости самим формировать пакеты сообщений, считать их длины, составлять и отправлять АТ-команды и самое главное позволить отправлять сообщения в PDU-формате.

Итак, подключимся к серверу, обновим систему и установим gammu:

ssh root@<IP_вашего_сервера>

apt update
apt upgrade -y

apt install gammu -y

Теперь нужно подключить модемы к USB-портам. Я буду использовать два модема, чтобы нагляднее показать чем отличаются настройки. Подключаем и смотрим какие порты они заняли.



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



На скрине выше видно, что установленный модем usb 5-1, Alcatel, имеет пять каналов. Теперь нам нужно определить какие из них используются для связи. Сделать это не сложно. Пишем в терминале:

screen /dev/ttyUSB1

В открывшемся окне вбиваем АТ и если в ответ получили ОК, то запоминаем этот порт – это то, что нужно. Выходим – CTRL+A затем D
Обратите внимание, что найдя один порт, все равно нужно проверить оставшиеся – ttyUSB2, ttyUSB3, и далее. Например, используемый мной Alcatel, имеет 2 независимых канала на ttyUSB4 и ttyUSB5, что позволяет одновременно отправлять два SMS-сообщения через один модем.

Настройка Gammu


Итак мы определились с портами и теперь нужно настроить Gammu. Есть утилита конфигурации gammu-config, но мы не будем ее использовать, а запишем сразу данные в конфигурационный файл.

nano ~/.gammurc

дописываем в нижней части файла данные конфигураций. Каждый блок [gammu] – это канал модема. [gammu] – это канал по умолчанию, [gammu1] – первый канал и т.д. Далее мы еще коснемся этого, когда будем отправлять сообщение. Итого я добавляю 3 доступных канала от двух своих модемов:

[gammu]

port = /dev/ttyUSB0
model = at
connection = at
synchronizetime = yes
logfile =
logformat = nothing
use_locking = yes
gammuloc =

[gammu1]

port = /dev/ttyUSB4
model = at
connection = at
synchronizetime = yes
logfile =
logformat = nothing
use_locking = yes
gammuloc =

[gammu2]

port = /dev/ttyUSB5
model = at
connection = at
synchronizetime = yes
logfile =
logformat = nothing
use_locking = yes
gammuloc =

Краткое описание настроек:

  • model – тип модема и как gammu следует общаться с модемом, at – с помощью AT-команд
  • connection = at – тип соединения. Подключаемся на скорости 9600
  • use_locking – говорит gammu, что нужно блокировать доступ к модему на время работы с ним. Иначе возможны различные ошибки и сбои


Вид настроек в терминале

Проверка работы


Gammu настроена и теперь мы можем протестировать отправку сообщений.

Базовая команда для отправки сообщения на английском и всего с одного модема выглядит следующим образом:

gammu sendsms TEXT +70001234567 -text "Test message"



Теперь рассмотрим варианты поинтереснее с использованием дополнительных аргументов

Если в системе несколько модемов, то добавляем нужный порт аргументом "-s <номер_порта>". Мы затрагивали этот момент, когда заполняли настройки. Нумерация начинается с 0 и в нашем случае это промежуток 0-2.

gammu -s 1 sendsms TEXT +70001234567 -text "Test message"

Отправка сообщений в PDU-формате (кириллица, прочие языки и спецсимволы) – "-unicode"

gammu -s 1 sendsms TEXT +70001234567 -unicode -text "Тестовое сообщение"

Отправка сообщений в PDU-формате с автоматической разбивкой на несколько сообщений и последующей склейкой на телефоне – "-autolen 5". Данный аргумент подразумевает использование числа, хотя объективно оно ни на что не влияет, по крайней мере у меня работает одинаково при любом числе, поэтому я решил, что сообщения длиной больше 5 у меня не будет и использую это число

gammu -s 1 sendsms TEXT +70001234567 -unicode -autolen 5 -text "Тестовое сообщение"

Есть очень интересный аргумент, который полезен, если вы отправляете одноразовые коды – "-replacemessages 1". Суть его работы заключается в следующем – мы указываем телефону, что при получении сообщения он должен заменить сообщений с ID 1, если оно имеется в полученных на то, что поступило сейчас. Таким образом телефон автоматически затирает все ранее полученные сообщения и в переписке всегда отображается только последнее полученное. Единственное, решить стоит его использовать или нет, желательно в самом начале, чтобы всегда заменять ID 1

gammu -s 1 sendsms TEXT +70001234567 -unicode -autolen 5 -flash -replacemessages 1 -text "Тестовое сообщение"



А теперь, самый интересный, на мой взгляд аргумент – "-flash".

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

gammu -s 1 sendsms TEXT +70001234567 -unicode -autolen 5 -flash -replacemessages 1 -text "Тестовое сообщение"


Всё!

В следующей статье


В этой части статьи мы настроили отправку сообщений, но оно происходит вручную. Во второй части статьи мы напишем небольшое API (на PHP) для получения запросов по http, сохранении их в базу данных и автоматической отправке через активный шлюз и не только …

RUVDS.com
VDS/VPS-хостинг. Скидка 10% по коду HABR

Комментарии 49

    +3
    а если использовать модемы с поддержкой голоса, вроде проверенных временем E1550, E173 и подобных, то можно поставить asterisk с модулем chan_dongle и получить кроме отправки смс, ещё и приём, а до кучи и голосовые вызовы с этих сим карт и полный блэкджек с sip телефонией…
      +1
      Я не претендую на уникальность решения – это как один из множества вариантов. Всё до нас уже кто-то изобрёл :) То, что я предлагаю в этой серии статей – это самописный, простой в работе сервис, который не потребует никаких особых навыков для старта. И да, если отклик будет, напишу третью часть с обработкой приёма сообщений

      А с asterisk всё таки надо уметь работать… У меня такого опыта увы нет, поэтому поделиться мне нечем. Я думаю если вы можете, будет отличная статья.
        +12
        если вкратце, то у меня сделано так:
        — есть несколько модемов E1550 (специально их искал и покупал на авито, т.к. лично у меня они более стабильно себя ведут)
        * у всех модемов изменён imei на «телефонный»
        * почему несколько — есть пара номеров которые не хочу терять и они «ждут лучшего часа»
        * завёл специально один номер, который указан в банках, госуслугах и прочих важных сервисах
        — всё это воткнуто в usb hub и в домашний «роутер»
        — на роутере поднят asterisk с chan_dongle
        — при приходе смс на любой номер дёргается скрипт, который пересылает текст смс в телеграм (через бота) + убивает ненужные от мчс и ряд других. если вдруг нет интернет или ошибки отправки через бота в течении 5 минут, то отправляется на номер который с собой обычной смс
        — через этого же бота можно отправить обычное смс наружу через любую симку
        — входящие звонки сначала попадают в ivr, где радостно сообщается что не могу говорить, но если вы хотите сообщить что то важное, нажмите «1», скажите кто\что, сообщите номер и я перезвоню — это отсекает вообще весь голосовой спам. было один раз что человек реальный так сделал, запись так же прилетела в телегу (+ в почту для резерва)
        — так же написана своя обёртка над tg2sip чтобы через телегу-tg2sip-asterisk-sim можно было позвонить наружу при острой необходимости, если для какой то идентификации требуется чтобы при звонке был нужный номер

        это работает давно и не замечаю уже, зато когда на номер который в телефоне с собой приходят звонки из банков и прочие разводы — точно знаешь что ничего у тебя не украли и радостно их тролишь…
          0
          Интересная схема. По сути у меня тот же функционал, но без варианта приема голоса
          С банками прикольно … однозначно + :)
            0
            Спасибо за пост! Было бы здорово иметь tutorial по настройке всего этого!
              0
              — всё это воткнуто в usb hub и в домашний «роутер»
              — на роутере поднят asterisk с chan_dongle

              Под роутером подразумевается комп на линуксе? Или на обычном wi-fi роутере можно завести asterisk с chan_dongle? Было бы любопытно узнать подробности решения )
                0
                сейчас да, купленный в китае миникомп с 6 гигабитными портами, ссд, wifi, bt, пассивное охлаждение… там сейчас всё
                до этого были асусы с entware
                собственно в последнем entware был/есть asterisk11-chan-dongle
                но тут есть нюанс, надо чтобы или в ядре уже поддержка модемов (точнее модули usb, usbcom) или возможность под ядро докачивать из пакетов эти модули и была совместимость с используемым модемом
                и из минусов — может быть не самая свежая версия, а там буквально недавно исправили проблему с отправкой юникодных смс…
                в этом отношении Е1550 хороший вариант, т.к. много кем поддерживается из коробки
            +1
            При написании следующих частей не забудьте указать, что при использовании SIM-карт, зарегистрированных на физ. лицо, есть высокая вероятность получить блокировку от оператора мобильной связи. В договорах прописано, что нельзя использовать номера как шлюзы.
              +1
              тут на помощь приходит смена imei )
                0
                А вот это уже не законно ;) я такое не практикую.
                На самом деле во всем нужна мера. Если не отсылать с одной сим-карты 5, 10, 50 тысяч смс, а ограничиться – 500 или 1000 и просто завести несколько номеров и балансировать нагрузку на карты, то уверен ни один оператор ничего не скажет
                  0
                  так речи про 5, 10, 50 тысяч и не было…
                  и у автора в оригинальном описании про количество сообщений ни слова…

                  про законность — операторам глубоко наплевать на взятые на себя обязательства!
                  простой пример, есть официальный тариф с включённой 1000смс в месяц, стоит в железном gsm шлюзе, у которого есть api для отправки и приёма смс, имеи не изменённый, так оператор в курсе что за железка.
                  по работе есть точка входа на сайте (сервис некий, информационные услуги если коротко) и там пользователь регестрируется и надо подтвердить номер (тк на него будет получать редкие смс)
                  замечено, что если в смс что отправляется есть слова типа «код» «проверка» — то смс отправляется, в выписке по счёту её видно, но не доходит
                  все попытки разобраться и решить проблему с оператором ни к чему не привели… они проверяют — всё хорошо, а по факту нет. в итоге такие слова не используем и всё работает…
                  но сразу скажу что по факту в месяц не более 100смс получается, чтобы не думаю что спам или что то подобное
                    +1
                    Про количество сообщений это было больше не к вам, а к стартовому комментарию

                    Такое поведение с блокированием определенных сообщений наблюдалось при получении у билайна. Причем именно при получении. Отправлял с yota и Тинькофф сообщения, в самом начале когда еще тестировал и через некоторое время на мой билайн они перестали приходить, а на мтс, тинькоф и мегафон приходили. В сообщении было https… убрал его, сообщение пришло. Вот думаю … :)
                    0
                    У нас не более 200-300 сообщений в месяц — мегафон регулярно добавляет наш билайновский номер в ЧС (и так же регулярно он оттуда выходит — видимо, по таймеру). Теле2 нас не блочит, кстати :)
                  +1
                  Это все и так знают, в любой статье про отправку sms об этом пишут, зачем повторяться?
                  В договорах еще есть такой пункт – «Запрещается использовать автоматизированные способы отправки сообщений». Таким образом использование сим-карт в системах Умный-дом тоже попадает под «возможность блокировки», но вы же понимаете, что этого никто не будет делать. Как оператор определит, вы отправили уведомление через модем скриптом или это вполне себе легальное устройство сделало? Здесь грань очень тонкая…
                  –1
                  Надо еще добавить к минусам — если ваше устройство не умеет правильно обрабатывать пуши с рекламой\предложениями от оператора — то оно будет автоматически подписываться на все платные услуги. Как примеры можете загуглить что-то вроде «ворота подписались на гороскопы» и где-то рядом будет объяснение оператора.
                    0
                    Ну на этом можно споткнуться в любом устройстве. Я предпочитаю пользоваться операторами, которые не «грешат» отправкой пуш-сообщений о подписке на «Сдай экзамен ЕГЭ» и пр… Благо таких как минимум 3
                    0

                    Не раскрыт вопрос стабильности и резервирования. Ушел от usb свистка, т.к. он виснет периодически и его нужно по питанию передергивать. Не удобно.

                      0
                      Этот пункт есть в Минусы. Сбои как правило случаются на «сложных» модемах требовательных к качеству питания и пр… Например на Huawei E3272 у меня сбоев было много. Потом я перешел на более старые или простые модемы и более чем за 12 месяцев ни одного сбоя. Идеальный модем – SIM800C с китайского магазина, который уже распаян на USB. Виден кусочек на заглавной фото. Стоимость порядка 600 руб…

                      Также Gammu позволяет контролировать зависание модема и ребутить его. В данной статье это не рассмотрено, а оставлено для самостоятельного изучения.
                        0
                        ребутить нужно отключением питания, либо монитор цеплять отдельной железкой.
                          0
                          На сколько мне известно, Linux позволяет управлять питанием USB-порта …
                            0
                            от железа ПК зависит, но пример бы не помешали.
                            0
                            В качестве платформы под такие шлюзы можно использовать роутеры с USB портами перешитые на OpenWrt. В них не редко производители закладывают управление питанием USB порта через GPIO как раз для решения проблем с модемами. Например у TP-Link TL-MR3020 есть такая возможность.
                              0
                              К сожалению благодаря бурному развитию SoC таких роутеров все меньше и меньше. Когда я в последний раз смотрел было дешевле купить микротик чем совместимый с openwrt роутер.
                                0
                                На самом деле даже с OpenWRT не надо заморачиваться. Отлично работает с любым MikroTik у которого есть USB-порт (от 3 т.р). Причем там можно usb назначить на любой tcp-порт и обращаться нему напрямую откуда угодно.
                                Да и перезагрузить в случает отсутствия ответа можно простым отключением питания порта – /system routerboard usb power-reset duration=5s
                                  0

                                  А как в микротике запустить gammu?
                                  Или как в gammu обратиться к модему, который проброшен через ethernet?

                                    0

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

                                      0
                                      OpenWRT можно и на некоторые модели Микротика поставить, если нужно
                                        0
                                        В последних версиях ROS уже нельзя
                              0
                              правильные модемы прекрасно понимают команду AT+CFUN=1,1 перегружаясь при этом исчезая и появляясь как устройство в системе
                                0
                                Проблема в том что если девайс хорошо завис то он уже ни на какие команды не реагирует, ему только передергивание питания поможет.
                              0
                              Еще добавлю если кто тоже будет использовать SIM800/900 — им очень важна стабильность питания. Причем не просто держать в определенном диапазоне, а не опускать ниже сколько-то милливольт за ту мили секунду пока идет ток 2А. В даташите на один написано, а на другой — нет.
                                0

                                А подскажете по SIM800C USB, что он из себя технически представляет, это тоже что и без usb, но с uart to usb на борту, или там что-то иное? Просто интересно можно ли добавив к SIM800L USB uart превратить его в usb модем?

                                  0
                                  Да, изначально я с этого и начинал свои тесты с sim800. Если вы к нему подключите usb/uart, то с ним можно начать общаться AT командами, соответственно это уже полноценный модем.

                                  Один у меня именно такой:
                                  Модем из Китая
                                  _https://aliexpress.ru/item/4000012717101.html

                                  Это просто модуль с uart и танталовым кондером.
                                0

                                если нужно промышленное решение, то smpp и что-то типа kannel. А через шлюз(описанное решение) — только опрос систем и оповещения админу.

                                  0
                                  uhubctl отлично перезапускает по питанию.
                                    +2

                                    Можно и без него отправлять в /sys/bus/usb/drivers/usb/unbind сигнал на отключение хаба, или отдельного порта хаба, если модем перестал отвечать "OK" на тестовую команду (вроде бы AT, или AT+).
                                    Отлично работало виде SystemD-юнита на CentOS7 (raspberry pi + d-link hub dub7 v2).


                                    Собсно, команда
                                    echo '2-1.1' > /sys/bus/usb/drivers/usb/unbind
                                    sleep 1
                                    echo '2-1.1' > /sys/bus/usb/drivers/usb/bind
                                      0
                                      Это зависит от того, умеет хаб в управление питанием или нет. Малина видимо умеет.
                                  0

                                  где ж ты раньше был..

                                    0
                                    Ребят, у меня немного другой вопрос — посоветуйте такой девайс… У девайса 2 RJ-11, как у факса или dial-upмодема — запаралеллинные Line и phone. На Line вход приходит аналог, а из phone выхода уходит на обычный аналоговый телефон. Если при входящем звонке, скажем в течение 10 секунд никто не поднял аналоговый телефон на выходе «phone», то девайс через свою симку внутри набирает сотовый офис-менеджера, удерживая при этом входящий звонок на аналоге в режиме ожидания. Цель девайса — расширить функционал аналоговой офисной АТС, так чтобы звонки в случае отсутствия ресепшениста на месте уходили ему/ей (ресепшенисту) сотовый. Как такие девайсы по научному зовутся и где их можно купить?
                                      0

                                      Такие девайсы называются GSM gate. На офисной АТС настраиваете группу дозвона, в качестве одного из офисных телефонов подключаете gsm gate, который и будет пробрасывать звонок на мобилку.
                                      Есть другой вариант — asterisk + fxo/fxs gate + gsm modem — можно получить более гибкий функционал, а в перспективе отказаться от аналоговой АТС. Лёгким этот путь не назовёшь, но возможности asterisk просто поражают — IVR, голосовая почта, конференции...

                                      0
                                      Дивайс называется аналоговый GSM-шлюз, пусть это будет «Sprut». Но нужно убедится что этот шлюз может дозваниваться по сотовой сети на указанный номер при входящем звонке по Line. Подключаем шлюз к внутренней линии\номеру и перенаправляем, средствами мини-атс, на него звонок по не ответу от секретаря.
                                        0

                                        Несколько лет назад как смс шлюз использовал старый андроид телефон и какую-то прогу с гугл плей, get запросом отправляем команду, sms отправляется, использовал для умного дома и nas. Потом телефон умер, а необходимость в уведомлениях отпала. Совсем недавно старенький Самсунг ушел на пенсию, попытался сделать его шлюзом, но уже не удалось найти ту чудесную прогу. На форумах советовали поставить termux, поднять NodeRED, и оттуда рулить отправкой sms. Но у меня андроид 5.0, а termux хочет овер 7.
                                        1- кто-то встречал софт sms шлюзы для андроида?
                                        2- а у кого какие тарифы? Я что-то не смог найти дешевле 50коп за sms, без абон платы.

                                        0
                                        Нашел в статье ошибку:
                                        В примере аргумента replacemessages 1 написан следующий за ним рассмотренный аргумент flash
                                        gammu -s 1 sendsms TEXT +70001234567 -unicode -autolen 5 -flash -replacemessages 1 -text «Тестовое сообщение»

                                        P.S.: Написал первый комментарий, если я в чем-то ошибся, поправьте меня, пожалуйста.
                                          0
                                          Ну это ошибкой не является, просто этот аргумент мы рассмотрели позже
                                          +1

                                          Оператор заблочит сразу, если сообщение будет шаблонное.
                                          У меня дед имеет привычку отправлять всем поздравления с праздником с кнопочного телефона, так его оператор блокирует регулярно...

                                            0

                                            :)
                                            Поэтому этот метод отправки хорошо подходит для двухфакторной аутентификации и подтверждении номера телефона — в сообщении только код и всегда разный

                                            0

                                            Спасибо за статью. Жду продолжения. Интересует прием и обрабодка СМС. Например сохранить данные из СМС в базу данных

                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                            Самое читаемое