Как стать автором
Обновить

Проводим GPON от МГТС в свой сервер на Linux + своя мини-атс на asterisk

Уровень сложности Средний
Время на прочтение 11 мин
Количество просмотров 14K

Disclaimer

На Хабре и на профильных форумах (типа 4pda) уже достаточно статей на тему того, как отказаться от GPON-роутера от МГТС и вывести интернет напрямую в свой роутер.
Большинство статей описывают опыт подключения к роутерам Mikrotik. Мне же это всё не подошло, так как у меня стоит сервер (обычный PC, хоть и достаточно мощный), который выполняет роль сетевого шлюза и много чего ещё. Требования у меня сформировались следующие:

  1. Сервер на базе Linux (в моём случае на базе дистрибутива Gentoo);

  2. Сохранить обратную совместимость: городской стационарный телефон (сам аппарат) должен продолжать работать в прежнем режиме;

  3. Не "ломать" и не "хакать" роутер от самого МГТС;

  4. Организовать локальную телефонию.

Чуть подробнее распишу по пунктам.

Исторически сложилось, что сервер у меня под дистрибутивом Gentoo. И для данной задачи это оказалось большим плюсом: Asterisk больше не делает пакетов. Хочешь установить? Изволь делать из исходников. В принципе, скрипты установки там определяют дистрибутив, и ставят зависимости пакетным менеджером. В Gentoo же есть ebuild и ставится всё нативным для неё способом.

С обратной совместимостью всё достаточно просто. Для людей старшего поколения все эти модные штуки ни к чему. Они пользуются стационарным аппаратом и объяснять им про sip-телефонию ни к чему. Как пользовались, так и будут пользоваться - ничего не меняется.

Ковырять роутер так же не имеет смысла. Оператор регулярно закручивает гайки в плане доступа к внутренней кухне. Сотрудники оператора так же читают эти статьи и закрывают дырки в своих роутерах, через которые можно получить настройки абонентского терминала. От роутера нам понадобятся только серийный номер, MAC-адрес интерфейса и SN Password. Всё это отображается прям на первой странице после логина: можно заскриншотить эти данные и выключить его навсегда.

Ну и локальная телефония. Если у вас есть дача с интернетом с каналом хотя бы в 10МБит или ещё квартира, то по VPN организовываем локальную сеть, подключаем стационарный аппарат и можно будет разговаривать в пределах своей сети через интернет.

Железо

Здесь, к сожалению, не всё так бюджетно, как хочется. Опущу конфигурацию сервера: читатели статьи наверняка уже имеют у себя необходимый конфиг. Кроме того, для asterisk много ресурсов не нужно.

Итак, понадобятся:

  1. SFP GPON ONU/ONT Stick. На али их много от 3.000 до 5.000 руб.;

  2. Оптический патч-корд на необходимую длину: 200-500 руб. - 1-10 метров;

  3. Переходник: 40-50 руб.;

  4. Медиаконвертер: 1.500-2.000 руб.;

  5. Опционально: FXS-шлюз для подключения стационарного аппарата. По сути конвертер sip<->аналоговая линия: 3.000-4.000 руб. Количество портов которого определяется количеством подключаемых аппаратов;

По первому пункту стоит иметь в виду, что нужны именно абонентские SFP (ONU и ONT - одно и то же). OLT - терминал провайдера и он для данных целей не подойдёт. Так же подойдут как GPON, так и XPON терминалы. EPON - нет. Также с модулем я бы порекомендовал дополнительно заказать 2-3 небольших радиатора с двусторонним термоскотчем. Хоть в конструкции модуля и предусмотрен радиатор, но всё равно он разогревается до 55-60 градусов. С радиаторами опускается до 40-45. Впрочем, это по желанию, так как производитель гарантирует штатную работу до 70 градусов. Я решил перестраховаться и установил с тыльной стороны и по бокам 3 радиатора.

GPON ONU Stick 1
GPON ONU Stick 1
GPON ONU Stick 2
GPON ONU Stick 2

Обратите внимание на синий индикатор на разъёме SFP на второй картинке. Большинство из них поставляются с разъёмом UPC. В принципе, можно найти SFP с разъёмом APC, но они, почему-то, очень редкие и дорогие.

Далее немного лирики про типы коннекторов. Для GPON используются концевики следующих типов:

SC APC: Зелёный коннектор
SC APC: Зелёный коннектор
SC UPC: Синий коннектор
SC UPC: Синий коннектор

Как правило провайдер использует коннектор APC типа, а SFP модули поставляются с разъёмом для UPC. Разница между ними невелика: APC имеет торец оптоволокна со скошенным под 8 градусов срезом. UPC имеет прямой срез. Можно вставить коннектор APC в разъём UPC, и даже кое-как это будет работать, но не рекомендуется. Торец оптоволокна или входного разъёма может повредиться, кроме того могут быть потери из-за ненадёжного соединения.

Теперь о том, что требуется для коммутации. Если планируется повесить медиаконвертер прямо там, где был роутер провайдера, то достаточно подобного аттенюатора:

Аттенюаторы UPC->APC, APC->UPC
Аттенюаторы UPC->APC, APC->UPC

На али стоит примерно 250 руб.

Я же взял простой переходник:

Переходник APC-APC
Переходник APC-APC

Патч-корд с концевиками APC-UPC:

Патч-корд
Патч-корд

В зависимости от места расположения сервера можно выбрать произвольную длину кабеля. По моему мнению оптическая среда менее "шумная" для сигнала по сравнению с медью. Поэтому лучше провести 10 метров оптики, чем 10 метров витой пары.

Медиаконвертер мне подошёл TP-LINK MC220L, но можно брать и аналогичный. Главное - не брать совсем дешёвые китайские. Взял на пробу ноунейм, произведённый в Китае, но с отечественным шильдиком и пожалел: в нём отсутствовала минимальная защита от статики, которая вся стекала в SFP-модуль, который по итогу вышел из строя.

Вместо медиаконвертера попытался использовать PCI-E сетевую карту с разъёмом для SFP, но, видимо, из-за особенностей модуля, в который встроен GPON-терминал, такая конфигурация не завелась.
Модуль, к слову, загружается около минуты, так что не ожидайте поднятия линка в медиаконвертере сразу при включении.

Ну и наконец FXS-шлюз. Потребуется тем, кто хочет сохранить возможность использования аналогового аппарата для звонков. Увы, самые простейшие от Yeastar начинаются от 3.000 руб. Я взял модель Yeastar TA100: простенькая, но настроек для подключения в SIP достаточно.

Ну и наконец три патч-корда:

  • От медиаконвертера в порт сетевой карты сервера (RJ-45);

  • От сервера через свитч в FXS-шлюз (RJ-45);

  • От FXS-шлюза до стационарного телефона (RJ-11).

Настройка железа

Для того, чтобы настроить SFP-модуль, нам потребуется информация с первой страницы роутера после авторизации. У меня была установлена достаточно старая версия роутера. Возможно, сейчас её уже не ставят, но наверняка стоит у многих, кто давно себе провёл GPON от МГТС.

ZTE F660
ZTE F660

Заходим в веб-интерфейс роутера (по умолчанию http://192.168.1.1) и видим страницу:

Поля, выделенные красным и жёлтым, нужно выписать в текстовый файл
Поля, выделенные красным и жёлтым, нужно выписать в текстовый файл

Далее заходим в меню "Сетевой интерфейс":

...и MAC-адрес
...и MAC-адрес

MAC-адрес, однако, можно увидеть и по другому:

  • В Windows набрать > arp -a <IP-адрес роутера>;

  • В Linux посмотреть через $ ip neigh.

Будет тот же самый MAC.

На этом можно роутер отключать, снимать и убирать в дальний угол. Больше он не потребуется.

Подключение SFP-модуля

Схема подключения тривиальна:

Схема подключения
Схема подключения

Так как SFP-модуль по умолчанию работает в подсети 192.168.1.0/24 и имеет адрес 192.168.1.1, то нужно немного поправить конфигурацию сети сервера:

  • $ ip a add 192.168.1.2/24 dev ext0 - устанавливаем адрес на внешний интерфейс для доступа к веб-интерфейсу SFP-модуля;

  • $ iptables -t nat -A POSTROUTING -d 192.168.1.0/24 -j SNAT --to-source 192.168.1.2 - прокидываем NAT до модуля, так как он отвечает только на адреса внутри своей подсети (работает по L2).

  • $ sysctl net.ipv4.ip_forward = 1 - разрешаем форвардинг.

Теперь можно входить из домашней сети в веб-интерфейс SFP-модуля http://192.168.1.1:

User: adminPassword: admin
User: admin
Password: admin

Переходим в меню Settings и заполняем нижеуказанные поля:

Основные настройки подключения к GPON
Основные настройки подключения к GPON

Отдельно стоит отметить поля Vendor key, MAC-адрес, MAC-Key.

  • Vendor-Key зависит от производителя роутера провайдера. Здесь можно найти Vendor-Key для разных производителей. У меня ZTE, поэтому прописываю ZTEG;

  • MAC-адрес указываем в нижнем регистре без двоеточий. Например: 00aabb1122ff;

  • MAC-Key формируется по следующему алгоритму. Например, для вышеприведённого адреса:
    $ echo -n "hsgq1.9a00AABB1122FF" | md5sum
    6073af93d6ca36099800f90cab965e02 -

  • Software/Hardware version прописываем как есть.

Отдельно хочу обратить внимание, что это две разные формы, каждая из которых имеет собственную кнопку "Apply Changes". Внесли в первую, нажали первую кнопку Apply. Внесли во вторую, нажали вторую кнопку Apply.

Перейдём во вкладку VLAN Settings:

Режим Manual -> Transparent Mode
Режим Manual -> Transparent Mode

Все VLAN будет разбирать ядро Linux на сервере. SFP-модулю оставим минимум задач, он и так слабый.

После применения настроек убедимся в правильности внесения настроек в разделе GPON:

ONU State O5 говорит о правильности настройки
ONU State O5 говорит о правильности настройки

Если статус отличается от O5, то либо ошиблись в настройках во вкладке Settings, либо плохое соединение на оптических каналах. Я час потратил на проверку настроек, прежде, чем проверил надёжность соединения всех переходников. Банально не до конца вставил оптический патч-корд в переходник.

Настройки сети

Прежде, чем настраивать сеть, нужно определиться по каким VLAN передаётся Интернет и собственно SIP. Как правило, это VLAN3/VLAN30 - Интернет и VLAN5/VLAN50 - SIP. Чтобы не гадать на кофейной гуще, спросим об этом у провайдера. Нет, не у оператора техподдержки, а у терминала OLT. :-)

Все первоначальные настройки передаются по OMCI-протоколу в кадрах PON. То есть прочитать их после терминирования PON ONT-терминалом не получится. К счастью, в прошивке модуля есть утилита omcicli, через которую эти настройки можно посмотреть.

Согласно инструкции нужно запросить MIB 84, который предоставит список VLAN. Подключаемся по telnet к SFP-модулю и выполняем команду omcicli mib get 84, после чего получим список нужных VLAN. Например:

EntityID: 0x101
FilterTbl[0]: PRI 0,CFI 0, VID 3
FwdOp:  0x04
NumOfEntries: 1
=================================
EntityID: 0x103
FilterTbl[0]: PRI 5,CFI 0, VID 5
FwdOp:  0x04
NumOfEntries: 1

Видно, что используются VLAN3 и VLAN5. Как правило, эти VLAN используются на OLT ZTE.

Создаём их:

  • $ ip link add link ext0 name internet type vlan id 3 - новый интерфейс с именем internet;

  • $ ip link add link ext0 name sip type vlan id 5 - новый интерфейс с именем sip.

Получаем адрес для интернет-подключения:

  • $ /sbin/dhclient -pf /run/dhclient-internet.pid -sf /sbin/dhclient-script -lf /var/lib/dhcp/dhclient.internet.leases -nw internet

Стоит отметить, что lease-файлы нужно указывать отдельно для каждого интерфейса, так как dhcp-клиенты начнут одновременно писать в один и тот же файл, что может привести к ошибкам в их работе.

SIP-интерфейс пока не трогаем, ниже объясню почему.

Настройки SIP

Для настройки SIP нужны следующие параметры:

  • Domain name;

  • Auth User;

  • Auth Password;

  • Список Outbound Proxy.

Domain name, который предоставляет МГТС, не является реальным хостом и не разрешается в какой-то конкретный адрес. Для работы SIP используется только Outbound Proxy. Первые три настройки получим через omcicli. Список Outbound Proxy пока отложим.

Вывод настроек
$ omcicli mib get 00148
X AuthSecMethod X
EntityId: 0x0001
ValidSchem: 3
Username1: +749NNNNNNNN@msk.ims.mgts
Password: 0x3030303030303030303000000000000000000000000000 
Realm: 0x00000000000000000000000000000000000000000000000000 
Username2: 0x2e727500000000000000000000000000000000000000000000

Стоит рассказать, как разобрать этот вывод.
Имя пользователя@домен: EntityId1.Username1 + decode_hex( EntityId1.Username2 )
Пароль: decode_hex( EntityId1.Password )

Скрипт на коленке на python - decode_hex
#!python3

import sys
import argparse

def main():
    _argp = argparse.ArgumentParser( 'HEX to String' )
    _argp.add_argument( 'hexstr', help='HEX string' )
    _args = _argp.parse_args()

    _hexstr = _args.hexstr.strip( ' \t\r\n' ).lower()
    _lhexstr = len( _hexstr )
    _result = ''
    _start = 1 if _hexstr.startswith( '0x' ) else 0
    for i in range( _start, int( _lhexstr / 2 ) ):
         _asc = int( '0x' + _hexstr[ (2*i) : (2*i)+2 ], 0 )
         if _asc < 0x20 or _asc > 0x7f: _result += '.'
         else: _result += chr( _asc )

    print( _result )


if __name__ == "__main__":
    sys.exit( main() )

Последним пунктом потребуется получить список OutboundProxy. Именно поэтому я отложил запуск dhcp-клиента на sip-интерфейс. Этот список предоставляет DHCP-сервер на SIP-интерфейсе в опции под номером 150 (TFTP Address list). Их можно получить скриптом dhclient-хуком и прописывать соответствующие роуты на sip-интерфейс.

Hidden text

Здесь я бы обратил внимание на то, что в роуты надо прописывать не сами адреса, а подсети, в которые они входят. Как минимум по маске /30, а лучше целиком /24.
Я долго не мог понять, почему у меня звонки проходят, а звука нет. Так вот, если Proxy 192.168.5.100, то следующий адрес - 192.168.5.101, - используется для передачи звуковых данных.

Кроме роутов лучше прописать NAT для SIP-интерфейса, иначе прокси не ответят на незнакомый адрес:

  • $ iptables -t nat -A POSTROUTING -o sip -j MASQUERADE

Окончательно настраиваем интерфейс sip:

  • $ /sbin/dhclient -pf /run/dhclient-sip.pid -sf /sbin/dhclient-script -lf /var/lib/dhcp/dhclient.sip.leases -nw sip

Подведём итог:

  1. Интернет-интерфейс в особенной настройке не нуждается. Достаточно поднять VLAN, по DHCP получить адрес и сделать его апстримом для нашего сервера. Здесь рассказывать нечего;

  2. SIP-настройки можно получить через omcicli команду в SFP-модуле;

  3. OutboundProxy адреса можно получить через 150 Option dhcp-клиентом.

Остаётся настроить Asterisk и FXS-шлюз.

Asterisk

Здесь меня закидают помидорами, но я использовал deprecated chan_sip. Да, я знаю про pjsip, но... так уж вышло.

Требования такие:

  1. Входящий звонок должен поступать всем внутренним абонентам. Кто первый трубку возьмёт, тот и молодец;

  2. Исходящий идёт через trunk МГТС;

  3. Все внутренние абоненты могут звонить друг другу без ограничений.

Ставим asterisk
$ cat /etc/portage/package.use/asterisk
net-misc/asterisk codec2 doc snmp syslog -pjproject

$ emerge -av asterisk

These are the packages that would be merged, in order:

Calculating dependencies... done!
Dependency resolution took 0.94 s.

[ebuild   N    ] net-misc/asterisk-18.13.0:0/18::gentoo  USE="caps codec2 doc iconv snmp ssl syslog systemd -alsa -blocks -bluetooth -calendar -cluster -curl -dahdi -debug -deprecated -freetds -gtalk -http -ilbc -ldap -lua -mysql -newt -odbc -oss -pjproject -portaudio -postgres -radius (-selinux) -span -speex -srtp -static -statsd -unbound -vorbis -xmpp" LUA_SINGLE_TARGET="lua5-1 -lua5-3 -lua5-4" VOICEMAIL_STORAGE="-imap -odbc" 27 469 KiB

Total: 1 package (1 new), Size of downloads: 27 469 KiB

Would you like to merge these packages? [Yes/No]

Конфиг предполагается простейший, поэтому никаких БД и прочего не ставлю. По вкусу можно добавить желаемое.

sip.conf
[general]
externaddr=<int0-ip>:5060
language=ru
context=default
allowoverlap=no
udpbindaddr=<int0-ip>
tcpenable=no
tcpbindaddr=<int0-ip>
transport=udp
srvlookup=yes
allowguest=no
limitonpeers=yes
useragent=ZXHN ZTEF660/V2.3.1P2T7

[authentication]

[localphones](!)
type=friend
context=call-out
secret=mypass
host=dynamic
nat=no
qualify=yes
canreinvite=no
callgroup=1
pickupgroup=1
call-limit=1
dtmfmode=auto
disallow=all
allow=alaw
allow=ulaw
allow=g729
allow=g723
allow=g722

[21](localphones)
callerid="n21" <21>
[22](localphones)
callerid="n22" <22>
[23](localphones)
callerid="n23" <23>

[mgts]
host=msk.ims.mgts.ru
insecure=invite,port
type=friend
sipregister=yes
fromdomain=msk.ims.mgts.ru
disallow=all
allow=alaw
dtmfmode=auto
secret=<МГТС-пароль>
defaultuser=+7<номер телефона>@msk.ims.mgts.ru
trunkname=mgts
fromuser=+7<номер телефона>
callbackextension=mgts
context=call-in
qualify=yes
directmedia=no
nat=force_rport,comedia
outboundproxy=<OUTBOUND_PROXY>

Хост msk.ims.mgts.ru НУЖНО прописать в /etc/hosts, так как по мнению chan_sip он обязан разрешаться хоть в какой-нибудь IP. Желательно, чтобы этот хост совпадал с OutboundProxy.

queues.conf
[local-phones]
strategy = ringall
member => SIP/21
member => SIP/22
member => SIP/23

Входящий звонок на всех локальных абонентов.

extensions.conf
[general]
static=yes
writeprotect=no
[globals]
[default]

[handup-sip]
exten => _X!,1,HangUp()

;Исходящие звонки
[call-out]
;Звонок на внутренний номер (2 цифры)
exten => _XX,1,Dial(SIP/${EXTEN})
include => handup-sip

;Звонок на внешний номер (больше, чем 2 цифры)
exten => _XX.,1,Dial(SIP/${EXTEN}@mgts)

;Входящие звонки
[call-in]
exten => mgts,1,Queue(local-phones,hr)

Номера локальных абонентов я ограничил двумя цифрами, так как в Москве есть трёхзначные номера. Например, 100 - точное время, 122 - позвонить в поликлинику.

Запускаем systemctl enable --now asterisk. Проверяем:

$ asterisk -r
Connected to Asterisk 18.13.0 currently running on gateway
gateway*CLI> sip show registry
Host                                    dnsmgr Username       Refresh State                Reg.Time
msk.ims.mgts.ru:5060                    N      +7<номер телефона>       105 Registered           
1 SIP registrations.
gateway*CLI> sip show users
Username                   Secret           Accountcode      Def.Context      ACL  Forcerport
mgts                       <пароль>                      call-in          No   Yes
21                         mypass                            call-out         No   No
22                         mypass                            call-out         No   No
23                         mypass                            call-out         No   No

Регистрация прошла. Можно подключать локальных абонентов. Настройку VPN-сервера и sip-клиентов я опущу, так как это не является целью статьи. Для Windows я использую MicroSIP, для Android установил первый попавшийся с минимальными настройками.

Вкратце лишь опишу настройку FXS-шлюза. Выше я уже писал, что решил использовать Yeastar TA100.

Настройка Yeastar TA100

По умолчанию, шлюз получает IP-адрес по DHCP. Пропишем для него какой-нибудь адрес в своём dhcp-сервисе на сервере и зайдём в веб-интерфейс.

Логин: adminПароль: password
Логин: admin
Пароль: password

Идём в настройки шлюза:

Настройки аналогового порта
Настройки аналогового порта
Регистрация порта
Регистрация порта

После нажатия на кнопку "Сохранить", зачем-то нужно ещё нажать кнопку "Применить"

...иначе ничего не заработает. Подключаем телефонный аппарат кабелем к шлюзу и пробуем звонить на внешний номер. Так же с внешнего номера звоним на свой домашний. Всё должно работать.

На мобильном телефоне ставим VPN-клиент, настраиваем, вводим настройки локального абонента из пула, указанного в sip.conf и так же прозваниваем. При этом одновременно звонок должен поступать как на стационарный аппарат, так и в sip-клиент.

Опционально: На даче или в другой квартире на роутере также поднимаем VPN-подключение к домашнему серверу, подключаем ещё один FXS-шлюз, аналогично настраиваем и получаем внутреннюю телефонную линию с возможностью звонить как локально на внутренние номера, так и с городского номера на внешние номера.

PS

Я намеренно не стал описывать процесс настройки сети и VPN-сервера, так как подобных мануалов в сети достаточно, да и статья без того вышла достаточно объёмной. Кто-то захочет использовать systemd-networkd, скрипты своего дистрибутива, pptpd, openvpn, что угодно. Это уже за рамками статьи.

Оборудование из раздела "Железо" приобреталось либо на али, либо в местных магазинах. Если кому интересно будет, то поделюсь ссылками.

На сим откланиваюсь, так как все и так уже устали читать, а я - писать. :-)

Теги:
Хабы:
+21
Комментарии 26
Комментарии Комментарии 26

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн