OpenSER – ограничение SIP регистрации по IP адресам

Произошел очередной инцидент с исходящим VoIP-трафиком в Колумбию, Гандурас и прочую Зимбабву с аккаунта одного из клиентов. Система мониторинга своевременно оповестила нас о происходящем. Аккаунт был заблокирован до выяснения обстоятельств.В процессе разборов было выяснено, что в этот раз пароли были достаточно криптостойкими, логины более 8 символов да и попыток подбора вообще не было – злоумышленники просто авторизовались с пакистанских адресов и стали понемногу сливать трафик. Клиент попросил реализовать возможность авторизации только с его IP адресов.

В данном случае авторизация проходит на OpenSER.

Решением стало использование функции allow_uri модуля permissions.

Функция работает следующим образом:

при поступлении запроса на авторизацию создается пара в форме (From URI и псевдопеременная) и

И все было бы совсем просто, если бы клиент не находился за NAT’ом…

Для решения проблемы авторизации из-за NAT`а на OpenSER проанализируем при помощи ??функции nat_uac_test запрос на регистрацию пришел из-за NAT или нет. Если клиент находится за NAT’ом, то вызываем функцию fix_nated_register для добавления к полю Contact атрибута «received», содержащего реальный IP, при ответе 200 OK и сохранения в локальной БД OpenSER’a.

Файлы с правилами allow и deny, с именем my-register, ищутся в директории с конфигом OpenSER с соответствующими расширениями.

В моем случае это будут:

/usr/local/etc/openser/my-register.allow
«^sip:00412345678? : «^192\.168\.137\.250$»

/usr/local/etc/openser/my-register.deny
«^sip:00412345678? : ALL

Немного изменяем конфиг самого OpenSER, загружаем модуль:

loadmodule «permissions.so»

…skiped…

а так же для метода REGISTER:

if(nat_uac_test("19")){
     xlog("L_INFO", "NATed REGISTER [$fU@$si]\n");
     fix_nated_register();
}
if (allow_uri("my-register","$si")){
      if(!www_authorize("sip.mydomain.com", "subscriber")){
          xlog("L_NOTICE", "Register authentication failed - M=$rm RURI=$ru F=$fu T=$tu IP=$si ID=$ci\n");
          www_challenge("sip.mydomain.com", "0");
          exit;
      }
}else{
      xlog("L_NOTICE", "Register denied by config - M=$rm RURI=$ru F=$fu T=$tu IP=$si ID=$ci\n");
      sl_send_reply("403", "Register authentication failed");
      exit;
}

…skiped…

и для метода INVITE:

if(nat_uac_test("19")){
     xlog("L_INFO", "NATed REGISTER [$fU@$si]\n");
     fix_nated_register();
}
if (allow_uri("my-register","$si")){
     if(!proxy_authorize("sip.mydomain.com", "subscriber")){
           xlog("L_NOTICE", "Proxy authentication failed - M=$rm RURI=$ru F=$fu T=$tu IP=$si ID=$ci\n");
           proxy_challenge("sip.mydomain.com", "0");
           exit;
      }
}else{
     xlog("L_NOTICE", "Proxy denied by config - M=$rm RURI=$ru F=$fu T=$tu IP=$si ID=$ci\n");
     sl_send_reply("403", "Proxy authentication failed");
     exit;
}

Рестартим OpenSER для применения изменений и пользуемся расширившимся функционалом.

Ниже приведены возможные варианты дебага:

Debug при методе REGISTER и нахождении IP в списке разрешенных:

NATed REGISTER [00412345678@192.168.137.250]
May  5 21:14:19 [16176] DBG:permissions:allow_uri: looking for From: sip:00412345678@sip.mydomain.com;transport=UDP URI: 192.168.137.250
May  5 21:14:19 [16176] DBG:permissions:allow_uri: allow rule found => URI is allowed
May  5 21:14:19 [16176] DBG:core:parse_headers: flags=4000
May  5 21:14:19 [16176] DBG:auth:pre_auth: credentials with given realm not found
Register authentication failed - M=REGISTER RURI=sip:sip.mydomain.com;transport=UDP F=sip:00412345678@sip.mydomain.com;transport=UDP 
T=sip:00412345678@sip.mydomain.com;transport=UDP IP=192.168.137.250 ID=MDhjYjQwOTZjMzFjNGNmMDcwNzI1NTU0ODA1Zjg1MTU.

Debug при методе и нахождении IP в списке запрещенных:

NATed REGISTER [00412345678@192.168.137.250]
May  5 21:10:54 [13758] DBG:permissions:allow_uri: looking for  From: sip:00412345678@sip.mydomain.com;transport=UDP URI:  192.168.137.250
May  5 21:10:54 [13758] DBG:permissions:allow_uri: deny rule found => URI is denied
Register denied by config - M=REGISTER  RURI=sip:sip.mydomain.com;transport=UDP  F=sip:00412345678@sip.mydomain.com;transport=UDP  
T=sip:00412345678@sip.mydomain.com;transport=UDP IP=192.168.137.250  ID=NDA2Y2NlMGFjNzZjN2YwZDJjYjllYzUxNDJlYmEzYjA.

при методе INVITE и нахождении IP в списке разрешенных:

NATed REGISTER [00412345678@192.168.137.250]
May  5 20:19:20 [13299] DBG:permissions:allow_uri: looking for From: sip:00412345678@sip.mydomain.com;transport=UDP URI: 192.168.137.250
May  5 20:19:20 [13299] DBG:permissions:allow_uri: allow rule found => URI is allowed
May  5 20:19:20 [13299] DBG:core:parse_headers: flags=10000
May  5 20:19:20 [13299] DBG:auth:pre_auth: credentials with given realm not found
Proxy authentication failed - M=INVITE RURI=sip:8499XXXXXXX@sip.mydomain.com;transport=UDP F=sip:00412345678@sip.mydomain.com;transport=UDP 
T=sip:8499XXXXXXX@sip.mydomain.com;transport=UDP IP=192.168.137.250 ID=NTkxNDhiMTlmOWNiOWY1MjM2Nzk0YTY3ODgxNzYzMjU.

Debug при методе INVITE и нахождении IP в списке запрещенных:

NATed REGISTER [00412345678@192.168.137.250]
May  5 20:26:04 [13758] DBG:permissions:allow_uri: looking for From: sip:00412345678@sip.mydomain.com;transport=UDP URI: 192.168.137.250
May  5 20:26:04 [13758] DBG:permissions:allow_uri: deny rule found => URI is denied
Proxy denied by config - M=INVITE RURI=sip:8499XXXXXXX@sip.mydomain.com;transport=UDP F=sip:00412345678@sip.mydomain.com;transport=UDP 
T=sip:8499XXXXXXX@sip.mydomain.com;transport=UDP IP=192.168.137.250 ID=MDk0YTQ1ODMzZjE0ODAxZDMwMGYxZjU1YmIyOTc4ZWY.

Источник статьи