Знакомая картина?

[root@pbx scripts]# asterisk -x "sip show registry"
Host                                    dnsmgr Username       Refresh State                Reg.Time
sipnet.ru:5060                          Y      XXXXXXXXXXX         102 Request Sent           Fri, 20 Mar 2020 09:19:31
87.103.236.26:5060                      N      XXXXXX             105 Request Sent           Fri, 20 Mar 2020 09:20:55
sbc.megafon.ru:5060                     Y      XXXXXXXXXXX@       165 Request Sent           Fri, 20 Mar 2020 09:20:28
login.mtt.ru:5060                       Y      XXXXXXXXXXXXXX       105 Request Sent           Fri, 20 Mar 2020 09:19:50

Однажды она меня тоже достала, и я написал скрипт.

Пытался искать готовые рецепты, большинство сводилось к такому:

ну это значит что пакеты уходят, а ответы не приходят.
варианты
1) у вас нет интеренета.
2) у вас упал провайдер
3) у вас фаервол все блочит
4) у вас нет дефаулт гейтевея в системе.
попробуйте попингать те же адреса.. дебаг включите

Попингать адреса получалось, дебаг включал и видел в нём ровно то, о чем говорится в первом предложении цитаты «пакеты уходят, а ответы не приходят». Но почему?

Пункт №1 исключался элементарно. Пункт №2 — тоже, т.к. тестовое соединение с того же IP-адреса, но другого внутреннего хоста работало. Пункт №4 это совсем «жость». А вот №3 — уже ближе. Только не блочит, а почему-то не дает обмениваться пакетами именно хосту с Asterisk'ом.
И происходит это в 99% случаях после пункта №2, когда рвется PPPoE сессия. Сессия-то потом восстанавливается, и доступ в инет из локалки тоже, а вот UDP-сессии залипают.

Вот что нам говорит Mikrotik, через который эти сессии проходят:

[admin@MikroTik] > /ip firewall connection print where dst-address~":5060" and srcnat
Flags: E - expected, S - seen-reply, A - assured, C - confirmed, D - dying, F - fasttrack, s - srcnat, d - dstnat
 #          PR.. SRC-ADDRESS           DST-ADDRESS           TCP-STATE   TIMEOUT     ORIG-RATE REPL-RATE ORIG-PACKETS REPL-PACKETS      ORIG-BYTES
 0  SAC  s  udp  10.X.X.X:5060     80.75.130.83:5060                 59m48s           0bps      0bps        2 172        2 191       1 358 335
 1  SAC  s  udp  10.X.X.X:5060     193.201.229.35:5060               59m47s           0bps      0bps        1 611        1 662         996 786
 2  SAC  s  udp  10.X.X.X:5060     212.53.40.40:5060                 59m44s           0bps      0bps        1 837        1 830       1 114 259
 3  SAC  s  udp  10.X.X.X:5060     87.103.236.26:5060                59m21s           0bps      0bps        2 501        2 509       1 614 239

Это состояние сессий в нормальном режиме, когда всё работает. При отсутствии регистраций, если мне не изменяет память, отсутствует флаг S — seen-reply.

Пробуем срубить залипшие сессии командой:

[admin@MikroTik] > ip firewall connection remove [find where dst-address~":5060" and srcnat]

И, о чудо, буквально через секунду транки восстанавливаются, звонки идут, жизнь расцветает яркими красками! Значит пишем скрипт!

Первое — нам надо управлять Микротом на основе информации с Asterisk. Поэтому скрипт будет запускаться в cron каждые 5 минут на хосте с Asterisk, а управлять Микротом будем по ssh с сертификатом. Вот тут прекрасно всё расписано — как создать ключ и привязать его к новому пользователю на Микроте.

Ну и сам скрипт:

#!/bin/sh

if /usr/sbin/asterisk -x "sip show registry" | grep -q "Request Sent"; then
    echo "$(date) Resetting UDP connections on Mikrotik" >> /var/log/asterisk/mikrotik
    ssh -l admin-ssh -i /XXXX/.ssh/id_dsa 10.X.X.X 'ip firewall connection remove [find where dst-address~":5060" and srcnat]'
    sleep 2
    asterisk -x "sip reload"
fi

На всякий случай через 2 секунды после сброса зависших сессий обновляем регистрации — чтобы уж точно заработало!

С 04.09.2019 скрипт отработал 273 раза, судя по логу. Можно посчитать, сколько он сэкономил мне времени, а менеджерам и их клиентом нервов.

P.S. Подобная ситуация происходит на всех роутерах, которые мне попадались в связке с Asterisk. И только Микрот позволяет решить проблему без затрагивания других сервисов. Остальные роутеры надо тупо перегружать.