Vous êtes sur la page 1sur 254

Julho/2008

Por: Flvio Eduardo de Andrade Gonalves


flavio@asteriskguide.com

Data: segunda-feira, 2 de junho de 2008 Arquivo:LivroSERr10-1.doc Reviso: 23


Gonalves, Flavio Eduardo de A.
Telefonia IP com SIP: Abordando o SIP Express Router
Florianpolis: Ttulo Independente, 2008
242p.

ISBN: 978-85-906904-1-2

1. Tecnologia 2. Softswitches I. Gonalves, Flavio


II.Ttulo
Prefcio

Algumas vezes, aps terminar um trabalho, eu me pergunto qual o valor que ele tem para o
pblico que o vai adquirir. O OpenSER uma plataforma sofisticada de telefonia IP. Dando
suporte a instalaes com alguns milhes de assinantes, ele capaz de suportar at mesmo
redes NGN em pequenos pases em desenvolvimento. O uso de software livre, e minha
opinio muda o balano do poder. Antes, pases e empresas estavam submetidos ao poder dos
fabricantes dos equipamentos de telefonia que detinham toda a informao para construo e
operao deste tipo de central. Agora, com software livre, mesmo que voc adquira de um
fabricante tradicional, o equilbrio maior, pois a tecnologia est disponvel para todos. No
ltimo ano no s vi um aumento do uso de software livre, mas uma sensvel reduo de
custos nas plataformas tradicionais, seja na forma de reduo efetiva de preos, seja na forma
de incorporao de funcionalidades antes vendidas separadamente.
O valor deste trabalho ema minha opinio permitir que em pouco mais de uma semana
ocorra no conhecimento de telefonia IP com SIP e OpenSER de quem puder se dedicar a ele.
Atravs de uma seqncia didtica possvel acelerar a curva de crescimento at o ponto de
ter um sistema funcionando.
Ns estamos iniciando uma nova era na rea de colaborao. Voz e vdeo sobre IP esto
comeando a dominar o mundo das telecomunicaes em um movimento de ruptura capaz
de mudar toda a indstria. A tecnologia SIP (Session Initiation Protocol) est no centro desta
revoluo. Eu acredito que o SIP no momento o protocolo mais usado para Voz e Vdeo
sobre IP.
No futuro, quando as pessoas aprenderem a usar a tecnologia, o SIP ser para as
comunicaes de voz o que o e-mail hoje para as comunicaes em texto. Ns estamos
comeando com ilhas SIP dentro dos provedores de VoIP, empresas e mesmo governos. Em
um futuro prximo, as barreiras entre as ilhas sero quebradas e voc poder se comunicar
com qualquer um em qualquer lugar sem pagar nenhuma tarifa.
As nicas tarifas que voc vai pagar no futuro so o acesso a rede de dados, por causa da
disponibilidade de voz e vdeo sobre IP, tudo em breve ser apenas comunicao de dados.
Eu me lembro dos primeiros dias do e-mail no incio dos anos 90. Levou algum tempo at
que todos tivessem um endereo de e-mail. A mesma coisa poderia estar acontecendo agora
no mundo SIP. Infelizmente, os provedores SIP ainda se comportam como ilhas no
permitindo o roteamento entre domnios.
Com a introduo do 3G, 4G e WiMAX, as comunicaes de dados em alta velocidade esto
se tornando amplamente disponveis na indstria de telefonia mvel. Novos telefones de
fabricantes conhecidos esto comeando a suportar WiFI, WiMax e obviamente 3G. Os
clientes SIP podem rodar nestas plataformas o que pode potencialmente mudar toda a
indstria em um futuro prximo.
claro, as companhias telefnicas iro tentar, legitimamente, proteger suas fontes de receita,
mas elas no podem esconder a infra-estrutura SIP j instalada. Lentamente, os usurios vo
comear a usar os clientes SIP em seus telefones mveis cortando os custos de comunicao.
O movimento, mesmo sem um grande patrocinador acabar sendo espalhado de boca em
boca at se tornar um fenmeno comum como o e-mail.

i
A infra-estrutura necessria para as comunicaes em SIP tem no seu componente principal
um servidor SIP Proxy. O OpenSER um dos melhores SIP Proxies disponveis no
mercado. Ele robusto, escalonvel e licenciado de acordo com a licena GNU GPL. A idia
deste livro ensinar como implantar a arquitetura do protocolo SIP usando o OpenSER. Eu
espero que este livro ajude a voc, se voc est aprendendo SIP, ou a implantar uma infra-
estrutura na sua companhia, escola ou governo. Eu desejo a voc sucesso na sua implantao
e sinceramente espero que este material o ajude.

ii
Audincia
Este livro para pessoas com algum conhecimento em telefonia IP e SIP. Conhecimento de
Linux indispensvel para realizar os laboratrios deste livro. recomendvel conhecimento
em VoIP sem o qual alguns assuntos podem demorar a ser entendidos.

Sobre o Autor
Flvio E. Gonalves nasceu em 1966 em Minas Gerais, Brasil. Tendo sempre sido um
aficionado por computadores, ganhou o seu primeiro computador pessoal em 1983 e desde
ento tem sido quase um vcio. Formou-se em engenharia em 1989 com foco em desenho e
manufatura auxiliada por computador.
Atualmente ele o Diretor Presidente da V.Office Solues em Redes e Telecomunicaes,
uma empresa de consultoria e treinamento dedicada as reas de redes, segurana,
telecomunicaes e software bsico desde 1996. Desde 1993 participou de vrios programas
de certificao tendo sido certificado como Novell MCNI/MCNI, Microsoft MCSE/MCT,
Cisco CCSP/CCNP/CCDP, Asterisk dCAP entre outras.
Ele comeou a escrever sobre software com cdigo aberto porque acredita que a forma como
os programas de certificao eram organizados no passado era boa para os que queriam
aprender. Alguns livros hoje so escritos por pessoas extremamente tcnicas que, as vezes
no tem uma idia clara de como as pessoas aprendem. Ele tentou usar sua experincia de 15
anos como instrutor para ajudar as pessoas a aprenderem software de telefonia de cdigo
aberto. Sua experincia com redes, analisadores de protocolo e telefonia IP, combinadas com
sua experincia de ensino, deram a ele um diferencial para escrever este livro. Este o
segundo livro que ele escrever, o primeiro foi o Guia de Configurao para o Asterisk PBX.
Como CEO da V.Office, Flavio E. Gonalves balanceia seu tempo entra a famlia, trabalho e
diverso. Ele pai de dois filhos e mora em Florianpolis, SC, Brasil. Ele pode ser contatado
em flavio@asteriskguide.com

Agradecimentos
Eu gostaria de agradecer a Guilherme Goes que escreveu boa parte do captulo 6 e
desenvolveu o SerMyAdmin para este livro, A Bogdan Andrei Iancu por ter revisado vrias
sees o que permitiu melhorar sensivelmente os scripts e tambm a todos os alunos que
assistiram o Curso de OpenSER antes e deram um bom feedback usado no livro.

iii
ndice
Introduo ao SIP .................................................................................................................... 1
Objetivos deste captulo ......................................................................................................... 1
Teoria bsica de operao do SIP .......................................................................................... 2
Exemplo de uma mensagem SIP........................................................................................ 2
SIP URIs ............................................................................................................................ 2
O trapezide SIP ................................................................................................................ 3
Componentes de uma rede SIP .............................................................................................. 4
Processo de Registro do SIP .............................................................................................. 5
Operao do SIP em modo Proxy. ..................................................................................... 6
Operao em modo de redirect. ......................................................................................... 6
Mensagens Bsicas ................................................................................................................ 6
Fluxo de um dilogo SIP........................................................................................................ 7
Transaes e dilogos no SIP .............................................................................................. 13
O protocolo RTP .................................................................................................................. 14
Codecs .................................................................................................................................. 14
DTMF-Relay ........................................................................................................................ 14
Real Time Control Protocol - RTCP.................................................................................... 14
Session Description Protocol - SDP .................................................................................... 15
O Protocolo SIP e o modelo OSI. ........................................................................................ 16
Viso geral de um provedor VoIP ....................................................................................... 16
Sumrio ................................................................................................................................ 18
SIP Express Router ................................................................................................................ 19
Onde ns estamos? ............................................................................................................... 19
O que o SIP Express Router? ............................................................................................ 20
Lista de recursos e cenrios de uso. ..................................................................................... 21
Cenrios de uso .................................................................................................................... 21
Provedores de Internet de valor agregado ........................................................................ 21
Provedores de Telefonia IP .............................................................................................. 21
Telefonia IP em universidades e na Internet II ................................................................ 21
Concentrador de telefonia para empresas do tipo .com e .gov ............................... 22
Arquitetura do OpenSER e o arquivo openser.cfg............................................................... 23
Ncleo e mdulos ............................................................................................................ 23
Sees do arquivo openser.cfg ......................................................................................... 24

iv
Sesses, Dilogos e Transaes. ...................................................................................... 24
Processamento de mensagens no openser.cfg .................................................................. 25
Comportamento esperado de um SIP Proxy .................................................................... 25
Operao em modo stateful .............................................................................................. 26
Validao do pedido ........................................................................................................ 26
Pr-processamento das informaes de roteamento. ....................................................... 26
Determinando os alvos dos pedidos ................................................................................. 27
Encaminhamento do pedido ............................................................................................. 27
Processamento da Resposta ............................................................................................. 27
Diferenas entre Strict Routing e Loose Routing ................................................................ 28
Entendendo SIP e RTP......................................................................................................... 29
Sumrio ................................................................................................................................ 30
Instalando o OpenSER .......................................................................................................... 31
Onde estamos? ..................................................................................................................... 31
Necessidades de Hardware .................................................................................................. 31
Instalando o Linux para o OpenSER ................................................................................... 32
Baixando e instalando o OpenSER. ................................................................................. 40
Rodando o OpenSER no boot do Linux .......................................................................... 41
Estrutura de diretrios do OpenSER v1.2 ............................................................................ 42
Arquivos de Log .................................................................................................................. 43
Comandos de inicializao .................................................................................................. 43
Sumrio ................................................................................................................................ 43
Configurao padro. ............................................................................................................ 45
Onde estamos? ..................................................................................................................... 45
Configurao padro ............................................................................................................ 46
Listagem e descrio dos comandos .................................................................................... 46
Anlise do arquivo padro ................................................................................................... 49
Usando a configurao padro. ............................................................................................ 53
Conceitos bsicos de roteamento SIP .................................................................................. 54
Transaes e dilogos ...................................................................................................... 54
Pedidos Iniciais e Seqenciais ......................................................................................... 55
Roteamento no contexto de uma transao ...................................................................... 55
Roteamento no contexto de um dilogo........................................................................... 56
Lab. Verificando um dilogo completo ........................................................................... 56
Lab. Rodando sem estado (stateless) ............................................................................... 58

v
Lab. Desabilitando o registro de rotas (Record-route)..................................................... 59
Sumrio ............................................................................................................................ 59
Autenticao com MySQL .................................................................................................... 60
Onde estamos? ..................................................................................................................... 61
O modulo Auth_DB ............................................................................................................. 61
Seqncia de autenticao para pedidos de registro: ........................................................... 62
Captura de uma seqncia de registro. ............................................................................ 62
Trecho do cdigo de registro com autenticao. ............................................................. 64
Seqncia de autenticao do INVITE ................................................................................ 64
Seqncia de pacotes de um pedido do tipo INVITE. ..................................................... 65
Trecho do cdigo do INVITE .......................................................................................... 66
Autenticao do tipo Digest ................................................................................................. 66
O cabealho WWW-Authenticate Response ................................................................ 67
O cabealho Authorization Request ............................................................................. 67
QOP Qualidade da proteo.......................................................................................... 68
Instalando o suporte ao MySQL. ......................................................................................... 68
Anlise do arquivo openser.cfg............................................................................................ 72
O script openserctl ............................................................................................................... 74
Arquivo de recursos do Openserctl ...................................................................................... 76
Laboratrio: Autenticao. .............................................................................................. 78
Melhorando o script ............................................................................................................. 80
Gerenciando mltiplos domnios ......................................................................................... 80
Rotas alternativas ................................................................................................................. 81
Pedidos do tipo REGISTER............................................................................................. 81
Pedidos diferentes de REGISTER route[3] .................................................................. 81
Gerenciando chamadas do mesmo domnio .................................................................... 83
As funes check_to() e check_from() ................................................................................ 84
Usando Aliases..................................................................................................................... 84
Tratando pedidos do tipo CANCEL e re-transmisses. ....................................................... 85
Script completo com todos os recursos acima. .................................................................... 85
Melhorando a segurana ...................................................................................................... 89
Aliases .................................................................................................................................. 89
Sumario ................................................................................................................................ 89
Portal de usurios com serMyAdmin ................................................................................... 91
SerMyAdmin........................................................................................................................ 91

vi
Instalando o SerMyAdmin ................................................................................................... 92
Tarefas bsicas ..................................................................................................................... 97
Gerenciamento de domnios .......................................................................................... 101
Customizao de interface ............................................................................................. 101
Sumrio .............................................................................................................................. 102
Conectividade com a rede pblica ...................................................................................... 103
Onde estamos? ................................................................................................................... 104
Mensagens enviadas para o gateway ................................................................................. 104
Mensagens vindas do gateway ........................................................................................... 106
Script de configurao ....................................................................................................... 108
Dissecando o arquivo openser.cfg ..................................................................................... 113
Usando Asterisk como um gateway................................................................................... 115
Using LCR (least cost routes) ............................................................................................ 118
O mdulo LCR ............................................................................................................... 118
Plano de discagem para o OpenSER .............................................................................. 119
A tabela LCR ................................................................................................................. 119
A tabela de gateways ..................................................................................................... 120
A tabela grupo de gateways ........................................................................................... 120
Gerenciando rotas e gateways ........................................................................................ 120
Comandos openserctl relacionados .................................................................................... 120
LAB Usando o recurso de LCR ...................................................................................... 122
Sumrio .............................................................................................................................. 128
Encaminhamento de chamadas .......................................................................................... 129
Verificando seu progressso? .............................................................................................. 129
Encaminhamento de Chamadas ......................................................................................... 130
Pseudo-variveis ................................................................................................................ 131
Tabela de pseudo-variveis do OpenSER verso 1.1 .................................................... 131
Viso geral dos pares atributo:valor (AVPairs) ................................................................. 133
Carga e parametrizao do avpops. ............................................................................... 135
Implementando siga-me incondicional .............................................................................. 135
LAB Implantando o recurso de siga-me ..................................................................... 136
Implementando siga-me (ocupado, no atende) ................................................................ 137
Dissecando o arquivo de configurao .............................................................................. 145
Lab - Testando o encaminhamento de chamadas. ............................................................. 146
Sumrio .............................................................................................................................. 147

vii
Tcnicas de travessia de NAT ............................................................................................. 148
Onde estamos? ................................................................................................................... 149
Tipos de NAT .................................................................................................................... 149
Full Cone (Cone Completo) ........................................................................................... 149
Restricted Cone (Cone Restrito) .................................................................................... 150
Port Restricted Cone (Cone restrito por porta) .............................................................. 150
Simtrico ........................................................................................................................ 151
Resumo dos tipos de Firewall ............................................................................................ 152
Formas de Resolver o problema do NAT .......................................................................... 152
Soluo para a sinalizao SIP (RFC3581) ....................................................................... 152
Resolvendo o problema de travessia dos pacotes RTP ...................................................... 153
Recebendo pedidos de registro atrs de NAT. ................................................................... 154
Determinando se o cliente est atrs de NAT. ............................................................... 154
Mensagem do tipo INVITE atrs de NAT ......................................................................... 155
Tratando as respostas ......................................................................................................... 157
Instalao e configurao do Media Proxy ........................................................................ 157
Instalao propriamente dita .......................................................................................... 157
Anlise do arquivo openser.cfg.......................................................................................... 161
Carga dos mdulos ......................................................................................................... 161
Parametrizao dos mdulos: ........................................................................................ 161
Tratamento das mensagens de REGISTER ................................................................... 162
Tratamento das mensagens de INVITE ......................................................................... 163
Tratamento das mensagens de BYE e CANCEL ........................................................... 163
Tratamento dos RE-INVITES........................................................................................ 164
Tratamento de mensagens para fora do nosso domnio ................................................. 165
Tratamento das respostas (on_reply_route). .................................................................. 165
Roteamento ........................................................................................................................ 166
Representao grfica do script ......................................................................................... 175
Seqncia dos pacotes.................................................................................................... 175
LAB Usando o mediaproxy para travessia de NAT. ...................................................... 181
Usando STUN .................................................................................................................... 182
Porque o STUN no funciona com NAT simtrico? ..................................................... 184
ALG Application Layer Gateways ................................................................................. 184
ICE (Interactive Connection Establishment) ..................................................................... 184
Sumrio .............................................................................................................................. 184

viii
Bilhetagem usando Radius e CDRTool .............................................................................. 186
Onde estamos? ................................................................................................................... 186
Como feita a contabilizao ............................................................................................ 187
Configurando e Instalando a Bilhetagem ........................................................................... 188
LAB Implementando a contabilizao com MySQL...................................................... 188
Dissecando o arquivo openser.cfg ..................................................................................... 194
Contabilizao usando um servidor Radius ....................................................................... 195
Instalao do FreeRadius. .................................................................................................. 196
Instalao dos pacotes .................................................................................................... 196
Crie e configure a base de dados do Freeradius ............................................................. 196
Configurao do Freeradius server .................................................................................... 197
Configure o client do Radius (radiusclient-ng) .................................................................. 198
Configure o OpenSER ....................................................................................................... 199
Teste a configurao fazendo uma ligao .................................................................... 199
Timestamp = 1142177368 ...................................................................................... 201
Tarifao com o CDRTool................................................................................................. 201
LAB. Instalao do CDRtool ............................................................................................. 201
LAB Usando o CDRTool............................................................................................ 206
Arquitetura do CDRTool ................................................................................................... 215
Como o CDRTool tarifa uma chamada ............................................................................. 215
Lab. Criando e aplicando um plano de tarifao ............................................................... 217
Sumrio .............................................................................................................................. 219
Objetivos ............................................................................................................................ 220
Onde estamos? ................................................................................................................... 220
Ferramentas prprias do OpenSER .................................................................................... 221
Ferramentas de trace e captura de pacotes ......................................................................... 222
Tshark e Wireshark ........................................................................................................ 222
O mdulo SIPTRACE.................................................................................................... 226
Ferramentas para testes de Stress ....................................................................................... 226
Sipsak ............................................................................................................................. 226
SIPp ................................................................................................................................ 227
Teste de stress da sinalizao SIP .................................................................................. 227
Teste de stress da sinalizao RTP ................................................................................ 229
Testando o MediaProxy ................................................................................................. 230
Ferramentas de monitoramento.......................................................................................... 230

ix
Sumrio .............................................................................................................................. 231
Expresses regulares ............................................................................................................ 232
Viso geral das expresses regulares. ............................................................................ 232
Cdigo de Status das Mensagens ........................................................................................ 235
Tabela de Cdigos de Mensagem ...................................................................................... 235
Definies usadas no SIP ..................................................................................................... 238

x
1
Introduo ao SIP

O SIP hoje um dos protocolos mais usados em voz sobre IP. Conhecer um pouco
sobre o este protocolo essencial no entendimento de um sistema de telefonia IP.
O protocolo SIP, Session Initiation Protocol est descrito principalmente em duas
RFCs Request for Comments, RC2543 e RFC3261 que tambm conhecida como
SIP verso 2. O SIP um protocolo da camada de aplicao usado para estabelecer,
modificar e terminar sesses ou chamadas multimdia. Essas sesses podem ser
conferncias, e-learning, telefonia pela Internet e aplicaes similares.
Ele um protocolo baseado em texto, similar ao HTTP e SMTP, desenhado para
iniciar, manter e terminar sesses de comunicao interativa entre usurios. Tais
sesses incluem: voz, vdeo, chat, jogos interativos e realidade virtual. Ele foi
definido pela IETF e vem se tornando o padro de fato em telefonia IP.

Objetivos deste captulo


Ao final deste captulo voc estar apto :
Descrever o que , e para o que serve o SIP
Descrever a arquitetura e seus principais componentes
Comparar os processos SIP que acontecem na sua rede com processos padro
Descrever os principais campos cabealho
O SIP suporta cinco aspectos do estabelecimento e trmino de sesses multimdia.
Localizao dos usurios: Determina o sistema final a ser usado para a
comunicao
Recursos disponveis para o usurio: Determina a mdia e os
parmetros da mdia a serem usados
Disponibilidade do usurio: Determina se o usurio est disponvel
para aceitar uma sesso
Estabelecimento da chamada: Estabelecimento dos parmetros de
chamados de ambos quem chamou e de quem foi chamado, alm de
progresso da chamada como tocando, ringing
Gerenciamento da chamada: Transferncia e trmino das chamadas.
O SIP foi projetado com parte de arquitetura de dados e controle multimdia, tais
como, os protocolos RSVP, RTP, RTSP, SDP, SAP, entretanto no depende de
nenhum deles para o seu funcionamento.
Teoria bsica de operao do SIP
O SIP muito semelhante ao HTTP na sua forma de funcionamento. O endereo SIP
como um endereo de e-mail. Um recurso interessante usado nos servidores SIP
Proxy o recurso de alias, de forma que voc pode ter ao mesmo tempo diversos
endereos SIP.
johndoe@sipA.com
+554845678901@sipA.com
45678901@sipA.com

Exemplo de uma mensagem SIP


INVITE sip:usuarioB@sipB.com.br SIP/2.0
Via: SIP/2.0/UDP lua.sipA.com.br;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: usuarioB <sip:usuarioB@sipB.com.br>
From: usuarioA <sip:usuarioA@sipA.com.br>;tag=1234567890
Call-ID: a84b4c76e66710@lua.sipA.com.br
CSeq: 314159 INVITE
Contact: <sip:usuarioB@lua.sipB.com.br>
Content-Type: application/sdp
Content-Length: 142
(SDP do usurio A no mostrado)

SIP URIs
Os endereos SIP so conhecidos como SIP URI (Indicador de recursos uniforme). A
URI um tipo geral de endereo usado na Internet. Ele contm informaes sobre o
servidor e o recurso a ser contatado. O esquema da URI contm o protocolo a ser
usado.
Exemplos de esquema da URI:
sips:johndoe@sipA.com
sip:johndoe@sipA.com

Voc pode tambm incluir parmetros de usurio junto com a URI tal como mostrado
abaixo:
sip:johndoe@sipA.com;user=John Doe

a parte domnio da URI pode ser resolvida por um servidor DNS. Os lookups de DNS
podem ser usados para determinar:
Os protocolos de transporte usando registros do tip NAPTR.
The IP address of the server using SRV or A records
The transport protocol to be used to reach the SIP server (UDP, TCP, SCTP or
TLS).
muito importante configurar corretamente os registros de nome de domnio antes de
implantar um SIP Proxy.

1 | Introduo ao SIP 2
O trapezide SIP
Na arquitetura SIP, ns usamos agentes usurio e servidores. O SIP usa um modelo
distribudo ponto-a-ponto usando um servidor de sinalizao. O servidor gerencia
apenas a sinalizao, enquanto os agentes usurio e os agentes servidores manuseiam
a sinalizao e a mdia (audio, vdeo, etc...). Veja figura abaixo:

No modelo SIP, um agente usurio, normalmente um telefone SIP, ir iniciar a


comunicao com seu SIP Proxy, visto aqui como Proxy de sada, para enviar uma
mensagem conhecida como INVITE (convite).
O Proxy de sada ir ver se a chamada direcionada para um domnio externo. Ele ir
pesquisar o DNS para determinar o domnio alvo e resolver o endereo IP. Ento ele
ir encaminhar a chamada para o SIP Proxy responsvel pelo domnio B.
O Proxy de entrada ir verificar na sua tabela de localizao pelo endereo IP do
agentB se este endereo tiver sido inserido na tabela de localizao de usurios
(normalmente em memria) por um processo prvio de registro. Se o Proxy de
entrada puder localizar o endereo, ele ir encaminhar a chamada o agentB.
Aps receber o pedido SIP, o agentB ter todas as informaes necessrias para
estabelecer uma sesso RTP (normalmente uma ligao com udio) com o agentA.
Uma mensagem de BYE termina a sesso.

3 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Normalmente os provedores VoIP no implementam um trapezide puro. Eles no
permitem que voc envie chamados para domnios externos, porque isto afeta a
receita. Eles implantam uma estrutura que mais parece um triangulo SIP.

Componentes de uma rede SIP


O SIP um protocolo de sinalizao de voz sobre IP que possui os seguintes
componentes:

UAC (user agent client) cliente ou terminal que inicia a sinalizao


SIP.

1 | Introduo ao SIP 4
UAS (user agent server) servidor que responde a sinalizao SIP de
um UAC.
UA (user agent) terminal de rede SIP (telefones SIP, ou gateway para
outras redes), contm UAC e UAS.
Servidor Proxy Recebe pedidos de conexo de um UA e transfere-o
para outro servidor Proxy se a estao em particular no est em sua
administrao.
Servidor de Redirecionamento Recebe pedidos de conexo e envia-
os de volta ao emissor incluindo os dados de destino ao invs de envi-
los diretamente parte chamada.
Servidor de localizao recebe pedidos de registro de um UA e
atualiza a base de dados de terminais com eles.
Todas as sees do servidor (Proxy, Redirect e Location) esto tipicamente
disponveis em uma nica mquina fsica chamada Proxy Server, que responsvel
pela manuteno da base de dados de clientes, estabelecimento de conexes,
manuteno e trmino e redirecionamento de chamadas.

Processo de Registro do SIP

O protocolo SIP emprega um componente chamado Registrar que um servidor


que aceita pedidos REGISTER e coloca a informao que ele recebe nestes pedidos
no servidor de localizao para o domnio que ele gerncia. O SIP oferece a
capacidade de descobrimento. Se um usurio inicia uma sesso com outro usurio, o
SIP deve descobrir o host atual onde o usurio pode ser alcanado. Este processo de
descobrimento feito pelo Location Server, que recebe o pedido, determina para onde

5 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
mand-lo baseado no conhecimento da localizao de cada usurio. Isto se baseia
numa tabela de localizao por domnio.
Antes que um telefone possa receber chamadas, ele precisa se registrar em uma base
de localizao. neste local que o nome ser associado ao endereo IP onde o
telefone se encontra. No nosso caso usamos como nome o ramal 8500. Poderia ser
tambm um endereo no formato sip:flavio@sermyadmin.org.

Operao do SIP em modo Proxy.

Operao em modo de redirect.

Mensagens Bsicas
As mensagens bsicas enviadas em um ambiente SIP so:

1 | Introduo ao SIP 6
As respostas para as mensagens do protocolo SIP so criadas em formato texto como
no protocolo HTTP. Aqui esto as respostas mais importantes.

Fluxo de um dilogo SIP


Esta seo introduz as operaes bsicas do SIP usando um exemplo simples. Vamos
examinar a seqncia de mensagens entre dois agentes-usurio mostrados abaixo.

7 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
As mensagens esto rotuladas na seqncia. Neste exemplo o usurio A usa um
telefone IP para se comunicar com outro telefone IP pela Internet. Para poder
completar esta ligao so usados dois SIP Proxies. O usurio A chama o usurio B
usando sua identidade SIP tambm conhecida como SIP URI. A URI semelhante a
um endereo de e-mail como sip:usuarioA@sip.com.br. O SIP tambm pode usar uma
URI segura como sips:usuarioA@sip.com.br. Uma chamada feita para um URI SIPS
garante um transporte de mensagens seguro (TLS) entre o originador e o destino
chamado.
A transao comea com o telefone do usurio A enviando um INVITE (Convite)
endereado ao usurio B. O pedido de INVITE (Convite) contm um nmero de
campos de cabealho. Campos de cabealho so atributos nomeados que provm
informaes adicionais sobre a mensagem, eles incluem um identificador nico, o
destino e informaes sobre a sesso.

1 | Introduo ao SIP 8
A primeira linha da mensagem contm o nome do mtodo. As linhas que seguem
fazem parte da lista dos campos cabealho. Este exemplo contm o conjunto mnimo
necessrio. Estes campos so rapidamente descritos abaixo:
VIA contm o endereo para o qual o usurioA est esperando receber respostas a
este pedido. Ele tambm contm um parmetro branch que identifica esta transao.
TO contm um nome (display name) e um SIP ou SIPS URI
(sip:usuarioB@sip.com.br) para o qual o pedido foi originalmente direcionado.
FROM tambm contm um nome (display name) e SIP ou SIPS URI
(sip:usuarioA@sip.com.br) que indica o originador da chamada. Este campo
cabealho tem um parmetro etiqueta (tag) contendo uma string aleatria
(1234567890) que foi adicionada ao URI pelo telefone IP ele usado para propsitos
de identificao.
CALL-ID contm um identificador globalmente nico para esta chamada, gerado
pela combinao de uma string aleatria e o nome do host ou endereo IP do telefone
IP. A combinao da etiqueta TO, FROM e CALL-ID definem completamente uma
relao SIP fim-a-fim (peer-to-peer) tambm conhecida como dilogo.
CSEQ ou seqncia de comandos contm um inteiro e um nome de mtodo. O
nmero CSEQ incrementado para cada novo pedido dentro de um dilogo e um
nmero de seqncia tradicional.
CONTACT contm um URI SIP ou SIPS que representa uma rota direta para
contatar o usuarioA, usualmente composta de um nome de usurio em um domnio
totalmente qualificado (FQDN). Como nem sempre alguns sistemas tm um domnio
registrado, endereos IP so permitidos. Enquanto o campo VIA diz aos outros
elementos para onde enviar uma resposta, o campo CONTACT diz aos outros
elementos para onde enviar requisies futuras.

9 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
MAX-FORWARDS serve para limitar o nmero de saltos que um pedido pode dar
no caminho ao seu destino. Ele consiste de um inteiro que decrementado por um
cada salto.
CONTENT-TYPE contm uma descrio do corpo da mensagem.
CONTENT-LENGTH contm uma contagem de bytes do corpo da mensagem.
Os detalhes de uma sesso, tal como o tipo de mdia, codec no so descritos usando o
SIP. Ao invs disso o corpo de uma mensagem SIP contm uma descrio da sesso,
codificado em outro formato de protocolo. Um destes formatos o SDP (Session
Description Protocol RFC 2327). Esta mensagem SDP carregada pela mensagem
SIP de forma anloga a um anexo de e-mail.
A seqncia da figura fica como acima:
(1) Como o telefone no conhece a localizao do usuarioB ou servidor SIP
do domnio sipB.com.br ele envia o INVITE para o servidor SIP que serve
ao domnio sipA, este endereo configurado no telefone do usuarioA, ou
pode ser descoberto via DHCP. O servidor sipA.com.br conhecido como
proxy.
(2) Neste exemplo o proxy recebe o pedido de INVITE e envia uma
mensagem 100 (Trying) de volta ao usuarioA indicando que o proxy
recebeu o INVITE e est trabalhando em encaminhar o pedido. As
respostas SIP usam um cdigo de trs dgitos seguidos por uma frase
descritiva. Esta resposta contm o mesmo To, From, Call-ID, CSeq e o
parmetro branch no campo Via como o INVITE, o que permite que o
telefone do usuarioA correlacione sua resposta para o INVITE enviado.
(3) O proxyA localiza o proxyB fazendo uma consulta especfica ao servidor
DNS para encontrar o servidor SIP que serve ao domnio B e encaminhar o
INVITE. Antes de encaminhar o pedido o ProxyA adiciona um campo Via
adicional que contm seu prprio endereo (O INVITE j contm o
endereo de A no primeiro campo Via).
(4) O proxy B recebe o INVITE e responde com um 100 (Trying) tentando
de volta ao proxy A indicando que ele est processando o pedido.
(5) O servidor Proxy consulta a base de dados, conhecida como servio de
localizao, que contm o endereo do usurioB. O proxyB adiciona um
outro campo Via com seu prprio endereo para o INVITE e encaminha
para o usurio B.
(6) O telefone do usurio B recebe o INVITE e alerta o usurio para a
chamada vinda do usurio A e o telefone desta forma toca. O telefone
indica isto com uma resposta 180 (ringing) tocando.
(7) que roteada de volta atravs dos dois proxys na direo inversa. Cada
proxy usa o campo Via para determinar para onde enviar a resposta e
remove seu prprio endereo do topo. Como resultado, embora o DNS e a
consulta ao servio de localizao sejam necessrios para rotear o INVITE
inicial, a resposta 180 (ringing) pode retornar ao originador sem lookups e
sem que seu estado seja mantido por cada proxy. Isto tambm faz com que
cada proxy que recebeu o INVITE veja todas as respostas do INVITE.

1 | Introduo ao SIP 10
(8) Quando o usurio A recebe o 180 (ringing), ele passa esta informao ao
telefoneA que vai soar o udio de tocando (ringback) e/ou mostrar a
mensagem na tela do usuarioA.
(9) Neste exemplo, o usurioB decide atender a chamada. Quando ele pega o
handset, este telefone SIP envia uma resposta 200(OK) para indicar que a
chamada foi respondida. O 200(OK) contm no corpo da mensagem com a
descrio da sesso usando o protocolo SDP. Como resultado, existe uma
troca em duas fases das mensagens SDP de A para B e de B para A. Este
recurso do SDP possui uma capacidade bsica de negociao dos recursos
em um modelo simples de oferta/resposta. Se o usurioB no quiser
responder a chamada ou estiver ocupado, um erro ser enviado ao invs do
200(OK). A mensagem 200(OK) algo como aparece abaixo:

A primeira linha de resposta contm o cdigo de resposta e a frase da razo (OK). As


linhas restantes contm campos cabealhos. Os campos Via, To, From, Call-ID, e
CSeq so copiados do pedido de INVITE. Existem trs campos Via, um adicionado
pelo telefoneA, outro pelo ProxyA e o ltimo pelo proxyB. O telefone SIP de Bob
adicionou em parmetro tag (etiqueta) em ambos os pontos finais dentro do dilogo e
sero includos em todos os pedidos futuros e respostas nesta chamada.
O campo Contact contm uma URI com a qual o usuarioB pode ser contatado
diretamente no seu telefone IP. Os campos Content-Type e Content-Length se referem
ao corpo da mensagem (no mostrado) que contm a informao da sesso SDP
(mdia). Alm do DNS e do servio de localizao mostrados no exemplo, os
servidores proxy podem decidir para onde enviar o pedido. Por exemplo, se o telefone
SIP do usurioB retornar um 486 (Busy here) Ocupado, o proxyB poderia fazer um
INVITE ao servidor de correio de voz do usurio B. Um servidor proxy pode tambm
enviar um INVITE para vrios locais ao mesmo tempo. Este tipo de busca paralela
conhecida como forking.

11 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
(10) Neste caso, o 200(OK) enviado de volta roteado de volta pelos dois
proxies e recebido pelo usurioA que ento para o tom de retorno e indica
que a chamada foi respondida.
(11) Finalmente o usurioA envia uma mensagem de ACK, para o telefone do
usurioB para confirmar o recebimento da resposta final 200 (OK). Neste
exemplo o ACK enviado diretamente do telefoneA para o telefoneB
evitando os dois proxies. Isto ocorre porque os pontos finais aprenderam
os endereos uns dos outros a partir dos campos Contact durante o
processo de INVITE/200(OK). Isto completa o ciclo INVITE/200/ACK
tambm conhecido como SIP three-way-handshake usado para
estabelecer sesses SIP.
(12) Neste momento a sesso entre os usurios comea e eles esto enviam
pacotes de media de um para o outro usando formato que eles
estabeleceram usando o SDP. Em geral os pacotes fim-a-fim tm um
caminho diferente das mensagens de sinalizao.Durante a sesso, os
usurios A e B podem decidir mudar as caractersticas de uma sesso. Isto
feito enviando um novo convite (re-INVITE) contendo uma nova
descrio de mdia. Este re-INVITE referencia um dilogo existente de
forma que a outra parte sabe que ela vai modificar uma sesso existente ao
invs de iniciar uma nova sesso. O outro lado envia um 200(OK) com um
ACK. Se o outro lado aceitar a mudana ele vai enviar um 200(OK) , o
originador responde ao 200(OK) com um ACK. Se o outro lado no
aceitar, ele vai enviar uma resposta tal como 488 (no aceitvel aqui), que
tambm recebe um ACK. Entretanto a falha no re-INVITE no causa a
falha da sesso existente.
(13) No final da sesso, o usurio B desconecta (hang up) e gera a mensagem
de BYE. Este BYE encaminhado diretamente para o softfone do
usuarioA contornando os proxies.
(14) O usurio A confirma a recepo do BYE com uma resposta 200 (OK) que
termina a sesso e a transao BYE. Nenhum ACK enviado. Um ACK
s enviado como resposta a um pedido de INVITE.
Em alguns casos pode ser til para os Proxies ficar no caminho da sinalizao para
ver todas as mensagens entre os pontos finais pela durao da sesso. Por exemplo, se
o servidor proxy B deseja permanecer no caminho da mensagem alm do INVITE
inicial, ele deve adicionar ao INVITE o campo conhecido como Record-Route que
contm a URI do proxy. Esta informao ser recebida pelo softfone do usurio B e
(devido ao campo Record-Route ser passada de volta na mensagem 200 (OK) para
o softfone do usurio A e armazenado pela durao do dilogo. Cada Proxy pode de
forma independente decidir receber mensagens subseqentes, e estas mensagens iro
passar atravs dos proxies que elegerem receb-las. Esta capacidade frequentemente
usada para proxies que esto provendo recursos usados no meio de uma chamada.
O registro uma forma que o Proxy B pode usar para aprender a localizao atual do
usurio B. Na inicializao e em intervalos regulares, o softfone B envia mensagens
do tipo REGISTER para o servidor no domnio B conhecido como SIP
REGISTRAR. As mensagens de registro associam o endereo SIP do usurio B
(usuarioB@sipB.com.br) com a mquina na qual ele est logado (Que vem como uma
URI SIP ou SIPS no campo Contact). O servidor registrar escreve esta associao,
1 | Introduo ao SIP 12
tambm chamada de binding, para um banco de dados, chamado location service
onde ela pode ser usada pelo servidor Proxy no domnio sipB. Normalmente o
servidor de registro fica junto com o proxy. O usurio pode se registrar de mais de um
local e o servidor pode fazer vrios tipos de busca para localizar o usurio B. De
forma similar, mais de um usurio pode ser registrado em um nico dispositivo ao
mesmo tempo.
Finalmente, importante notar que no SIP o processo de registro usado para rotear
as chamadas SIP e no tem papel na autorizao dos pedidos de ligao. Autenticao
e autorizao so gerenciadas pelo SIP em uma base pedido a pedido com um
mecanismo de desafio/resposta, ou usando um esquema de nvel mais baixo como
checagem de endereo IP.

Transaes e dilogos no SIP

Transactions and Dialogs

INVITE(1)
INVITE(3)
100 Trying (2)
INVITE(5)
100 Trying (4)
180 Ringing (6)
Transaction
180 Ringing (7)
180 Ringing (8) 200 OK (9)
200 OK (10)
200 OK (10)
Dialog
ACK (11)

Media Session RTP(12)

Transaction
BYE (13)

200 OK (14)

importante entender a diferena entre uma transao e um dilogo. Uma transao


ocorre entre um UAC e um UAS e compreende todas as mensagens do primeiro
pedido at a resposta final. As respostas podem ser provisrias iniciando com 1
seguido por dois dgitos (ex: 180 Ringing) ou final, iniciando com 2seguido por
dois dgitos (ex: 200 Ok).
O escopo de uma transao definido pela pilha de cabealhos VIA das mensagens
SIP. De forma que UAs, aps o convite inicial no necessitam se valer do DNS ou das
tabelas de localizao para encaminhar as mensagens.
Um dilogo normalmente se inicia com uma transao do tipo INVITE e termina com
uma transao do tipo BYE. Um dilogo pode ser identificado pelo cabealho CALL-
ID. A combinao Call-ID, junto com TO tag e FROM tag define um dilogo.

13 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
De acordo com a RFC3665, existem 11 fluxos de estabelecimento de sesso. A lista
no exatamente complete, mas cobre as melhores prticas nesta questo. Os
primeiros dois tipos de estabelecimento de sesso foram cobertos neste captulo.
Estabelecimento de sesso com sucessoe Estabelecimento de sesso com sucesso
atreves de dois proxies. Alguns destes fluxos sero vistos mais a frente, tais como
No atendido e Ocupado.

O protocolo RTP
O protocolo RTP responsvel pelo transporte de dados como udio e vdeo. Ele foi
padronizado pela RFC3550. Ele usa UDP como um protocolo de transporte. Para ser
transportado, o udio e vdeo tem de ser empacotados por um codec. Basicamente o
protocolo permite a especificao da temporizao e do contedo da transmisso da
mdia.
O RTP tem um protocolo auxiliar chamado RTCP (Real Time Control Protocol)
usado para monitorar os pacotes de RTP. Ele pode medir o delay e o jitter.

Codecs
O contedo descrito no protocolo RTP normalmente codificado por um Codec.
Cada codec tem um uso especfico. Alguns tem compresso enquanto outros no. O
Codec G.711 que no usa compresso o mais comum. Usando 64 Kbps de banda
para um nico canal, ele normalmente precisa de uma rede de alta velocidade,
normalmente encontrada em redes locais. Entretanto em redes de longa distncia,
64Kbps muito oneroso. Codecs como o G.729 e o GSM podem compactar os
pacotes de voz em at 8 vezes e permitir um melhor uso da banda disponvel. Alguns
codecs como o iLBC podem sustentar uma boa qualidade de voz mesmo com 7% de
perda de pacotes. A correta escolha do codec de voz fundamental na operao de um
provedor VoIP

DTMF-Relay
Algumas vezes os usurios vo precisar usar o teclado do telefone para operar
sistemas automticos como, por exemplo, tele-banco e correio de voz. Para que esta
operao se d sem problemas, preciso que o DTMF (Dual Tone Multi Frequency)
seja repassado para a rede pblica corretamente. Quando usamos um Codec com
compresso como o g.729, os tons enviados pelos dgitos do telefone passam
distorcidos e podem ser interpretados de forma incorreta ou simplesmente ignorados.
Para resolver isso precisamos de um mtodo especial para a passagem do DTMF. Em
alguns casos o protocolo RTP usado para levar informaes de sinalizao como o
DTMF. A RFC2833 especifica os mtodos para transmitir O DTMF na forma de
eventos nomeados. importante que voc use o mesmo mtodo para servidores e
clientes.

Real Time Control Protocol - RTCP


O RTCP pode prover um feedback sobre a qualidade da recepo. Ele fornece
controle fora de banda de informaes como o RTT (Round Trip Time, Latncia e
perda de pacotes. normalmente usado para gerar relatrios da qualidade da ligao.
1 | Introduo ao SIP 14
Session Description Protocol - SDP
O protocolo SDP descrito na RFC4566. Ele usado para negociar parmetros de
sesso entre os UAs. Detalhes como endereos IP e portas para comunicao do RTP
e informaes relacionadas aos codecs e dtmf-relay so trocadas no SDP. O SDP
funciona no modelo Oferta/Resposta. Normalmente a mensagem de INVITE contm a
oferta e a mensagem 200 Ok contem a resposta. No exemplo abaixo voc pode
notar que o codec GSM foi oferecido, mas o outro fone no o suportava, por isto esta
conexo acabou sendo fechada com o codec G.711 suportado por ambos. A sesso
rtpmap:101 referente ao dtmf-relay descrito na RFC2833.

INVITE (SDP Offer)

200 Ok (SDP Answer)

15 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
O Protocolo SIP e o modelo OSI.
sempre importante entender os protocolos de voz a luz do modelo OSI e com isto
situar mais claramente a funo de cada protocolo.

Application SER/OpenSER

Presentation G.729/G711/GSM/Speex

Session H323/SIP/MGCP/IAX

Transport UDP/RTP/SRTP/RTCP

Network IP

Datalink Frame-Relay/ATM/PPP/Ethernet

Physical Ethernet/V.35/RS-232/xDSL

Viso geral de um provedor VoIP

The SIP provider MySQL/Postgres/


Big Picture Unixodbc Database

Ethernet

Media
User Radius
SIP PSTN Media Proxy CDRTool Monitoring
Portal Server Tools
Proxy Gateway Server Nat Rating
Provis. Traversal Acct.

Ethernet

CPE device (router)


Usually xDSL or
Cable
Internet Firewall
Customer Customer
Using an ATA Firewall
or Softphone

Antes de comear a se aprofundar no SIP Proxy importante entender todos os


componentes envolvidos na soluo. Um provedor VoIP normalmente consiste de
vrios servidores e servios. Os servios descritos aqui poderiam ser instalados em
um nico servidor ou em mltiplos servidores dependendo do dimensionamento.

1 | Introduo ao SIP 16
Neste material, ns iremos cobrir cada um dos componentes nos captulos a frente.
Vamos usar esta figura em todos os captulos para poder situ-lo.

Sip Proxy
O SIP Proxy o componente central de nossa soluo. Ele responsvel pelo registro
dos usurios e por manter a base de dados de localizao (mapeado endereos SIP
(uri) para endereos IP). Toda a sinalizao e o encaminhamento so gerenciados
pelo SIP Proxy. O SIP Proxy nunca gerencia a media (udio ou vdeo em RTP).
Todos os pacotes RTP so enviados diretamente entre os usurios e os gateways.

Portal Web para administrao dos usurios


Um componente importante o portal de provisionamento e administrao. O usurio
tem de se inscrever no servio, ele deveria ser capaz de comprar crditos, mudar
senhas, verificar sua conta a assim por diante. Por outro lado, os administradores
precisam remover usurios, dar e alterar privilgios, e adicionar crditos. O
provisionamento usado para tornar mais simples a configurao dos soft-fones pelos
usurios.

PSTN gateway
Para que haja comunicao com o servio pblico de telefonia so necessrios
gateways. Normalmente esta interface de gateway vai usar troncos E1 ou T1
dependendo do pas. Os produtos mais comuns para esta tarefa so os gateways da
Cisco, AudioCodes e Quintum. O Asterisk vem ganhando mercado nesta rea
tambm. Verifique o suporte dos gateway no somente a RFC3261, mas tambm as
RFCs 3515(REFER) e 3891(Replaces) e 3892(Referred By). Este protocolo permitem
a transferncia de chamadas com consulta. Sem eles pode ser impossvel transferir
chamadas.

Media Server
Um SIP Proxy nunca gerencia a mdia (RTP). Servios como URA, correio de voz,
conferncia ou quaisquer outros relacionados ao uso da mdia, necessitam deste
componente. Os dois componentes mais populares para Media Server so o Asterisk e
o SEMS desenvolvido pela IPTEL. O SEMS tem recursos interessantes como correio
de voz, conferncia e anncios.

Media Proxy or RTP Proxy for Nat Traversal


Qualquer provedor SIP ter de gerenciar a travessia de NAT para seus clientes. O
Media Proxy uma ponte que ajuda os usurios atrs de um NAT simtrico a acessar
o provedor. Sem ele no possvel atender cerca de 30% dos usurios. Voc pode
implantar tcnicas universais de travessia de NAT usando estes componentes. O
Media Proxy pode ainda ser usado no auxlio da bilhetagem evitando que pacotes de
INVITE sem um BYE deixem de ser contabilizados.

Contabilizao com um servidor Radius


Um servidor com o protocolo Radius instalado ser fundamental para a contabilizao
das chamadas. Um provedor SIP dever tomar o mximo cuidado com a

17 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
contabilizao dos registros. O OpenSER pode ser configurado para enviar os
registros de chamada para um servidor Radius tal como o Freeradius ou o Radiator.

Tarifao com CDRTool


O servidor Radius contem informaes sobre a durao da chamada, mas ele no tem
informaes sobre as tarifas e as regras de tarifao. Aplicar preos as chamadas
podem ser bem complicado. Ns vamos usar no captulo 10 uma ferramenta chamada
CDRTool desenvolvida pela AG-Projects (cdrtool.agprojects.com). Ela ser
responsvel por aplicar estas taxas s chamadas.

Ferramentas de monitoramento
Por fim, ns iremos precisar de ferramentas de monitoramento e testes para nos ajudar
a depurar quaisquer problemas ocorrendo no servidor SIP. A primeira destas
ferramentas o analisador de protocolo. Vamos ver tambm outras ferramentas como
o SIP Trace.

Onde voc pode encontrar mais informaes.


A melhor referncia para o protocolo SIP a RFC3261. Ler as RFCs sem dvida
entediante, mas voc pode encontr-las em www.ietf.org/rfc3261.

Um bom tutorial sobre SIP pode ser encontrado na Universidade de Columbia.


http://www.cs.columbia.edu/~coms6181/slides/11/sip_long.pdf.
No mesmo lugar voc pode encontrar vrias informaes
www.cs.comlumbia.eu/sip.
Outro bom tutorial pode ser encontrado no site da IPTEL.
.http://www.iptel.org/files/sip_tutorial.pdf
Existem tambm listas de e-mail sobre SIP chamada SIP Implementors.
https://lists.cs.columbia.edu/mailman/listinfo/sip-implementors
Este um portal excepcional a respeito da arquitetura do SIP.
http://www.tech-invite.com/

Sumrio
Neste captulo voc aprendeu o que o SIP seus principais componentes, SIP Proxy,
SIP Registrar, User Agent Client, User Agent Server, Gateway PSTN. Entendeu como
funciona a arquitetura SIP com seus SIP Proxies, entendeu o significado de uma URI
e seus Aliases. Alem disto foi possvel entender os principais tipos de mensagem SIP
e seu processamento.

1 | Introduo ao SIP 18
2
SIP Express Router

Ns discutimos no ultimo captulo a viso geral do provedor VoIP. Normalmente o


provedor VoIP composto de vrios componentes. Estes componentes residem na
mesma mquina ou so distribudos em diversos equipamentos dependendo do seu
dimensionamento. Um destes componentes o SIP Proxy. No nosso caso um servidor
baseado em OpenSER. Como o prprio nome implica, o que melhor descreve o SER
um roteador SIP. Ele permite a manipulao de cabealhos SIP e encaminha pacotes
em alta velocidade. Mdulos de terceiros do ao SER extrema flexibilidade para fazer
papeis para os quais ele no tinha sido pensado originalmente, tais como travessia de
NAT, IMS, balanceamento de carga e outras funcionalidades. Neste captulo, ns
iremos mostrar a voc algumas destas possibilidades e a arquitetura do SER.
Ao final deste captulo voc estar apto :
Explicar o que o SIP Express Router
Descrever seus cenrios de uso
Descrever os arquivos de configurao
Distinguir diferentes sees do arquivo openser.cfg

Onde ns estamos?
A soluo de um provedor VoIP possui muitos componentes. Para evitar perder a
perspectiva, ns iremos mostrar esta figura a cada captulo. Neste captulo, ns iremos
trabalhar com o componente chamado SIP Proxy.

The SIP provider MySQL/Postgres/


Big Picture Unixodbc Database

Ethernet

Media
User Radius
SIP PSTN Media Proxy CDRTool Monitoring
Portal Server Tools
Proxy Gateway Server Nat Rating
Provis. Traversal Acct.

Ethernet

CPE device (router)


Usually xDSL or
Cable
Internet Firewall
Customer Customer
Using an ATA Firewall
or Softphone
O que o SIP Express Router?
O SIP Express Router um servidor de voz sobre IP gratuito baseado no protocolo
SIP (Session Initiated Protocol, RFC3261) voltado a aplicaes de grande volume.

Funces do SIP proxy


Stateful proxy
Validar a requisio
Pr-processar informaes de roteamento
Determinar o alvo da requisio
Encaminhar a requisio para o alvo
Processar todas as respostas

Ele foi criado para atender infra-estruturas de voz sobre IP de larga escala. O servidor
mantm o registro dos usurios, configura as sesses VoIP, encaminha mensagens
instantneas e cria espao para novas aplicaes. Sua interoperabilidade comprovada
garante integrao simples com componentes de outros fornecedores. Isto elimina a
possibilidade de ficar travado em um nico fabricante.
O OpenSER tem um modelo flexvel de plug-in para novas aplicaes. Terceiros pode
facilmente ativar seus plug-ins com o cdigo do servidor e prover deste modo servios
avanados. Desta forma, plug-ins tais como contabilizao usando o protocolo
RADIUS, gateways de SMS, queries ENUM, ou agente de presena j foram
desenvolvidos e so fornecidos como recursos avanados. Outros mdulos esto a
caminho: controle de firewall, postgres, drivers de LDAP e mais.

Principais caractersticas

Velocidade
Baixo consumo de recursos
Escalabilidade
Portabilidade (Ansi C)
Interoperabilidade

Seu desempenho e robustez permitem a ele servir milhes de usurios e acomodar as


necessidades de grandes operadoras. O SIP Express Router extremamente
configurvel e permite a criao de vrias polticas de roteamento e admisso bem
como servios novos e personalizados. Sua configurao flexvel permite que ele
sirva a muitos papeis como barreira de segurana, servidor de aplicaes e proteo
um gateway com a rede pblica de telefonia.

2 | SIP Express Router 20


O SER mantido pela IPTEL (www.iptel.org) que saiu da companhia nacional de
pesquisa alem FHG Focus. O site de IPTEL uma fonte primria de informaes
sobre o SER.
O OpenSER uma ramificao do projeto SER (www.openser.org). Comeamos este
material usando o SER carregado da IPTEL, mas no meio do caminho decidimos
trocar para o OpenSER. O grupo de desenvolvimento do OpenSER se encontra mais
ativo e novas verses esto sendo lanadas. Muito da documentao do SER data de
2003 e no tem sido freqentemente atualizada depois que a empresa foi comprada
pela Tekelec.

Lista de recursos e cenrios de uso.


Baseado nos ltimos padres, o OpenSER inclui suporte para o servidor de registro,
de Proxy e de redirecionamento (Registrar, SIP Proxy e SIP Redirect Mode). Alm
disso, ele atua como um servidor de aplicaes com suporte para instant messaging
e presena incluindo 2G/SMS e Jabber Gateway, uma linguagem de polticas de
controle de chamadas, traduo de nmeros de chamada, planos de discagem
privados, ENUM e AAA. O OpenSER roda nas principais vertentes do Linux, Solaris
e suporta ambos o IP verso 6 e o IP verso 4. possvel manter mltiplos domnios e
ter a base de dados redundante.

Cenrios de uso
Nesta seo vamos ver os casos mais comuns de uso do SIP. Em todos estes cenrios,
o OpenSER pode ser instalado facilmente como um elemento aglutinador entre todos
os componentes SIP, sejam eles softfones, telefones IP, gateways PSTN e quaisquer
outros dispositivos compatveis com SIP.

Provedores de Internet de valor agregado


Alguns provedores para atrair clientes vo oferecer servios de valor agregado. Em
alguns casos VoIP poder ser uma opo. No Brasil, vrias empresas j oferecem
servios de VoIP com valores inferiores aos do mercado de telefonia convencional.
Outros servios so mensagens instantneas e comunicaes unificadas. O OpenSER
foi criado para atender redes de larga escala, pela sua capacidade de atender um
grande nmero de clientes.

Provedores de Telefonia IP
ITSPs (provedores de servio de telefonia na Internet) oferecem um servio de
interconectar usurios de telefonia usando um softfone rede pblica de telefonia.
Isto pode reduzir os custos em ligaes DDD, DDI e para celulares. O OpenSER pode
ser facilmente configurado para esta aplicao.

Telefonia IP em universidades e na Internet II


Diversas universidades vm usando o OpenSER como um SIP Proxy para telefonia IP
e mensagens instantneas. Podemos citar a universidade de Columbia e o MIT como
usurios destas estruturas que permitem a comunicao de um telefone SIP para outro

21 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
dentro e fora da instituio. Em outubro de 2005 esta rede chegou cerca de 200000
endereos conectados. Maiores informaes podem ser obtidas em:
http://www.internet2.edu/sip.edu/. Boa parte destes servidores usam o OpenSER.

Concentrador de telefonia para empresas do tipo .com e .gov


comum que rgos de governo regulem o uso de VoIP entre suas unidades. Um
projeto que tem se tornado comum o uso do OpenSER para controle de numerao e
centralizao da sinalizao SIP, liberando cada rgo para adquirir sua prpria
soluo (PBX) baseada em SIP RFC 3261 e integrando solues de diferentes
fabricantes. A capacidade de tratar os cabealhos das mensagens em baixo nvel torna
o OpenSER um excelente tradutor, capaz de interconectar sistemas antes
incompatveis.

2 | SIP Express Router 22


Arquitetura do OpenSER e o arquivo openser.cfg

openser.cfg configuration file


# ----------- global configuration parameters ------------------------
debug=3 # debug level (cmd line: -dddddddddd)
fork=yes Global
log_stderror=no # (cmd line: -E)
check_via=no # (cmd. line: -v)
Configuration
dns=no # (cmd. line: -r) Parameters
rev_dns=no # (cmd. line: -R)
port=5060
children=4
fifo="/tmp/openser_fifo"
# ------------------ module loading ----------------------------------
loadmodule "/usr/lib/openser/modules/sl.so"
loadmodule "/usr/lib/openser/modules/tm.so" Module loading
loadmodule "/usr/lib/openser/modules/rr.so"
loadmodule "/usr/lib/openser/modules/maxfwd.so"
loadmodule "/usr/lib/openser/modules/usrloc.so"
Module Specific Parameters
loadmodule "/usr/lib/openser/modules/registrar.so"
loadmodule "/usr/lib/openser/modules/textops.so"
# ----------------- setting module-specific parameters ---------------
modparam("usrloc", "db_mode", 0)
# ------------------------- request routing logic -------------------
route{
if (!uri==myself) {
route(1);
}; Main routing block
if (uri==myself) {
if (method=="REGISTER") {
save("location");
exit;
};
lookup("aliases");
if (!uri==myself) {
append_hf("P-hint: outbound alias\r\n");
route(1);
};
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
append_hf("P-hint: usrloc applied\r\n");
};
route(1);
} Routing blocks
route[1] {
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
exit;
Reply routing blocks
}
onreply_route[1] {
.... Failure routes blocks
failure_route[1] {
....

Ncleo e mdulos
O OpenSER construdo sobre um ncleo que responsvel pela funcionalidade
bsica e pelo manuseio das mensagens SIP. A maior parte da funcionalidade do
OpenSER executada a partir de seus mdulos. Estes mdulos expem sua
funcionalidade de forma que possam ser usados dentro do arquivo openser.cfg. O
arquivo de configurao openser.cfg controla que mdulos so carregados e permite
configurar parmetros que regulam o funcionamento dos mdulos. O openser.cfg o
principal arquivo de configurao do OpenSER.

23 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Sees do arquivo openser.cfg
O OpenSER tem sete sees:
Definies globais
o Esta poro contm o endereo IP e a porta no qual ele deve
ouvir e nvel de depurao. So opes do processo do
OpenSER.
Mdulos
o Contm a lista de bibliotecas externas que so necessrias para
expor funcionalidades que no esto disponveis no ncleo. Os
mdulos so carregados com o comando loadmodule.
Configurao dos mdulos
o Vrios mdulos possuem parmetros que precisam ser passados
adequadamente. Estes parmetros so configurados com o
comando modparam(nome do mdulo, parmetro do mdulo,
valor do parmetro).

Bloco de roteamento principal


o O bloco de roteamento principal onde comea o processamento
das mensagens SIP. Ele controla como cada mensagem recebida
processada.
Bloco de roteamento secundrio
o Alm do bloco principal, a seqncia de comandos pode ser
desviada usando o comando route. Os blocos secundrios so
como sub-rotinas.
Bloco de roteamento de respostas
o Blocos de resposta (Reply) so usados para processar os as
respostas, normalmente mensagens (200 OK).
Bloco de roteamento de falhas
o Blocos de roteamento de falhas so usados para processar
condies de falha como ocupado ou timeout.

Sesses, Dilogos e Transaes.


De maneira a entender o OpenSER, preciso entender trs conceitos do mundo SIP.
Transao SIP
o Uma mensagem SIP (e quaisquer re-envios) e sua resposta direta
(Exemplo o usurio envia um REGISTER ao OpenSER e recebe
uma mensagem 200 OK como resposta);
Dilogo SIP
o Uma relao entre duas entidades SIP que exista por algum
tempo (Exemplo, um dilogo estabelecido desde o INVITE
terminando com o BYE).

2 | SIP Express Router 24


Sesso
o Um fluxo de mdia (udio/vdeo) entre duas entidades SIP

Processamento de mensagens no openser.cfg


O openser.cfg um script que executado para cada mensagem SIP recebida. Por
exemplo, o usurio A quer falar com o usurio B e envia uma mensagem do tipo
INVITE. Esta mensagem processada no bloco de roteamento principal (route[]). O
processamento continua at encontrar um ponto onde o processamento encerrado
com um t_relay() (encaminhar), um sl_send_reply() (para enviar um erro) ou ainda
o descarte de uma mensagem chegando ao fim do bloco ou usando o comando
exit().

Comportamento esperado de um SIP Proxy


importante entender os processo bsicos esperados de um SIP Proxy segundo
RFC3261. Sem entender estes processos, fica difcil entender como configurar o
Proxy Server.
Cada SIP Proxy tomar decises de roteamento, modificando o pedido antes de
encaminh-lo para o prximo elemento. As respostas sero encaminhadas atravs do
mesmo conjunto de proxies atravessados pelo pedido na ordem inversa.
Um Proxy pode operar no modo stateless (sem manuteno de estado) ou stateful
com manuteno de estado. Quando o Proxy atua apenas como um simples
encaminhador dos pacotes. Ele encaminha os pacotes para um nico elemento
determinado apenas pelo pedido. Um proxy atuando como stateless descarta
quaisquer informaes sobre a mensagem uma vez que tenha sido encaminhada. Isto
limita o tratamento de falhas e bilhetagem por exemplo.
Quando o OpenSER sabe que mensagem OK pertence a cada INVITE, dizemos que
ele est operando no modo stateful isto significa na prtica que voc poder
gerenciar a resposta no bloco on_reply_route(). Com o processamento stateless (ou
simplesmente forwarding), cada mensagem no dilogo gerenciada sem contexto.
O encaminhamento sem estado usado para um processamento simples das
mensagens SIP como distribuio da carga.
Quando se quer implantar recursos mais sofisticados como contabilizao das
chamadas, siga-me se ocupado, correio de voz voc tem de usar o processamento
statefull. Cada transao ser mantida na memria de forma que quaisquer falhas,
respostas ou retransmisses sejam reconhecidas.
Uma confuso que ocorre com estes conceitos que o processamento statefull por
transao e no por dilogo SIP. Ento statefull o processamento do INVITE e da
sua resposta OK e no do INVITE at o BYE.

25 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Operao em modo stateful

SIP Request Processing (RFC3261)

Preprocess
Request Determine Forward Request Process All
Routing
Validation Reqeuests target to Target Responses
Information

Check Syntax If Record-Route Is it in the location Call t_relay() on_reply_route()


header present database?
URI Scheme Copy the received
Process it External Find appropriate
request
Max-forwards destination? Update r-uri context
(Loop detection) Update Timer C
Proxy-require Upd Max-forwards
Rem. topmost via
Proxy- New header fields Add the response
Authorization
to the context
Postprocess forward
routing immediately?
Next hop, Choose the best
address, port final response
Add via header
Add content-
length
Forward new
request
Set Timer C

Quando em modo stateful, um Proxy simplesmente um processador de transaes


SIP. Quando operando neste modo de acordo com a RFC so necessrios pelo menos
os seguintes processos:
Validar o pedido
Pr-processar as informaes de roteamento
Determinar o alvo do pedido
Encaminhar o pedido para cada alvo
Processar todas as respostas

Validao do pedido
Antes que um Proxy possa processar um pedido ele deve verificar a validade de
mensagem. As seguintes validaes so feitas:
Sintaxe razovel
Estrutura da URI (URI scheme)
Max-forwards
Loop Detection (opcional)
Proxy-Require
Proxy-Authorization

Pr-processamento das informaes de roteamento.


O proxy deve inspecionar a R-URI do pedido. Se a R-URI do pedido contiver um
valor que este proxy colocou previamente no campo ROUTE o proxy deve substituir a

2 | SIP Express Router 26


R-URI no pedido com o ltimo valor de campo ROUTE e remove-lo. O proxy ento
deve seguir em frente como se ele tivesse recebido este pedido modificado.
Isto s vai acontecer quando o elemento enviando o pedido para o Proxy (que pode
ser o ponto final) for um roteador estrito (strict router). Reescrever o campo no
recebimento necessrio para manter compatibilidade com estes elementos.

Determinando os alvos dos pedidos


Em seguida o Proxy calcula o alvo do pedido. O conjunto de alvos ir ser
predeterminado pelo contedo do pedido ou de um servio de localizao. Cada alvo
no conjunto representado como uma URI. Se o domnio da R-URI indica um
domnio que no responsabilidade deste Proxy, a R-URI deve ser colocada no alvo
como o nico alvo e o Proxy deve seguir para o encaminhamento.

Encaminhamento do pedido
Assim que o alvo estiver preenchido, um Proxy pode iniciar o encaminhamento. Ele
pode processar mltiplos alvos serialmente, onde cada transao de cliente
completada at que a prxima se inicie. Este processo pode ser paralelo tambm. Para
cada alvo, o Proxy encaminha o pedido seguindo os seguintes passos:
Faz uma cpia do pedido recebido
Atualiza a R-URI
Atualiza o Max-Forwards
Opcionalmente adiciona um campo Record-Route
Opcionalmente adiciona campos cabealho
Ps-processa informaes de roteamento
Determina o endereo do prximo salto, porta e transporte
Adiciona o valor do cabealho Via
Adicionar o cabealho Content-Length
Encaminha o novo pedido
Seta o temporizador C

Processamento da Resposta
Quando uma resposta recebida por um elemento, ele primeiro tenta localizar a
transao do cliente. Se nenhuma for encontrada, o elemento deve processar a
resposta, mesmo se uma resposta informacional como um Proxy stateless. Se uma
transao correspondente for encontrada a resposta enviada ao cliente. Todas as
transaes de clientes passam respostas camada do Proxy e os seguintes processos
devem ocorrer:
1. Encontrar o contexto da resposta apropriado.
2. Atualizar o temporizador C.
3. Remover o cabealho Via mais alto.

27 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
4. Adicionar a resposta ao contexto de resposta.
5. Verificar se a resposta deve ser encaminhada imediatamente.
6. Quando necessrio, escolher a melhor resposta final.
7. Agregar o campo Authorize se necessrio
8. Opcionalmente re-escrever o campo record-route
9. Encaminhar a resposta

Diferenas entre Strict Routing e Loose Routing


Loose e Strict routing so formas de roteamento de mensagens SIP. Loose Routing
uma das grandes mudanas da verso 2.0 na forma de roteamento. Usando Loose
Routing a R-URI nunca alterada e mantida compatibilidade com a verso anterior
prevista na RFC 2543 (strict-routing).
O problema com strict routing previsto na RFC2543 que era preciso especificar
um conjunto de proxies para o pedido inicial de um dilogo atravessar. O
processamento do roteamento inicial joga fora a informao na R-URI recebida. O
comportamento dos UAs com outbound-proxy padro era problemtico. O sistema
inteiro falhava se houvesse uma falha em um dos elementos.

STRICT ROUTING
(RFC2543)

B C

INVITE B INVITE C INVITE D


Route C,D Route D

A
D

A soluo loose routing a forma correta, ela mantm o alvo do pedido separado da
prxima rota. Permite a cada destino de roteamento determinar se ele foi alcanado,
possui um mecanismo para manter a compatibilidade com elementos do tipo strict
routing. O suporte de loose routing indicado atravs de um parmetro ;lr.

2 | SIP Express Router 28


LOOSE ROUNTING
(RFC3261)

B C

INVITE D INVITE D INVITE D


Route B,C Route C

A
D

Se o OpenSER deseja ficar no meio da conversao (para bilhetagem por exemplo)


ele deve inserir um campo cabealho de roteamento na mensagem SIP usando a
funo record_route(). Para que isto funcione o OpenSER precisa atuar no modo
loose routing para verificar se deve processar as mensagens com o cabealho
record_route(). O SIP pode incluir tambm informaes de como configurar a
sesso de udio ou vdeo atravs do protocolo SDP (Session Description Protocol).
Quando um servidor SIP recebe uma mensagem, ele pode decidir se quer ficar no
meio da chamada ou no. Se no quiser o OpenSER pode prover aos agente-usurio
a informao que eles precisam para se conectar um ao outro, depois as mensagens
SIP seguem diretamente de um agente para outro.

Entendendo SIP e RTP.


De maneira a entender as subsees seguintes, voc deve entender algumas coisas
sobre o SIP e RTP. Primeiro, SIP o protocolo de sinalizao que controla a chamada
convidando para a chamada, cancelando (desliga quando est tocando), desligando
aps o fim da chamada e assim por diante. O protocolo SIP inclui no pedido de
INVITE as informaes sobre a sesso usando o protocolo SDP.
A informao do SDP ir resultar em um ou mais fluxos de mdia, que so
configurados normalmente entre os dois agentes do tipo usurio. O OpenSER nunca
participa do fluxo de mdia RTP. Entretanto o OpenSER pode fazer com que uma
aplicao de terceiros como um B2BUA ou um Proxy RTP possam se tornar um
intermedirio (principalmente para fins de travessia do NAT).
O protocolo SDP funciona no modelo Oferta/Resposta. O SDp embutido nas
mensagens de INVITE e nas respostas do tipo 200 OK.
Abaixo o exemplo de uma captura do Ethereal.

29 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Sumrio
Neste captulo aprendemos que o OpenSER um software que faz a funo de SIP
Proxy. possvel identificar a estrutura bsica do arquivo de configurao
openser.cfg com suas sees, definies globais, carga dos mdulos, parametrizao
dos mdulos, bloco de roteamento principal, bloco de roteamento de respostas e bloco
de roteamento de falhas.

2 | SIP Express Router 30


3
Instalando o OpenSER

Agora que entendemos um pouco mais sobre o SER, vamos instal-lo para podermos
comear a explorar os seus recursos.
Ao final deste captulo voc estar apto :
Instalar o Linux de forma adequada ao OpenSER
Baixar, compilar e instalar o OpenSER
Executar o OpenSER na carga do Linux.
Conhecer algumas opes de execuo do OpenSER

Onde estamos?
Neste captulo, continuaremos a explorar os recursos do componente SIP Proxy.

The SIP provider MySQL/Postgres/


Big Picture Unixodbc Database

Ethernet

Media
User Radius
SIP PSTN Media Proxy CDRTool Monitoring
Portal Server Tools
Proxy Gateway Server Nat Rating
Provis. Traversal Acct.

Ethernet

CPE device (router)


Usually xDSL or
Cable
Internet Firewall
Customer Customer
Using an ATA Firewall
or Softphone

Necessidades de Hardware
OpenSER roda em algumas variedades de Linux e no Solaris da Sun Microsystems.
Alguns pacotes genricos compactados em tarballs para algumas variedades de
linux e solaris esto disponveis. Estes pacotes podem ser baixados do site
www.openser.org
Os programas gcc ou icc, bison ou yacc, flex, GNU make ou gmake, sed e tr so
necessrios para compilao. provvel que voc j os tenha em sua mquina. De
qualquer forma voc pode baix-los gratuitamente junto com sua distribuio de
Linux. Se voc quiser suporte ao MySQL, voc tambm vai precisar do libmysql e
libz. Mdulos opcionais podem requerer suporte de bibliotecas adicionais.
A IPTEL no especifica um hardware mnimo e o OpenSER ir rodar em um PC com
poucos recursos. Um dimensionamento apropriado para os horrios de pico precisa
ser determinado de forma emprica. A documentao cita que uma mquina bi-
processada agentaria um horrio de pico de uma regio como a baia de So
Francisco, CA, USA. Como regra geral, qualquer PC com uma placa de 100 Mbps
com recursos razoveis deve ser adequado, particularmente para testes. Isto vale
apenas para voz, na medida em que se adicionam facilidades, a carga pode crescer e
s possvel neste caso determinar o hardware de forma emprica.

Instalando o Linux para o OpenSER


A maior parte dos laboratrios deste material pode ser testada usando uma
combinao de dois telefones e um servidor para o OpenSER. Os laboratrios foram
testados na V.Office usando VMWare, com a mquina virtual rodando o OpenSER
verso 1.2 em um servidor com Debian Etch 4.0, um softfone no Windows da
mquina hospedeira e dois telefones ligados um ATA da Linksys. O CD do debian
pode ser baixado de: http://cdimage.debian.org/debian-cd/4.0_r3/i386/.

Cuidado: O CD usado neste laboratrio em geral formata a mquina do


usurio. Use um PC em que voc possa descartar o contedo do disco rgido
ou use uma mquina virtual.

Passo 1: Coloque o CD do Debian e inicialize o computador. Pressione <enter> para


iniciar a instalao.

Passo 2: Escolha uma linguagem

3 | Instalando o OpenSER 32
Passo 3: Escolha um layout de teclado

Passo 4: Escolha um hostname.

Passo 5: Escolha seu domnio

33 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Passo 6: Escolha seu mtodo de particionamento.

Passo 7 Selecione o disco

Passo 8: Selecione All files in one partition, todos os arquivos em uma partio.

3 | Instalando o OpenSER 34
Passo 9: Finaliza as mudanas para o disco

Passo 10: Escreva as mudanas para o disco.

Passo 11: Configure o fuso horrio.

35 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Passo 12: Configure a senha de root como openser

Step 13: Reinsira a senha para confirmar

Passo 14: Entre com o nome complete do usurio como openser

3 | Instalando o OpenSER 36
Passo 15: Entre o nome para a conta do usurio como openser

Passo 16: Insira a senha como openser. Duas vezes para confirmar.

Passo 17: Configure o gerenciador de pacotes. Selecione yes para usar um mirror.

37 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Passo 18: Selecione o pas do mirror.

Passo 19: Selecione ftp.debian.org ou seu mirror preferido.

Passo 20. Deixe em branco o Proxy http ou preencha-o com o endereo ip do seu
HTTP Proxy.

3 | Instalando o OpenSER 38
Passo 21: Selecione no na pesquisa de popularidade de pacotes.

Passo 22: Selecione o sistema padro

Passo 23: Selecione yespara instalar o GRUB.

39 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Passo 24: Termine a instalao.

O sistema ir reinicializar automaticamente.


Aps a re-inicializao instale o servidor SSH
apt-get install ssh

Baixando e instalando o OpenSER.


Mesmo sendo mais fcil de instalar o OpenSER usando os pacotes do Debian, ns
vamos compilar o OpenSER do zero. mais flexvel e de qualquer forma
precisaramos re-compilar o OpenSER algumas vezes neste material pata incluir
alguns mdulos. O processo passo a passo segue.
Passo 1: Instalar as dependncias
apt-get install gcc bison flex make openssl libmysqlclient-dev
libradiusclient-ng2 libradiusclient-ng-dev mysql-server

The MySQL server is not really a dependency, but we will install it at this
moment to make things easier.

3 | Instalando o OpenSER 40
Passo 2: Descarregue os pacotes fonte e descompacte-os.
cd /usr/src
wget http://www.openser.org/pub/openser/1.2.2/src/openser-1.2.2-
tls_src.tar.gz
tar -xzvf openser-1.2.2-tls_src.tar.gz

Passo 3: Use seu editor Linux favorite para editar o Makefile


Remova da linha Exclude= os mdulos MySQL e quaisquer mdulos relacionados
ao Radius. Isto vai fazer com que estes mdulos sejam compilados.
cd /usr/src/openser-1.2.2-tls/
vi Makefile

Trecho do arquivo antes das mudanas:


exclude_modules?= jabber cpl-c mysql pa postgres osp unixodbc \
avp_radius auth_radius
group_radius uri_radius xmpp \
presence pua pua_mi pua_usrloc \
mi_xmlrpc perl snmpstats

Trecho do arquivo aps as mudanas:


exclude_modules?= jabber cpl-c pa postgres osp unixodbc \
xmpp \
presence pua pua_mi pua_usrloc \
mi_xmlrpc perl snmpstats

Passo 4: Use o seu editor favorito para editar o arquivo Makefile do modulo ACC e
remover duas linhas relacionadas a contabilizao Radius.
vi modules/acc/Makefile

Trecho do arquivo antes das mudanas:


# uncomment the next two lines if you wish to enable RADIUS accounting
#DEFS+=-DRAD_ACC -I$(LOCALBASE)/include
#LIBS=-L$(LOCALBASE)/lib $(RADIUS_LIB)

Trecho do arquivo aps as mudanas:


# uncomment the next two lines if you wish to enable RADIUS accounting
DEFS+=-DRAD_ACC -I$(LOCALBASE)/include
LIBS=-L$(LOCALBASE)/lib $(RADIUS_LIB)

Passo 5: Compile e instale o ncleo e os mdulos


cd openser-1.2.2-tls
make prefix=/ all
make prefix=/ install

Passo 6: Faa os ajustes necessrios


mkdir /var/run/openser

Rodando o OpenSER no boot do Linux


Passo 1: Inclua o OpenSER no boot do Linux
cd /usr/src/openser-1.2.2-tls/packaging/debian
cp openser.default /etc/default/openser
cp openser.init /etc/init.d/openser
update-rc.d openser defaults 99

41 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Passo 2: Edite o arquivo /etc/openser/openser.cfg e remova a linha fork=no,
mesmo que ela esteja comentada. O script de inicializao procura esta instruo no
arquivo e vai encontr-la mesmo que comentada.
Passo 3: Certifique-se de que o script openser.ini tenha as permisses necessrias.
cd /etc/init.d
chmod 755 openser

Passo 4: Edite o arquivo /etc/default/openser, mude o parmetro de memria para


128 MB e o RUN_OPENSER para yes.
Passo 5: Edite o script de inicializao para certificar-se que de ele est apontando
para o processo no diretrio correto.
vi /etc/init.d/openser

Antes:
DAEMON=/usr/sbin/openser

Depois:
DAEMON=/sbin/openser

Passo 6: Reinicialize o computador e certifique-se de que o OpenSER iniciou.


ps-ef |grep openser.

altamente recomendvel que voc troque o usurio e senha usado para


executar o OpenSER no arquivo /etc/init.d/openser

Estrutura de diretrios do OpenSER v1.2


Configuration files (etc/openser)

openser-1:/etc/openser# ls -l
total 12
-rw-r--r-- 1 root root 1804 2007-09-10 14:02 dictionary.radius
-rw-r--r-- 1 root root 4077 2007-09-10 14:05 openser.cfg
-rw-r--r-- 1 root root 1203 2007-09-10 14:02 openserctlrccd

Modulos (/lib/openser/modules)

openser-1:/lib/openser/modules# ls
acc.so domain.so msilo.so sms.so
alias_db.so enum.so mysql.so speeddial.so
auth_db.so exec.so nathelper.so sst.so
auth_diameter.so flatstore.so options.so statistics.so
auth_radius.so gflags.so path.so textops.so
auth.so group_radius.so pdt.so tm.so
avpops.so group.so permissions.so uac_redirect.so
avp_radius.so imc.so pike.so uac.so
dbtext.so lcr.so registrar.so uri_db.so
dialog.so mangler.so rr.so uri.so
dispatcher.so maxfwd.so seas.so usrloc.so
diversion.so mediaproxy.so siptrace.so xlog.so

3 | Instalando o OpenSER 42
domainpolicy.so mi_fifo.so sl.socd /lib/openser/modules

Binaries (/sbin)

openser-1:/sbin# ls -l op*
-rwxr-xr-x 1 root root 2172235 2007-09-10 14:02 openser
-rwxr-xr-x 1 root root 41862 2007-09-10 14:02 openserctl
-rwxr-xr-x 1 root root 38107 2007-09-10 14:02 openser_mysql.sh
-rwxr-xr-x 1 root root 13562 2007-09-10 14:02 openserunixcd /sbin

Arquivos de Log
Os registros de inicializao podem ser vistos em /var/log
Sep 10 14:25:56 openser-1 openser: init_tcp: using epoll_lt as the io watch
method (auto detected)
Sep 10 14:25:56 openser-1 /sbin/openser[7791]: INFO: statistics manager
successfully initialized
Sep 10 14:25:56 openser-1 /sbin/openser[7791]: StateLess module -
initializing
Sep 10 14:25:56 openser-1 /sbin/openser[7791]: TM - initializing...
Sep 10 14:25:56 openser-1 /sbin/openser[7791]: Maxfwd module- initializing
Sep 10 14:25:56 openser-1 /sbin/openser[7791]: INFO:ul_init_locks: locks
array size 512
Sep 10 14:25:56 openser-1 /sbin/openser[7791]: TextOPS - initializing
Sep 10 14:25:56 openser-1 /sbin/openser[7791]: INFO: udp_init: SO_RCVBUF is
initially 109568
Sep 10 14:25:56 openser-1 /sbin/openser[7791]: INFO: udp_init: SO_RCVBUF is
finally 262142
Sep 10 14:25:56 openser-1 /sbin/openser[7791]: INFO: udp_init: SO_RCVBUF is
initially 109568
Sep 10 14:25:56 openser-1 /sbin/openser[7791]: INFO: udp_init: SO_RCVBUF is
finally 262142
Sep 10 14:25:56 openser-1 /sbin/openser[7792]:
INFO:mi_fifo:mi_child_init(1): extra fifo listener processes created

Comandos de inicializao
OpenSER pode ser iniciado com:
/etc/init.d/openser start|stop|restart

Voc pode iniciar o OpenSER para propsitos de depurao usando o comando


abaixo para verificar a sintaxe.
openser c

Outras opes podem ser vistas com openser help.

Sumrio
Neste captulo voc aprendeu a instalar o Linux, preparando a instalao do Sip
Express Router. Escolhemos o OpenSER por ser um projeto com atualizaes e

43 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
evolues mais constantes. O OpenSER compatvel com a RFC3261 por j suportar
TLS. Usamos pacotes do Debian para instalar o OpenSER pela facilidade da
instalao e por j colocar o OpenSER na carga do sistema.

3 | Instalando o OpenSER 44
4
Configurao padro.

No captulo passado, voc aprendeu como instalar o OpenSER. Nesta altura seu
servidor j deve estar instalado e funcionando. Vamos agora comear a explorar as
possibilidades partindo do exemplo mais bsico que o arquivo de configurao
padro.
Ao final deste captulo voc estar apto :
Identificar as sees do arquivo openser.cfg
Entender a configurao padro
Identificar as limitaes do OpenSER
Usar o utilitrio ngrep para rastrear o SIP
Ligar de um telefone a outro usando SIP
Reconhecer como funciona o roteamento bsico

Onde estamos?
Ainda continuamos dentro do mesmo componente, o SIP Proxy.

The SIP provider MySQL/Postgres/


Big Picture Unixodbc Database

Ethernet

Media
User Radius
SIP PSTN Media Proxy CDRTool Monitoring
Portal Server Tools
Proxy Gateway Server Nat Rating
Provis. Traversal Acct.

Ethernet

CPE device (router)


Usually xDSL or
Cable
Internet Firewall
Customer Customer
Using an ATA Firewall
or Softphone
Configurao padro
A configurao padro um bom ponto de partida. Ela tem uma funcionalidade
mnima e no suporta autenticao, de forma que voc pode conectar telefones SIP
sem uma senha. De qualquer forma, voc pode us-la para chamar de um telefone IP
para outro. Ao final deste captulo, ns vamos testar a configurao padro.

Listagem e descrio dos comandos


#
# $Id: openser.cfg 1676 2007-02-21 13:16:34Z bogdan_iancu $
#
# simple quick-start config script
# Please refer to the Core CookBook at
http://www.openser.org/dokuwiki/doku.php
# for a explanation of possible statements, functions and parameters.
#

# ----------- global configuration parameters ------------------------

debug=3 # debug level (cmd line: -dddddddddd)


fork=yes
log_stderror=no # (cmd line: -E)
children=4

# Uncomment these lines to enter debugging mode


#fork=no
#log_stderror=yes
#

port=5060

# uncomment the following lines for TLS support


#disable_tls = 0
#listen = tls:your_IP:5061
#tls_verify_server = 1
#tls_verify_client = 1
#tls_require_client_certificate = 0
#tls_method = TLSv1
#tls_certificate = "//etc/openser/tls/user/user-cert.pem"
#tls_private_key = "//etc/openser/tls/user/user-privkey.pem"
#tls_ca_list = "//etc/openser/tls/user/user-calist.pem"

# ------------------ module loading ----------------------------------

#set module path


mpath="//lib/openser/modules/"

# Uncomment this if you want to use SQL database


#loadmodule "mysql.so"

loadmodule "sl.so"
loadmodule "tm.so"

4 | Configurao padro. 46
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "mi_fifo.so"

# Uncomment this if you want digest authentication


# mysql.so must be loaded !
#loadmodule "auth.so"
#loadmodule "auth_db.so"

# ----------------- setting module-specific parameters ---------------

# -- mi_fifo params --

modparam("mi_fifo", "fifo_name", "/tmp/openser_fifo")

# -- usrloc params --

modparam("usrloc", "db_mode", 0)

# Uncomment this if you want to use SQL database


# for persistent storage and comment the previous line
#modparam("usrloc", "db_mode", 2)

# -- auth params --
# Uncomment if you are using auth module
#
#modparam("auth_db", "calculate_ha1", yes)
#
# If you set "calculate_ha1" parameter to yes (which true in this config),
# uncomment also the following parameter)
#
#modparam("auth_db", "password_column", "password")

# -- rr params --
# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)

# ------------------------- request routing logic -------------------

# main routing logic

route{

# initial sanity checks -- messages with


# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};

47 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
if (msg:len >= 2048 ) {
sl_send_reply("513", "Message too big");
exit;
};

# we record-route all messages -- to make sure that


# subsequent messages will go through our proxy; that's
# particularly good if upstream and downstream entities
# use different transport protocol
if (!method=="REGISTER")
record_route();

# subsequent messages withing a dialog should take the


# path determined by record-routing
if (loose_route()) {
# mark routing logic in request
append_hf("P-hint: rr-enforced\r\n");
route(1);
};

if (!uri==myself) {
# mark routing logic in request
append_hf("P-hint: outbound\r\n");
# if you have some interdomain connections via TLS
#if(uri=~"@tls_domain1.net") {
# t_relay("tls:domain1.net");
# exit;
#} else if(uri=~"@tls_domain2.net") {
# t_relay("tls:domain2.net");
# exit;
#}
route(1);
};

# if the request is for other domain use UsrLoc


# (in case, it does not work, use the following command
# with proper names and addresses in it)
if (uri==myself) {

if (method=="REGISTER") {

# Uncomment this if you want to use digest


authentication
#if (!www_authorize("openser.org", "subscriber")) {
# www_challenge("openser.org", "0");
# exit;
#};

save("location");
exit;
};

lookup("aliases");
if (!uri==myself) {

4 | Configurao padro. 48
append_hf("P-hint: outbound alias\r\n");
route(1);
};

# native SIP destinations are handled using our USRLOC DB


if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
append_hf("P-hint: usrloc applied\r\n");
};

route(1);
}

route[1] {
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
exit;
}

Anlise do arquivo padro


Agora que vimos a configurao padro, vamos explicar cada linha no arquivo de
forma que voc possa entender o bsico do OpenSER. Esta configurao completa e
mnima, os clientes podem se registrar, a autenticao tanto do REGISTER quanto
dos INVITES no est instalado.
debug=3 # debug level (cmd line: -dddddddddd)

Nvel de informao de debug. O nvel 3 suficiente para deteco de erros. O maior


nvel 9 e o sistema pode ficar um pouco lento neste nvel de debug.
fork=yes

A diretiva fork diz ao processo do OpenSER para executar em foreground ou em


background. Para operar em background use fork=yes.
log_stderror=no # (cmd line: -E)

A instruo log_stderror, registra as mensagens na rea padro para erros. Como


vamos rodar o processo em background no vamos jogar os erros na tela.
children=4

A diretiva children informa ao OpenSER quantos processos filho por interface


devem ser criadas. Quatro um bom ponto de partida na maioria dos sistemas.
dns=no

49 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Estas linhas previnem o OpenSER de pesquisar o seu endereo IP no DNS. Ao
adicionar estas linhas, ns suprimimos avisos do sistema de que o IP no esta no
servidor DNS
rev_dns=no

Este parmetro controla se o servidor SIP deveria tentar verificar seu prprio endereo
IP no DNS. Se configurado para yes e o endereo IP no est no DNS, um aviso
(warning) ser impresso no syslog e um received= ser adicionado ao cabealho via.
A no ser que tenha uma boa razo deixe-o sem modificao.
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "mi_fifo.so"

Nestas linhas os mdulos externos do OpenSER esto sendo carregados. A pergunta


bvia , quais mdulos devem ser carregados? Os que esto neste arquivo so o
mnimo, funcionalidades adicionais podem necessitar de outros mdulos como
autenticao no RADIUS, por exemplo. Todos os mdulos do OpenSER tm um
README que expe os comandos e parmetros que so disponibilizados.
modparam("usrloc", "db_mode", 0)

O mdulo USRLOC responsvel por cuidar dos registros dos clientes SIP e guardar
em uma base de localizao. Em outras palavras, quando um cliente SIP se registra
com um SIP Proxy, o OpenSER ir guardar as informaes de contato, tambm
conhecidas como AOR (endereo do registro). A localizao desta tabela depende do
valor do parmetro db_mode. Um db_mode de 0 significa no persistir os dados, em
outras palavras se o OpenSER desligado todos os registros so perdidos.
modparam("rr", "enable_full_lr", 1)

O parmetro do mdulo RR chamado enable_full_lr realmente uma forma de


contornar os problemas para clientes SIP antigos que no gerenciam cabealhos do
tipo Record-route.
route {

Este o incio da lgica de processamento do SIP. Esta linha define o bloco de


roteamento principal. O bloco comea e termina com uma chave. Neste bloco as
mensagens SIP so processadas. Uma viso geral do que acontece pode ser vista
abaixo:
# initial sanity checks -- messages with
# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};

if (msg:len >= 2048 ) {

4 | Configurao padro. 50
sl_send_reply("513", "Message too big");
exit;
};

Quando uma mensagem chega no bloco de roteamento principal, algumas verificaes


so feitas.
A funo mf_process_maxfwd_header() faz uma verificao de segurana que voc
deve sempre incluir como a primeira linha do bloco principal. Esta funo exposta
pelo mdulo MF e usada para registrar quantas vezes a mensagem SIP passou
atravs do OpenSER. Isto usado para evitar loops.
Se uma situao de looping ocorrer o OpenSER precisa de uma forma de dizer ao
cliente SIP que um erro ocorreur. A funo sl_send_reply faz esse trabalho. A funo
sl_send_reply() exposta pelo mdulo SL e o que ele faz enviar uma mensagem
sem estado ao cliente SIP. Isto significa que o OpenSER envia a mensagem e no
espera por uma confirmao. Alguns telefones mostram a mensagem ao usurio. A
instruo exit diz ao OpenSER para parar o processamento da mensagem SIP e sair.
O msg:len uma funo do ncleo do OpenSER que retorna o comprimento em bytes
da mensagem SIP. Esta uma verificao padro para evitar estouros de buffer.
if (!method=="REGISTER")
record_route();

Aqui verificamos se a mensagem SIP que foi recebida um REGISTER. Se no um


REGISTER, ento devemos gravar as rotas (Record-route) da mensagem para
assegurar que os Proxies frente e a r possam interagir e manter nosso SIP
informado a respeito das mudanas de estado SIP. A palavra chave method do ncleo
do OpenSER e permite descobrir o tipo de mensagem SIP com a qual voc est
lidando.
A funo record_route() simplesmente adiciona um cabealho Record-Route
mensagem SIP atual. Outros servidores SIP ou clientes usaro este cabealho para
saber onde enviar uma resposta ou uma nova mensagem em um dilogo SIP.
# subsequent messages withing a dialog should take the
# path determined by record-routing
if (loose_route()) {
# mark routing logic in request
append_hf("P-hint: rr-enforced\r\n");
route(1);
};

A funo loose_route() testa para ver se a mensagem atual SIP deveria ser
encaminhada no modo loose route ou no. Se uma mensagem deve funcionar neste
modo, o OpenSER ir simplesmente encaminhar a mensagem para o prximo destino
como especificado no cabealho Route mais alto. Em todos os arquivos openser.cfg
voc deve chamar o loose_route() aps o record_route(). Esta a definico bsica
de loose routing. Voc pode conhecer um pouco mais sobre loose routing na
RFC3261.

51 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Se o teste para o loose routing retorna verdadeiro, ento ns devemos encaminhar a
mensagem sem nenhum outro processamento. Para tal ns passamos o controle da
execuo para o bloco de roteamento nmero 1 (route[1]).
Como loose routing foi pedido, ns no podemos mais processar a mensagem de
forma que devemos usar o exit para sair do bloco principal.
if (!uri==myself) {
# mark routing logic in request
append_hf("P-hint: outbound\r\n");
# if you have some interdomain connections via TLS
#if(uri=~"@tls_domain1.net") {
# t_relay("tls:domain1.net");
# exit;
#} else if(uri=~"@tls_domain2.net") {
# t_relay("tls:domain2.net");
# exit;
#}
route(1);
};

No cdigo acima entramos na parte do arquivo de configurao SIP onde ns


processamos as mensagens fora do dilogo. Em outras palavras, ns vamos processar
ou uma mensagem que inicia um novo dilogo ou vamos processar uma mensagem
que no destinada ao nosso SIP Proxy. A chave uri definida no ncleo do
OpenSER e sinnimo de Request URI, a palavra myself sinnimo do prprio
proxy.
Se a mensagem no tem como destino final o nosso Proxy, vamos encaminh-la para
o seu destino final.
if (method=="REGISTER") {
# Uncomment this if you want to use digest authentication
#if (!www_authorize("openser.org", "subscriber")) {
# www_challenge("openser.org", "0");
# exit;
#};

save("location");
exit;
};

Testa se a mensagem um REGISTER que ser gerenciada de forma diferenciada.


Todos os pedidos de registro so salvos na tabela de localizao. Fazemos isto para
facilitar a visualizao do arquivo openser.cfg.
lookup("aliases");
if (!uri==myself) {
append_hf("P-hint: outbound alias\r\n");
route(1);
};

A funo lookup(aliases) tenta recuperar quaisquer aliases para a URI. Um alias


apenas outra forma de se referir um destino SIP. Por exemplo, se voc tem um

4 | Configurao padro. 52
usurio SIP flavio@sermyadmin.org e um nmero de ramal 8590, quando algum
discar o nmero, o telefone associado quele usurio ir tocar.
Se um alias foi encontrado e a uri no mais um destino localmente servido, ento
fazemos encaminhamento da chamada.
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
append_hf("P-hint: usrloc applied\r\n");

A funo lookup(location) tenta recuperar o endereo (AOR) para a URI


solicitada. Em outras palavras a funo tenta descobrir o endereo IP da pessoa que
voc est chamando. Ele faz isto buscando esta informao na tabela de localizao
onde voc salvou o usurio durante o REGISTER. Se este usurio for localizado, ele
receber um INVITE, seno vamos enviar um erro dizendo que o usurio no foi
encontrado.
route[1] {
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
exit;
}

Se a mensagem SIP atual no um REGISTER, ento vamos apenas encaminhar para


o seu destino. Fazemos isso passando o controle para a rota 1 que o processamento
padro das mensagens.
A funo t_relay() exposta pelo mdulo TM e talvez uma das funes mais
importantes em qualquer arquivo openser.cfg. A funo t_relay() responsvel por
enviar a mensagem para o seu destino e cuidar de quaisquer re-envios e respostas. Se
a mensagem no puder ser enviada para o destino com sucesso, ento o t_relay() ir
retornar uma condio de erro. Se ele no conseguir despachar a mensagem ento a
funo sl_reply_error() ir enviar o erro de volta para o cliente SIP para informar
que um erro no servidor ocorreu.

Usando a configurao padro.


Neste exerccio usaremos um analisador de protocolo para capturar uma chamada SIP.
Depois de capturar a chamada vamos analisar os cabealhos e o fluxo de mensagens.
Voc pode criar este ambiente com dois PCs e um ATA ou qualquer combinao que
gere um computador com o OpenSER instalado e dois agentes usurio IP (softfones,
Atas e telefones IP).

53 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Ambiente do Laboratrio
PC com Linux Estao de
Instalado e trabalho com
Adaptador de OpenSER Softfone
Telefonia SIP - Proxy
Analgica

Rede Ethernet

Nota: Adapte este laboratrio as suas necessidades

1 Configure o Xlite no seu PC


Configure o X-LITE com os seguintes parmetros
sip proxy 10.1.x.y ip do seu proxy
usurio: 1000
senha: 1000
Configure o Adaptador de Telefonia Analgica
Sip proxy 10.1.x.y ip do seu proxy
Realm voffice.com.br
Usurio: 1001
Senha: 1001
2 Abra o softfone e disque 1001, isto vai tocar no ATA.
3 Capture os pacotes usando o ngrep e verifique que ao contrrio da captura feita no
captulo 1, nenhuma mensagem 407 Proxy Authentication Required foi enviada.
Porque ?
debianSER#ngrep p q W byline port=5060 >teste.txt

Veja o arquivo teste.txt usando o utilitrio pg.


debianSER#pg teste.txt

Conceitos bsicos de roteamento SIP


No fcil de entender como os pacotes SIP so roteados. Ns vamos apresentar
agora nesta seo alguns dos conceitos bsicos para se rotear pacotes atravs de um
SIP Proxy. O primeiro conceito importante o que envolve dilogos e transaes.

Transaes e dilogos
Uma transao iniciada com um pedido e termina, normalmente, com um cdigo de
resposta. O parmetro branch no cabealho VIA identifica uma transao. Um dilogo
4 | Configurao padro. 54
pode iniciar com uma transao INVITE e terminar com uma transao BYE. Um
dilogo identificado por uma combinao dos cabealhos FROM, TO e CALL-ID.
Nem todos os mtodos SIP abrem um novo dilogo. Os mtodos REGISTER e
MESSAGE, por exemplo, no abrem.

Pedidos Iniciais e Seqenciais


importante entender a diferena entre pedidos iniciais e seqenciais. Para pedidos
iniciais, voc tem de decidir como vai rote-lo baseado em um mecanismo de
descobrimento, normalmente baseado em DNS ou em uma tabela de localizao.
O pedido inicial registra suas informaes de roteamento no campo VIA e se voc
habilitou o recurso de Record routing nos cabealhos ROUTE tambm. Dentro de
uma transao, os pacotes so roteados de volta usando o campo VIA passando por
cada Proxy passado anteriormente. Os pedidos subseqentes so roteados usando a
informao contida no campo CONTACT. No entanto, se voc habilitou o recurso de
registro do roteamento (record route), os pedidos subseqentes sero roteados usando
o conjunto de rotas definidos pelos cabealhos ROUTE. Voc pode distinguir entre
um pedido inicial ou seqencial usando o parmetro TAG no campo cabealho TO.

Roteamento no contexto de uma transao


Dentro de uma transao, todos os pedidos so roteados usando o campo VIA. Desta
forma, todas as respostas passam atravs do Proxy antes de chegar ao destino final. Se
voc encaminhar o pedido usando a funo t_relay(), o SIP Proxy opera no modo
stateful. Isto permite que voc possa manipular as respostas e falhas usando as
sees onreply_route[] e failure_route[].

55 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Roteamento no contexto de um dilogo
Pedidos subseqentes no mesmo dilogo so normalmente roteados diretamente de
ponto a ponto usando o campo CONTACT. Na maioria das vezes ao invs de enviar
diretamente uma transao subseqente como BYE, voc vai preferir for-la atravs
do Proxy, de forma a ser possvel bilhetar a chamada e controlar o dilogo. Voc pode
fazer isto habilitando um recurso chamado Record Routing. Ao fazer isto voc
instrui o Proxy a gravar as rotas em cabealhos Route dentro do prprio pacote SIP.

Mais tarde voc poder usar as rotas pr-gravadas, tambm conhecidas como conjunto
de rotas (route-set). Esta a configurao mais comum e est contida na configurao
padro.

Lab. Verificando um dilogo completo


Neste laboratrio, ns vamos usar um script simplificado para entender os conceitos
de roteamento. Ns vamos usar a funo append_hf() para adicionar um cabealho ao
pacote marcando o ponto onde ele foi processado no script.

4 | Configurao padro. 56
Passo1: Use o script abaixo (openser.chapter4-2). Reinicie o OpenSER e ento
registre novamente os telefones SIP.
route{
# All messages, except for REGISTER will pass here
if (!method=="REGISTER") record_route();

# subsequent messages withing a dialog should take the


# path determined by record-routing
if (loose_route()) {
# mark routing logic in request
append_hf("P-hint: (1)rr-enforced\r\n");
route(1);
};

# We will route only intra-domain requests


if (!uri==myself) {
exit();
};

# main routing of intra-domain requests


if (uri==myself) {

if (method=="REGISTER") {
save("location");
exit;
};

# native SIP destinations are handled using our USRLOC DB


if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};

57 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
append_hf("P-hint: (2)usrloc applied\r\n");
};
route(1);
}

route[1] {
# send it out now; use stateful forwarding
t_on_reply("1");
t_on_failure("1");
if (!t_relay()) {
sl_reply_error();
};
exit;
}

onreply_route[1] {
append_hf("P-hint: (3)passed thru onreply_route[1]\r\n");
}

failure_route[1] {
append_hf("P-hint: (4)passed thru failure_route[1]\r\n");
}

Passo 2: Use o ngrep para capturar os pedidos e respostas para um arquivo.


ngrep p q W byline port 5060 >rr-stateful
Passo 3: Inicie uma chamada do telefone 1000 para o telefone 1001 (ou qualquer
outro telefone registrado)
Passo 4: Pare o ngrep usando a tecla CTRL-C
Verifique os pacotes usando um editor de texto e veja os campos P-Hint no cabealho
dos pacotes. Eles devem estar iguais a figura mostrada no incio deste laboratrio.

Lab. Rodando sem estado (stateless)


Se voc substituir a funo t_relay() pela funo forward(), voc ir usar o SIP
Proxy no modo sem estado. Tudo continuar funcionando, mas voc no poder mais
manipular as respostas. O Proxy agora no mais correlaciona os pedidos e as respostas
nas mesmas transaes. As respostas so processadas pelo campo VIA como usual
Passo 1: Substitua a funo t_relay() pela funo forward() como abaixo.
Replace:
if (!t_relay()) {
sl_reply_error();
};

By:
forward()

Passo 2: Reinicialize o OpenSER e registre novamente os telefones


Passo 3: Use o ngrep para capturar os pedidos e respostas para um arquivo
ngrep p q W byline port 5060 >rr-stateless

4 | Configurao padro. 58
Passo 4: Faa uma chamada do 1000 para o 1001
Passo 5: Aps terminar a chamada, pare o ngrep
Passo 6: Use um editor de texto para verificar o arquivo chamado rr-stateless. Voc
ir notar que as respostas agora no tem o campo P-Hint. Isto indica que elas no
foram processadas na seo onreply_route[]. Desta forma, se voc usar o
processamento sem controle de estado, no poder lidar com as respostas, apenas
poder encaminh-las ao seu destino final.

Lab. Desabilitando o registro de rotas (Record-route)


Neste laboratrio, ns vamos para de registrar as rotas. Assim od pedidos
subseqentes de um dilogo iro diretamente de um telefone para outro contornando o
SIP Proxy. Eles usam a informao no campo CONTACT para tal.
Passo 1: Comente a linha responsvel pelo registro de rotas.
#if (!method=="REGISTER") record_route();

Passo 2: Reinicie o OpenSER e registre novamente os telefones.


Passo 3: Use o ngrep para capturar os pedidos e respostas para um arquivo.
ngrep p q W byline port 5060 >norr-stateless

Passo 4: faa uma chamada do telefone 1000 para o telefone 1001


Passo 5: aps terminar a chamada, pare o ngrep.
Passo 6: Use um editor de texto para verificar o arquivo norr-stateless. Voc ir notar
que agora no possvel capturar os pedidos de BYE e ACK. Isto acontece porque
agora eles esto indo diretamente de um ponto para o outro. Se voc quiser bilhetar s
chamadas, este o tipo de comportamento que no vai lhe interessar.

Sumrio
Neste captulo voc aprendeu algumas instrues para cada uma das sesses do
arquivo openser.cfg. Este a configurao mais simples. Nos prximos captulos ns
vamos aumentar a funcionalidade e a complexidade do script. Este captulo serviu
como um ponto de partida para desenvolver scripts mais avanados. No final foi
possvel conhecer um pouco mais sobre o roteamento SIP um dos conceitos mais
importantes de se entender para trabalhar com o OpenSER. Mesmo sendo um script
simples ele permitiu que voc conectasse dois telefones um ao outro.

59 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
5
Autenticao com MySQL

Agora que voc j aprendeu a operar o OpenSER na configurao padro, vamos


examinar como usar o MySQL na autenticao dos usurios. Nesta seo vamos
aprender a autenticar os telefones no OpenSER usando o MYSQL e a manter a base
de contatos (AOR ou base de localizao) de forma persistente no SQL. Em
circunstncias normais, vamos restringir o uso do servidor SIP queles telefones que
queremos. O objetivo nos certificarmos que apenas os telefones que tem senha
possam usar o servidor.
No final deste captulo, voc estar apto :
Configurar o MySQL para autenticar dispositivos SIP
Usar o openserctl para operaes bsicas como adicionar e remover usurios.
Mudar o script openser.cfg para configurar a autenticao MySQL.
Implantar persistncia para as tabelas de localizao
Reiniciar o servidor sem perder os registros de localizao
Lidar corretamente com chamadas entre domnios

5 | Autenticao com MySQL 60


Onde estamos?

The SIP provider MySQL/Postgres/


Big Picture Unixodbc Database

Ethernet

Media
User Radius
SIP PSTN Media Proxy CDRTool Monitoring
Portal Server Tools
Proxy Gateway Server Nat Rating
Provis. Traversal Acct.

Ethernet

CPE device (router)


Usually xDSL or
Cable
Internet Firewall
Customer Customer
Using an ATA Firewall
or Softphone

O modulo Auth_DB
A autenticao feita pelo mdulo AUTH_DB. Ele trabalha em conjunto com os
mdulos de bases de dados tais como o SQL e o Postgres. O AUTH_DB tem alguns
parmetros que no so declarados explicitamente no script. Vamos mostrar abaixo os
parmetros padro para o mdulo AUTH_DB.
Parmetro Default Descrio
db_url "mysql://openserro:openserro URL da base de dados
@localhost/openser"
user_column "username" Nome da coluna que mantm
os usurios
domain_column "domain" Nome da coluna do domnio
dos usurios
password column ha1 Nome da coluna mantendo as
senhas
password_column2 ha1b Nome da coluna mantendo os
hashs pr-calculados que
incluem o nome do usurio e
domnio.
calculate_ha1 0 (server assumes that ha1 Diz ao servidor se ele deve
strings are already calculated esperar senhas em texto plano
in the database) na base de dados ou no.
use_domain 0 (domains wont be checked Use este parmetro se voc
when looking up in the vai ter um ambiente multi-
subscriber database) domnio.
load_credentials rpid Especifica as credencias a
serem buscadas na base de

61 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
dados quando a autenticao
feita. Esta credencial ser
armazenada em um AVP.

O modulo AUTH_DB exporta duas funes.


www_authorize(realm, table)

Esta funo usada na autenticao dos pacotes do tipo REGISTER que ocorrem de
acordo com a RFC2617.
proxy_authorize(realm, table)

Esta funo verifica as credenciais de acordo com a RFC2617 para os pedidos de


INVITE. Se as credenciais forem verificadas com sucesso elas sero marcadas como
autorizadas.

Seqncia de autenticao para pedidos de registro:


O script deve autenticar mensagens de REGISTER e INVITE. Vamos mostrar como
isto acontece antes de mudar o arquivo openser.cfg. Quando o OpenSER recebe um
pedido de registro ele verifica a existncia de um cabealho de AUTHORIZE. Se ele
no encontra, ento ele solicita ao UAC suas credenciais e sa.

Sequncia de Autenticao
para o Register

Aps receber a solicitao o UAC deve enviar uma mensagem de registro com um
campo cabealho do tipo AUTHORIZE.

Captura de uma seqncia de registro.


O processo de registro pode ser visto na captura de pacotes abaixo:
U 192.168.1.119:29040 -> 192.168.1.155:5060

5 | Autenticao com MySQL 62


REGISTER sip:192.168.1.155 SIP/2.0.
Via: SIP/2.0/UDP 192.168.1.119:29040;branch=z9hG4bK-d87543-13517a5a8218ff45-1--d87543-
;rport.
Max-Forwards: 70.
Contact: <sip:1000@192.168.1.119:29040;rinstance=2286bddd834b3cfe>.
To: "1000"<sip:1000@192.168.1.155>.
From: "1000"<sip:1000@192.168.1.155>;tag=0d10cc75.
Call-ID: e0739d571d287264NjhiZjM2N2UyMjhmNDViYTgzY2I4ODMxYTVlZTY0NDc..
CSeq: 1 REGISTER.
Expires: 3600.
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO.
User-Agent: X-Lite release 1003l stamp 30942.
Content-Length: 0.

U 192.168.1.155:5060 -> 192.168.1.119:29040


SIP/2.0 401 Unauthorized.
Via: SIP/2.0/UDP 192.168.1.119:29040;branch=z9hG4bK-d87543-13517a5a8218ff45-1--d87543-
;rport=29040.
To: "1000"<sip:1000@192.168.1.155>;tag=329cfeaa6ded039da25ff8cbb8668bd2.41bb.
From: "1000"<sip:1000@192.168.1.155>;tag=0d10cc75.
Call-ID: e0739d571d287264NjhiZjM2N2UyMjhmNDViYTgzY2I4ODMxYTVlZTY0NDc..
CSeq: 1 REGISTER.
WWW-Authenticate: Digest realm="192.168.1.155",
nonce="46263864b3abb96a423a7ccf052fa68d4ad5192f".
Server: OpenSER (1.2.0-notls (i386/linux)).
Content-Length: 0.
.
U 192.168.1.119:29040 -> 192.168.1.155:5060
REGISTER sip:192.168.1.155 SIP/2.0.
Via: SIP/2.0/UDP 192.168.1.119:29040;branch=z9hG4bK-d87543-da776d09bd6fcb65-1--d87543-
;rport.
Max-Forwards: 70.
Contact: <sip:1000@192.168.1.119:29040;rinstance=2286bddd834b3cfe>.
To: "1000"<sip:1000@192.168.1.155>.
From: "1000"<sip:1000@192.168.1.155>;tag=0d10cc75.
Call-ID: e0739d571d287264NjhiZjM2N2UyMjhmNDViYTgzY2I4ODMxYTVlZTY0NDc..
CSeq: 2 REGISTER.
Expires: 3600.
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO.
User-Agent: X-Lite release 1003l stamp 30942.
Authorization: Digest
username="1000",realm="192.168.1.155",nonce="46263864b3abb96a423a7ccf052fa68d4ad5192f"
,uri="sip:192.168.1.155",response="d7b33793a123a69ec12c8fc87abd4c03",algorithm=MD5.
Content-Length: 0.

U 192.168.1.155:5060 -> 192.168.1.119:29040


SIP/2.0 200 OK.
Via: SIP/2.0/UDP 192.168.1.119:29040;branch=z9hG4bK-d87543-da776d09bd6fcb65-1--d87543-
;rport=29040.
To: "1000"<sip:1000@192.168.1.155>;tag=329cfeaa6ded039da25ff8cbb8668bd2.c577.
From: "1000"<sip:1000@192.168.1.155>;tag=0d10cc75.

63 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Call-ID: e0739d571d287264NjhiZjM2N2UyMjhmNDViYTgzY2I4ODMxYTVlZTY0NDc..
CSeq: 2 REGISTER.
Contact: <sip:1000@192.168.1.119:29040;rinstance=2286bddd834b3cfe>;expires=3600.
Server: OpenSER (1.2.0-notls (i386/linux)).
Content-Length: 0.

Trecho do cdigo de registro com autenticao.


if (method=="REGISTER") {
# Uncomment this if you want to use digest authentication
if (!www_authorize("", "subscriber")) {
www_challenge("", "0");
exit;
};
save("location");
exit;
};

Na seqncia acima, na primeira passada o pacote de registro no autenticado. Ento


a instruo www_chalenge() invocada. Ela envia o pacote 401 Unauthorized. Na
segunda passada o UAC envia o pacote de registro com o campo cabealho Authorize
preenchido corretamente. Ento a funo save(location) invocada para salvar o
registro na tabela location do servidor de banco de dados MySQL.

Seqncia de autenticao do INVITE


Abaixo est mostrada uma seqncia de autenticao de um pedido de INVITE de
uma chamada ordinria. O servidor Proxy sempre responde ao primeiro INVITE com
uma resposta contendo a mensagem 407 Proxy Authentication Required. Esta
mensagem tem um cabealho Authorize contendo parmetros para a gerao do
Digest como o Realm e o Nonce. Uma vez que estes dados so recebidos pelo
UAC, esta mensagem respondida com um novo INVITE, agora com um cabealho
Authorize contendo o digest calculado com o nome do usurio, senha, realm e o
nonce usando o algoritmo MD5.

5 | Autenticao com MySQL 64


Seqncia de autenticao dos
pedidos de INVITE

INVITE
407 Proxy
Authentication
Required
ACK
INVITE
With Proxy-Authorize
header
100 Giving a try User Agent
User Agent
Client
Client INVITE
(1000)
(1001) 180 Ringing
SIP Proxy
180 Ringing
200 Ok
200 Ok
ACK
ACK
Call Established

Seqncia de pacotes de um pedido do tipo INVITE.


U 192.168.1.169:5060 -> 192.168.1.155:5060
INVITE sip:1000@192.168.1.155 SIP/2.0.
Via: SIP/2.0/UDP 192.168.1.169;branch=z9hG4bKf45d977e65cf40e0.
From: <sip:1001@192.168.1.155>;tag=a83bebd75be1d88e.
To: <sip:1000@192.168.1.155>.
Contact: <sip:1001@192.168.1.169>.
Supported: replaces.
Call-ID: 8acb7ed7fc07c369@192.168.1.169.
CSeq: 39392 INVITE.
User-Agent: TMS320V5000 TI50002.0.8.3.
Max-Forwards: 70.
Allow: INVITE,ACK,CANCEL,BYE,NOTIFY,REFER,OPTIONS,INFO,SUBSCRIBE.
Content-Type: application/sdp.
Content-Length: 386.
(sdp header striped off).

U 192.168.1.155:5060 -> 192.168.1.169:5060


SIP/2.0 407 Proxy Authentication Required.
Via: SIP/2.0/UDP 192.168.1.169;branch=z9hG4bKf45d977e65cf40e0.
From: <sip:1001@192.168.1.155>;tag=a83bebd75be1d88e.
To: <sip:1000@192.168.1.155>;tag=329cfeaa6ded039da25ff8cbb8668bd2.b550.
Call-ID: 8acb7ed7fc07c369@192.168.1.169.
CSeq: 39392 INVITE.
Proxy-Authenticate: Digest realm="192.168.1.155",
nonce="4626420b4b162ef84a1a1d3966704d380194bb78".
Server: OpenSER (1.2.0-notls (i386/linux)).
Content-Length: 0.

65 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
U 192.168.1.169:5060 -> 192.168.1.155:5060
ACK sip:1000@192.168.1.155 SIP/2.0.
Via: SIP/2.0/UDP 192.168.1.169;branch=z9hG4bKf45d977e65cf40e0.
From: <sip:1001@192.168.1.155>;tag=a83bebd75be1d88e.
To: <sip:1000@192.168.1.155>;tag=329cfeaa6ded039da25ff8cbb8668bd2.b550.
Contact: <sip:1001@192.168.1.169>.
Call-ID: 8acb7ed7fc07c369@192.168.1.169.
CSeq: 39392 ACK.
User-Agent: TMS320V5000 TI50002.0.8.3.
Max-Forwards: 70.
Allow: INVITE,ACK,CANCEL,BYE,NOTIFY,REFER,OPTIONS,INFO,SUBSCRIBE.
Content-Length: 0.

U 192.168.1.169:5060 -> 192.168.1.155:5060


INVITE sip:1000@192.168.1.155 SIP/2.0.
Via: SIP/2.0/UDP 192.168.1.169;branch=z9hG4bKcdb4add5db72d493.
From: <sip:1001@192.168.1.155>;tag=a83bebd75be1d88e.
To: <sip:1000@192.168.1.155>.
Contact: <sip:1001@192.168.1.169>.
Supported: replaces.
Proxy-Authorization: Digest username="1001", realm="192.168.1.155", algorithm=MD5,
uri="sip:1000@192.168.1.155", nonce="4626420b4b162ef84a1a1d3966704d380194bb78",
response="06736c6d7631858bb1cbb0c86fb939d9".
Call-ID: 8acb7ed7fc07c369@192.168.1.169.
CSeq: 39393 INVITE.
User-Agent: TMS320V5000 TI50002.0.8.3.
Max-Forwards: 70.
Allow: INVITE,ACK,CANCEL,BYE,NOTIFY,REFER,OPTIONS,INFO,SUBSCRIBE.
Content-Type: application/sdp.
Content-Length: 386.
(sdp header striped off)

Trecho do cdigo do INVITE


} else if (method=="INVITE") {
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","0");
exit;
};
#consume_credentials();
};

Autenticao do tipo Digest


A autenticao SIP baseada na RFC2617 HTTP Authentication: Basic and Digest
Access Authentication. Nosso objetivo nesta seo mostrar o bsico do sistema de
autenticao por Digest. Ele no foi criado para ser uma resposta a todos os possveis
problemas de segurana com SIP, mas certamente um bom mtodo para proteger
nomes e senhas passando pela rede.

5 | Autenticao com MySQL 66


Digest Authentication

WWW-Authenticate: Digest
realm="192.168.1.155",
nonce="46263864b3abb96a423a7ccf052fa68d4ad5192f".

1
2
Authorization: Digest
username="1000", SIP
realm="192.168.1.155", Server
nonce="46263864b3abb96a423a7ccf052fa68d4ad5192f",
uri="sip:192.168.1.155",
response="d7b33793a123a69ec12c8fc87abd4c03",
algorithm=MD5.

O esquema do Digest um mecanismo simples de desafio-resposta. Ele desafia o


UA usando um valor para o parmetro nonce. Uma resposta vlida contm um
checksum com todos os parmetros. Desta forma a senha nunca transmitida em
texto simples.

O cabealho WWW-Authenticate Response


Se um servidor recebe um pedido de REGISTER ou INVITE e um cabealho vlido
de autorizao no enviado, o servidor responde com um 401 Unauthorized e um
cabealho WWW-Authenticate. Ele contm um realm e um nonce.

O cabealho Authorization Request


esperado que o cliente tente novamente, passando a linha de cabealho de
autorizao. Ela contm o nome do usurio, realm,.nonce (passado pelo servidor),
uri, resposta em hexadecimal de 32 dgitos (Checksum gerado pelo cliente) e o
algoritmo usado.

67 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Digest Authentication
with qop=auth

WWW-Authenticate: Digest
realm="8.8.30.49",
nonce="4630c7304423763c9e34850300dab814939d2658",
qop="auth".

1
2
Authorization: Digest
SIP
username="1000",
Server
realm="8.8.30.49",
nonce="4630c7304423763c9e34850300dab814939d2658",
uri="sip:8.8.30.49",
response="2fad708663e109fe68774e08fda91808",
cnonce="87c730b997eb79ca",
nc=00000001,
qop=auth,
algorithm=MD5.

QOP Qualidade da proteo


O parmetro qop indica a qualidade da proteo que o cliente aplicou a
mensagem. Se presente este valor deve ser uma das alternativas que o servidor
indicou que suporta no cabealho www-authenticate. Estes valores afetam a
computao do digest. Esta diretiva opcional de forma a preservar a compatibilidade
com uma implantao mnima da RFC2609.
Voc pode configurar o parmetro qop em ambos os comandos
www_challenge(realm,qop) e proxy_challenge(realm, qop). Se configurado para 1,
o servidor ir pedir o parmetro qop. Use sempre qop=1 (habilitado), ele ajuda a evitar
ataques do tipo replay. No entanto alguns clientes podem ser incompatveis com o
qop.

Uma descrio detalhada do processo de autenticao por digest pode ser encontrada
na RFC2617.

Instalando o suporte ao MySQL.


Para permitir a persistncia, em outras palavras, manter as credenciais dos usurios e
lembrar onde esto os usurios, mesmo aps uma re-inicializao, o OpenSER precisa
ser configurado para usar o MySQL. Antes de prosseguir voc deve se certificar que o
MySQL esteja instalado no seu computador.
No captulo trs, ns instalamos o OpenSER com suporte ao MySQL. Verifique no
diretrio /lib/openser/modules pelo modulo mysql.so. Alguma tarefas adicionais se
fazem necessrias para usar o MySQL.
Passo 1: Verificar existncia do modulo mysql.so em /lib/openser/modules
ls /lib/openser/modules/mysql.so

Se o modulo no existir, compile novamente o OpenSER com suporte ao MySQl.

5 | Autenticao com MySQL 68


Passo 2: Crie as tabelas MySQL usando o script openser_mysql.sh.
Este script ir criar as tabelas MySQL com os seguintes parmetros:
DBNAME="openser"
DBHOST="localhost"
DBRWUSER="openser"
DBRWPW="openserrw"
DBROUSER="openserro"
DBROPW="openserro"
DBROOTUSER="root"

Rode o script com a linha de comando abaixo:


cd /usr/sbin
./openser_mysql.sh create

A sada do comando aparece abaixo, bem como as opes usadas


MySQL password for root:
Enter password:
Enter password:
creating database openser ...
Core OpenSER tables succesfully created.
Install presence related tables ?(y/n):y
creating presence tables into openser ...
Presence tables succesfully created.
Install extra tables - imc,cpl,siptrace,domainpolicy ?(y/n):y
creating extra tables into openser ...
Extra tables succesfully created.
Install SERWEB related tables ?(y/n):n
Domain (realm) for the default user 'admin': your-domain.com

Uma senha ser solicitada para acesso ao banco de dados. A senha est vazia neste
momento. O script ir pedir pela senha duas vezes. Pressione <enter> em ambas. O
script ir perguntar por um domnio (realm), informe o seu domnio para o usurio
admin.

Passo 3: Configure o Openser para usar o MySQL. Faa as alteraes destacadas


abaixo (arquivo openser.chapter5-1).
# ------------------ module loading ----------------------------------

#set module path


mpath="//lib/openser/modules/"

# Uncomment this if you want to use SQL database


loadmodule "mysql.so"

loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"

69 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
loadmodule "textops.so"
loadmodule "mi_fifo.so"

# Uncomment this if you want digest authentication


# mysql.so must be loaded !
loadmodule "auth.so"
loadmodule "auth_db.so"
# ----------------- setting module-specific parameters ---------------

# -- mi_fifo params --

modparam("mi_fifo", "fifo_name", "/tmp/openser_fifo")

# -- usrloc params --

#modparam("usrloc", "db_mode", 0)

# Uncomment this if you want to use SQL database


# for persistent storage and comment the previous line
modparam("usrloc", "db_mode", 2)

# -- auth params --
# Uncomment if you are using auth module
#
modparam("auth_db", "calculate_ha1", yes)
#
# If you set "calculate_ha1" parameter to yes (which true in this config),
# uncomment also the following parameter)
#
modparam("auth_db", "password_column", "password")

# -- rr params --
# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)

# ------------------------- request routing logic -------------------


# main routing logic

route{

# initial sanity checks -- messages with


# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};

if (msg:len >= 2048 ) {


sl_send_reply("513", "Message too big");
exit;
};

# we record-route all messages -- to make sure that


# subsequent messages will go through our proxy; that's

5 | Autenticao com MySQL 70


# particularly good if upstream and downstream entities
# use different transport protocol
if (!method=="REGISTER")
record_route();

# subsequent messages withing a dialog should take the


# path determined by record-routing
if (loose_route()) {
# mark routing logic in request
append_hf("P-hint: rr-enforced\r\n");
route(1);
};

if (!uri==myself) {
# mark routing logic in request
append_hf("P-hint: outbound\r\n");
# if you have some interdomain connections via TLS
#if(uri=~"@tls_domain1.net") {
# t_relay("tls:domain1.net");
# exit;
#} else if(uri=~"@tls_domain2.net") {
# t_relay("tls:domain2.net");
# exit;
#}
route(1);
};

# if the request is for other domain use UsrLoc


# (in case, it does not work, use the following command
# with proper names and addresses in it)
if (uri==myself) {

if (method=="REGISTER") {

# Uncomment this if you want to use digest.


if (!www_authorize("", "subscriber")) {
www_challenge("", "0");
exit;
};

save("location");
exit;
};

if (!proxy_authorize("","subscriber")) {
proxy_challenge("","0");
exit;
};

consume_credentials();

lookup("aliases");

71 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
if (!uri==myself) {
append_hf("P-hint: outbound alias\r\n");
route(1);
};

# native SIP destinations are handled using our USRLOC DB


if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
append_hf("P-hint: usrloc applied\r\n");
};

route(1);
}

route[1] {
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
exit;
}

Anlise do arquivo openser.cfg


A nossa configurao j est atendendo a necessidades reais. Agora podemos guardar
os registros de usurios no MySQL que nos habilita a reiniciar o SIP Proxy sem
perder os dados de registro. Isto significa que voc pode reiniciar rapidamente o
OpenSER sem que os clientes sejam afetados.
Outro ponto importante que agora o OpenSER faz autenticao dos usurios. Isto
ocorre em dois momentos. Nas transaes de registro (REGISTER) impedindo que
qualquer um se registre de forma annima. A segunda rea onde aplicada a
autenticao nas transaes INVITE, pois no queremos que usurios sem senha
possam fazer uma chamada. Se permitssemos isto, o SIP Proxy seria chamado de
open-relay. Se o SIP Proxy estiver conectado a um gateway voc pode acabar com
uma conta alta no fim do ms.
loadmodule "mysql.so"
loadmodule "auth.so"
loadmodule "auth_db.so"

O suporte MySQL adicionado facilmente incluindo o mysql.so na lista de mdulos


a serem carregados. O MySQL deve ser carregado antes de todos os outros mdulos.
A razo que o MySQL no tem quaisquer dependncias em outros mdulos,
entretanto outros mdulos como o URI_DB dependem do mdulo MYSQL.
O mdulo AUTH no diretamente usado pelo openser.cfg, entretanto ele
necessrio para habilitar a funcionalidade de autenticao. A funcionalidade de
autenticao neste openser.cfg fornecida pelos mdulos AUTH e AUTH_DB. O

5 | Autenticao com MySQL 72


mdulo AUTH_DB o mdulo que ns podemos invocar diretamente. Este mdulo
inter opera com o AUTH para fazer esta funo.
modparam("auth_db", "calculate_ha1", 1)
modparam("auth_db", "password_column", "password")
modparam("usrloc", "db_mode", 2)

O parmetro calculate_ha1 do mdulo AUTH_DB diz ao OpenSER se ele vai ou no


usar senhas criptografadas na tabela de assinantes. Em um sistema em produo
recomendamos colocar este parmetro em zero (com criptografia), aqui em testes
podemos usar o valor um (sem criptografia).
O mdulo AUTH_DB tem como padro a coluna da senha chamada ha1, entretanto
o esquema do MySQL que o OpenSER usa chama a coluna de senhas de password.
Por isso devemos informar ao OpenSER que o nome da coluna mudou.
O parmetro db_mode do mdulo USRLOC deve ser alterado de zero, usado no
exemplo anterior para 2 neste exemplo. Isto ir dizer ao OpenSER para usar o
MySQL no armazenamento de informaes de contato e dados de autenticao.
if (method=="REGISTER") {
# Uncomment this if you want to use digest auth.
if (!www_authorize("", "subscriber")) {
www_challenge("", "0");
exit;
};

save("location");
exit;

} else if (method=="INVITE") {
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","0");
exit;
};

consume_credentials();
};

No cdigo acima, ns verificamos a autenticao para ambos os mtodos INVITE e


REGISTER. Se o mtodo REGISTER e as credenciais esto corretas, o sistema
salva os dados de localizao deste UAC. O primeiro parmetro especifica o realm
onde o usurio ser autenticado. O realm normalmente o nome do domnio, do host
ou o endereo IP. O segundo parmetro diz ao OPENSER qual tabela MySQL usar.
A linha com a funo www_authorize() usada para verificar as credenciais do
usurio contra os valores armazenados na tabela de assinantes no MySQL. Se as
credenciais estiverem corretas, ento a funo retorna true. O primeiro parmetro
especifica o realm no qual o usurio ser autenticado. Realm pode ser traduzido
como domnio, rea, normalmente o nome do domnio de Internet ou o nome do
host. O segundo valor diz ao OpenSER qual tabela MySQL usada para encontrar as
credencias do usurio.

73 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Se ele no autorizar na primeira linha, mandamos uma mensagem 401
Unauthorized para o cliente SIP que diz a ele para retransmitir o pedido com as
credenciais (digest) includas. O www-challenge() leva dois argumentos. O
primeiro o realm, que ir aparecer no cabealho WWW-Authorize que o
OpenSER envia de volta ao cliente SIP. Se voc colocar um valor aqui ento o realm
ir aparecer para o cliente SIP quando ele for desafiado pelas credenciais. O segundo
valor afeta incluso do parmetro qop no desafio (challenge-request).
recomendado manter em 1 o valor. Veja a RFC2617 para uma descrio completa
deste tipo de autenticao (digest authentication). O segundo valor afeta a incluso do
parmetro qop. Alguns telefones no suportam qop. Voc pode usar 0 se experimentar
problemas de senhas erradas.
consume_credentials();
if (!save("location")) {
sl_reply_error();
};

Se a execuo do openser.cfg chegar nesta linha ento o usurio foi validado contra a
tabela MySQL, ento vamos usar o save(location) na linha 120 para adicionar o
registro do contato do usurio para a tabela de localizao do MySQL. Salvar este
contato permite que voc reinicie com segurana o OPENSER.
As mensagens de INVITE so gerenciadas de forma semelhante s de registro.
Usamos o proxy_authorize para nos certificarmos que no somos um Proxy aberto
(open relay). A funo proxy_authorize() vai exigir que as mensagens de INVITE
tenham credenciais do tipo digest includas no pedido. Se elas estiverem includas a
funo ir tentar valid-las contra a tabela de assinantes (subscriber). Da mesma
forma que a funo www_authorize, a funo proxy_authorize leva dois argumentos, o
primeiro o realm e o segundo a tabela MYSQL.
Se o usurio no se autenticar ento o OPENSER ir enviar um reply 401
Unauthorized.
Como no queremos arriscar enviar as credenciais para frente, removemos quaisquer
cabealhos www-autorize ou proxy-authorize com a funo consume_credentials()

O script openserctl
Openserctl um shell script localizado em /usr/sbin. Ele usado para gerenciar o
OpenSER a partir da linha de comando do Linux. Ele pode ser usado para:
Iniciar, parar e reiniciar o OPENSER.
Dar, revogar e mostrar as ACLs
Adicionar, remover e listar aliases
Adicionar, remover e configurar um AVP.
Gerenciar rotas de menor custo.
Gerenciar o rpid
Adicionar, remover e listar assinantes.
Adicionar, remover e mostra a tabela de localizao in-ram.

5 | Autenticao com MySQL 74


Monitorar o Openser
Aprendermos vrias das suas opes ao longo dos prximos captulos e laboratrios.
debian:/usr/etc/openser# openserctl help
database engine 'MYSQL' loaded
Control engine 'FIFO' loaded
/usr/sbin/openserctl 1.2 - $Revision: 1.3 $
Existing commands:
-- command 'start|stop|restart'

restart ............................ restart OpenSER


start .............................. start OpenSER
stop ............................... stop OpenSER
-- command 'acl' - manage access control lists (acl)

acl show [<username>] .............. show user membership


acl grant <username> <group> ....... grant user membership (*)
acl revoke <username> [<group>] .... grant user membership(s) (*)
-- command 'alias_db' - manage database aliases

alias_db show <alias> .............. show alias details


alias_db list <sip-id> ............. list aliases for uri
alias_db add <alias> <sip-id> ...... add an alias (*)
alias_db rm <alias> ................ remove an alias (*)
alias_db help ...................... help message
- <alias> must be an AoR (username@domain)"
- <sip-id> must be an AoR (username@domain)"
-- command 'avp' - manage AVPs
avp list [-T table] [-u <sip-id|uuid>]
[-a attribute] [-v value] [-t type] ... list AVPs
avp add [-T table] <sip-id|uuid>
<attribute> <type> <value> ............ add AVP (*)
avp rm [-T table] [-u <sip-id|uuid>]
[-a attribute] [-v value] [-t type] ... remove AVP (*)
avp help .................................. help message
- -T - table name
- -u - SIP id or unique id
- -a - AVP name
- -v - AVP value
- -t - AVP name and type (0 (str:str), 1 (str:int),
2 (int:str), 3 (int:int))
- <sip-id> must be an AoR (username@domain)
- <uuid> must be a string but not AoR
-- command 'db' - database operations
db exec <query> ..................... execute SQL query
db show <table> ..................... display table content
-- command 'lcr' - manage least cost routes (lcr)

* lcr *
* IP addresses must be entered in dotted quad format e.g. 1.2.3.4 *
* <uri_scheme> and <transport> must be entered in integer or text,*
* e.g. transport '2' is identical to transport 'tcp'. *
* scheme: 1=sip, 2=sips; transport: 1=udp, 2=tcp, 3=tls *
* Examples: lcr addgw_grp usa 1 *
* lcr addgw level3 1.2.3.4 5080 sip tcp 1 *
* lcr addroute +1 % 1 1 *
lcr show ....................................................................
............. show routes, gateways and groups
lcr reload ..................................................................
............. reload lcr gateways
lcr addgw_grp <grp_name> ....................................................
.............. add gateway group, autocreate grp_id
lcr addgw_grp <grp_name> <grp_id> ...........................................
............... add gateway group with grp_id
lcr rmgw_grp <grp_id> ......................................................
............... delete the gw_grp
lcr addgw <gw_name> <ip> <port> <scheme> <transport> <grp_id> ...............
............... add a gateway
lcr addgw <gw_name> <ip> <port> <scheme> <transport> <grp_id> <prefix> ......
............... add a gateway with prefix
lcr addgw <gw_name> <ip> <port> <scheme> <transport> <grp_id> <prefix> <strip>
............... add a gateway with prefix and strip
lcr rmgw <gw_name> .........................................................

75 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
............... delete a gateway
lcr addroute <prefix> <from> <grp_id> <prio> ................................
.............. add a route
lcr rmroute <prefix> <from> <grp_id> <prio> ................................
.............. delete a route
-- command 'rpid' - manage Remote-Party-ID (RPID)
rpid add <username> <rpid> ......... add rpid for a user (*)
rpid rm <username> ................. set rpid to NULL for a user (*)
rpid show <username> ............... show rpid of a user
-- command 'speeddial' - manage speed dials (short numbers)
speeddial show <speeddial-id> ....... show speeddial details
speeddial list <sip-id> ............. list speeddial for uri
speeddial add <sip-id> <sd-id> <new-uri> [<desc>] ...
........................... add a speedial (*)
speeddial rm <sip-id> <sd-id> ....... remove a speeddial (*)
speeddial help ...................... help message
- <speeddial-id>, <sd-id> must be an AoR (username@domain)
- <sip-id> must be an AoR (username@domain)
- <new-uri> must be a SIP AoR (sip:username@domain)
- <desc> a description for speeddial

-- command 'add|mail|passwd|rm' - manage subscribers


add <username> <password> <email> .. add a new subscriber (*)
passwd <username> <passwd> ......... change user's password (*)
rm <username> ...................... delete a user (*)
mail <username> .................... send an email to a user
-- command 'cisco_restart' - restart CISCO phone (NOTIFY)
cisco_restart <uri> ................ restart phone configured for <uri>
-- command 'online' - dump online users from memory
online ............................. display online users
-- command 'monitor' - show internal status
monitor ............................ show server's internal status
-- command 'ping' - ping a SIP URI (OPTIONS)
ping <uri> ......................... ping <uri> with SIP OPTIONS
-- command 'ul|alias' - manage user location or aliases
ul show [<username>]................ show in-RAM online users
ul rm <username> [<contact URI>].... delete user's UsrLoc entries
ul add <username> <uri> ............ introduce a permanent UrLoc entry
ul add <username> <uri> <expires> .. introduce a temporary UrLoc entry

-- command 'fifo'
fifo ............................... send raw FIFO command

Arquivo de recursos do Openserctl


Na verso 1.1 foi introduzido o arquivo de recursos chamado openserctlrc. Este
script tenta encontrar este arquivo no diretrio /usr/etc/openser.
# $Id: openserctlrc,v 1.2 2006/07/05 19:37:20 miconda Exp $
#
# openser control tool resource file
#
# here you can set variables used in the openserctl

## your SIP domain


SIP_DOMAIN=voffice.com.br

## database type: MYSQL or PGSQL, by defaulte none is loaded

5 | Autenticao com MySQL 76


DBENGINE=MYSQL

## database host
DBHOST=localhost

## database name
DBNAME=openser

## database read/write user


DBRWUSER=openser

## database read only user


DBROUSER=openserro

## password for database read only user


DBROPW=openserro

## database super user


DBROOTUSER="root"

## type of aliases used: DB - database aliases; UL - usrloc aliases


## - default: none
ALIASES_TYPE="DB"

## control engine: FIFO or UNIXSOCK


## - default FIFO
CTLENGINE="FIFO"

## path to FIFO file


OSER_FIFO="FIFO"

## check ACL names; default on (1); off (0)


VERIFY_ACL=1

## ACL names - if VERIFY_ACL is set, only the ACL names from below list
## are accepted
ACL_GROUPS="local ld int voicemail free-pstn"

## verbose - debug purposes - default '0'


VERBOSE=1

## do (1) or don't (0) store plaintext passwords


## in the subscriber table - default '1'
# STORE_PLAINTEXT_PW=0

Este arquivo configure a autenticao do banco de dados e parmetros de


comunicao. Normalmente ele usa o mecanismo conhecido como FIFO para enviar

77 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
comandos ao OpenSER. Ns iremos olhar como a FIFO funciona no prximo
captulo.

Laboratrio: Autenticao.
Passo 1: Faa as mudanas descritas neste captulo ao arquivo openser.cfg.
Passo 2: Reinicialize o openSER usando /etc/init.d/openser restart.

Passo 3: Configure o openserctlrc com os parmetros padro para poder usar o


openserctl.
# $Id: openserctlrc 1827 2007-03-12 15:22:53Z bogdan_iancu $
#
# openser control tool resource file

#
# here you can set variables used in the openserctl

## your SIP domain


SIP_DOMAIN=your-sip-domain

## database type: MYSQL or PGSQL, by defaulte none is loaded


DBENGINE=MYSQL

## database host
DBHOST=localhost

## database name
DBNAME=openser

## database read/write user


DBRWUSER=openser

## database read only user


DBROUSER=openserro

## password for database read only user


DBROPW=openserro

## database super user


DBROOTUSER="root"

## type of aliases used: DB - database aliases; UL - usrloc aliases


## - default: none
ALIASES_TYPE="DB"

## control engine: FIFO or UNIXSOCK


## - default FIFO
CTLENGINE="FIFO"

## path to FIFO file


OSER_FIFO="/tmp/openser_fifo"

## check ACL names; default on (1); off (0)

5 | Autenticao com MySQL 78


VERIFY_ACL=1

## ACL names - if VERIFY_ACL is set, only the ACL names from below list
## are accepted
ACL_GROUPS="local ld int voicemail free-pstn"

## presence of serweb tables - default "no"


HAS_SERWEB="yes"

## verbose - debug purposes - default '0'


VERBOSE=1

## do (1) or don't (0) store plaintext passwords


## in the subscriber table - default '1'
#STORE_PLAINTEXT_PW=0

Passo 4: Antes que voc possa usar esta nova configurao voc deve configurar as
contas de usurio SIP usando o script openserctl. Ns vamos continuar a usar os
usurios 1000 e 1001. No exemplo anterior o OpenSER registrava qualquer usurio,
agora apenas com senhas cadastradas no MySQL. Por isso cadastre os dois usurios
com os seguintes dois comandos.
openserctl add 1000 <password> user1@voffice.com.br
openserctl add 1001 <password> user2@voffice.com.br
(senha: openserrw)
Voc pode remover usurios usando openserctl rm e trocar a senha usando
openserctl passwd. Veja o help do comando para os detalhes de sintaxe.

Passo 5: Use o comando ngrep para jogar as mensagens SIP para um arquivo
ngrep -p -q -W byline port 5060 >registro.pkt

Passo 6: Abra outra janela do terminal e registre os dois telefones usando os nomes e
senhas do passo 4.
Passo 7: Verifique o registro na tabela de localizao usando:
#openserctl ul show

Voc pode adicionar e remover entradas permanentes na tabela de localizao usando


openserctl add e openserctl rm. Veja o help do comando para a sintaxe exata.

Passo 8:Voc pode verificar os usurios online de forma mais simples usando:
#openserctl online

Passo 9: Voc pode pingar via SIP um cliente existente usando:


#openserctl ping 1000

Passo 10: Verifique as mensagens de autorizao no utilitrio ngrep.


Passo 11: Faa uma chamada de um telefone para o outro.
Passo 12: Verifique a autenticao no arquivo registro.pkt
Volte a janela onde o ngrep est rodando e tecle <CTRL-C>
Verifique o arquivo usando:
#pg registro.pkt

79 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Melhorando o script

Chamadas Intra-domain e Inter-domain

ourdomain.com otherdomain.com

Internet

userA.ourdomain.com userB.ourdomain.com userA.otherdomain.com

Ns temos diferentes tipos de chamadas e elas tm de ser gerenciadas de forma


diferente. As chamadas podem ser divididas em:
Chamadas para destinos no mesmo domnio
Chamadas para domnios externos
Chamadas vindas de domnios externos
Eis alguns problemas encontrados no nosso script da forma como est no momento.
Problema #1: Neste momento no estamos verificando a identidade para chamadas de
sada entre domnios. Isto faz do nosso servidor uma porta aberta (open-relay).
Problema #2: Nosso script no aceita uma chamada vinda de outro domnio.
Problema #3 Um usurio pode forjar o campo cabealho FROM em um pedido de
INVITE usando as credenciais de outro usurio.
Problema #4: Um usurio pode forjar o campo TO em um pedido de registro usando
as credenciais de um outro usurio.
Problema #5: Nosso script no est preparado para gerenciar mltiplos domnios.

Gerenciando mltiplos domnios


At agora ns verificamos os pedidos usando a instruo uri==myself. Entretanto,
esta instruo verifica apenas nomes e endereos locais. Se precisamos gerenciar
mltiplos domnios e suas respectivas funes is_from_local() e
is_uri_host_local() temos de usar o mdulo domnio.

Como dito anteriormente o mdulo domain exporta duas funes que sero usadas
neste script. A primeiro is_from_local() que verifica se o campo FROM contm
5 | Autenticao com MySQL 80
um dos domnios gerenciados pelo seu Proxy. A segunda funo,
is_uri_host_local() substitui a instruo uri==myself. A vantagem das funes
exportadas pelo domnio que elas verificam o domnio na tabela DOMAIN no
MySQL. Esta a melhor forma de gerenciar mltiplos domnios na sua
configurao.

Esta funo requer que todos os domnios servidos estejam inseridos no banco
de dados. Um erro bastante comum para os usurios deste material esquecer
de inserir o domnio na tabela MySQL antes de registrar os telefones.

Rotas alternativas
Para simplificar nosso script vamos criar vrias rotas alternativas. Temos visto que o
script pode se tornar bastante complexo e confuso. Para evitar isto vamos criar rotas
alternativas que funcionam de forma semelhante a sub-rotinas. O uso de rotas
alternativas permite separar certas partes do cdigo e melhorar e legibilidade.

Pedidos do tipo REGISTER


Uma rota de registro responsvel por gerenciar todos os pedidos do tipo
REGISTER. O cdigo autentica o usurio e salva a localizao do UAC na sua tabela
no script abaixo.
route[2] {
#
# -- Register request handler --
#
if (is_uri_host_local()) {
if (!www_authorize("", "subscriber")) {
www_challenge("", "1");
exit;
};
if (!check_to()) {
sl_send_reply("401", "Unauthorized");
exit;
};
save("location");
exit;
} else if {
sl_send_reply("401", "Unauthorized");
};
}

Pedidos diferentes de REGISTER route[3]


A rota de pedidos diferentes de REGISTER gerencia todas as outras requisies.
Novamente os pedidos precisam ser autenticados. Ns decidimos separar os pedidos
em:
Entre domnios internos (route[10])
De um domnio interno para um externo (route[11])
81 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
De um domnio externo para um interno (route[12])
Entre domnios internos (route[13])
Normalmente voc permitir pedidos entre domnios internos com autenticao. As
rotas onze (11) e doze (12) so usadas para gerenciar requisies de chamadas entre
domnios. A maioria dos provedores de voz no permite comunicaes entre
domnios, porque elas podem potencialmente reduzir a sua receita. Chamadas de for a
para for a raramente so permitidas. Na maioria dos casos elas so consideradas um
furo de segurana.
route[3] {
#
# -- non-register requests handler --
#

# Verify the source (FROM)


if (is_from_local()){
# From an internal domain -> check the credentials and the FROM
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","1");
exit;
} else if (!check_from()) {
sl_send_reply("403", "Forbidden, use From=ID");
exit;
};
consume_credentials();

# Verify aliases
lookup("aliases");

# Verify the destination (URI)


if (is_uri_host_local()) {
# -- Inbound to Inbound
route(10);
} else {
# -- Inbound to outbound
route(11);
};

} else {

#Verify aliases, if found replace R-URI.


lookup("aliases");

# Verify the destination (URI)


if (is_uri_host_local()) {
#-- Outbound to inbound
route(12);
} else {
# -- Outbound to outbound
route(13);
};
};
}

5 | Autenticao com MySQL 82


Gerenciando chamadas do mesmo domnio
Nosso script openser.cfg agora est diferenciando chamadas pela fonte e destino. Ele
determina o destino usando a funo if(is_uri_host_local()) e a fonte usando
if(is_from_local()).

Para chamadas originadas por domnios internos, ns iremos primeiro verificar a


identidade e remover as credenciais para evitar envi-las a frente. Ns iremos resolver
quaisquer Aliases definidos antes, verificando o destino antes de encaminhar o pedido
Se a chamada destinada a um dos domnios gerenciados pelo nosso Proxy
(verificado usando is_uri_host_local()) ns iremos envi-lo para a rota 10, seno, se
destinado a um domnio externo, usaremos a rota 11.

Inbound to Inbound route[10]

Rotas internas sero geridas pela tabela de localizao armazenada na base de dados
MySQL.
route[10] {
#from an internal domain -> inbound
#Native SIP destinations are handled using the location table
append_hf("P-hint: inbound->inbound \r\n");
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

Inbound to Outbound route[11]

Ns iremos rotear chamadas para destinos externos usando uma busca ao DNS.
route[11] {
# from an internal domain -> outbound
# Simply route the call outbound using DNS search
append_hf("P-hint: inbound->outbound \r\n");
route(1);
}

Outbound to Inbound route[12]

Ns iremos permitir chamadas de domnios externos para nossos telefones. Esta


configurao permite ligaes de SPAM atravs de SIP para nossos telefones. No
entanto, no momento em que eu estou escrevendo este material, esta no uma
prtica comum. Eu acredito que hoje os benefcios so maiores que os riscos, no
futuro ningum sabe. Parece-me lgico abrir e receber chamadas da mesma forma que
ns recebemos chamadas nos nossos telefones vindas de qualquer parte e tambm
estamos abertos a receber e-mails de qualquer pessoa.
route[12] {
# From an external domain -> inbound

83 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
# Verify aliases, if found replace R-URI.
lookup("aliases");
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

Outbound to Outbound route[13]

Ns no queremos encaminha mensagens externas como um relay aberto. Algum


poderia usar nosso Proxy para encaminhar uma chamada anonimamente se esta
configurao no fosse feita.
route[13] {
#From an external domain outbound
#we are not accepting these calls
sl_send_reply("403", "Forbidden");
exit;
}

As funes check_to() e check_from()


Quando voc opera um SIP Proxy, voc deve garantir que uma conta vlida no ser
usada por usurios no autenticados. As funes check_to() e check_from() so
usadas para mapear os usurios SIP com o usurio da autenticao.O usurio SIP est
no campo FROM e TO , mas o usurio autenticado, auth user encontrado no
campo Authorize que usado no processo de autenticao. No exemplo atual, a
funo verifica que um usurio do campo FROM ou TO o mesmo do campo auth
user encontrado no cabealho Authorize. Isto feito para evitar que um usurio use a
autenticao de outro usurio. Estas funes so habilitadas pelo mdulo URI_DB.

Usando Aliases
Em alguns casos voc vai querer permitir que um usurio tenha vrios endereos, tais
como um nmero de telefone associado ao seu endereo principal. Voc pode usar os
Aliases para este propsito.
Para adicionar um alias, voc pode usar:
#openserctl alias add 1000@8.8.30.49 flavio@8.8.30.49
database engine 'MYSQL' loaded
Control engine 'FIFO' loaded
MySql password for user 'openser@localhost':
Para processar um alias dentro de um script use:
lookup(aliases);

Esta funo ir traduzir o alias para a forma cannica da URI. Em alguns casos o
Alias pode ser resolvido para um domnio externo. Este condio deve ser tratada de
acordo com as regras previamente estabelecidas. .

5 | Autenticao com MySQL 84


Tratando pedidos do tipo CANCEL e re-transmisses.
Os pedidos de cancelamento de acordo com a RFC3261 precisam ser roteados da
mesma forma que os pedidos de INVITE. O script abaixo verifica se o pedido de
CANCEL bate com alguma transao existente. Se a transao existe, a funo
t_check_trans() ir tratar automaticamente o pedido e encerrar o script.
#CANCEL processing
if (is_method("CANCEL"))
{
if (t_check_trans())
t_relay();
exit;
}

t_check_trans();

Script completo com todos os recursos acima.


Abaixo o script completo com todas as modificaes.
------------------ module loading ----------------------------------

#set module path


mpath="//lib/openser/modules/"

# Uncomment this if you want to use SQL database


loadmodule "mysql.so"

loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "mi_fifo.so"
loadmodule "uri.so"
loadmodule "uri_db.so"
loadmodule "domain.so"

# Uncomment this if you want digest authentication


# mysql.so must be loaded !
loadmodule "auth.so"
loadmodule "auth_db.so"
# ----------------- setting module-specific parameters ---------------

# -- mi_fifo params --

modparam("mi_fifo", "fifo_name", "/tmp/openser_fifo")

# -- usrloc params --

85 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
#modparam("usrloc", "db_mode", 0)

# Uncomment this if you want to use SQL database


# for persistent storage and comment the previous line
modparam("usrloc", "db_mode", 2)

# -- auth params --
# Uncomment if you are using auth module
#
modparam("auth_db", "calculate_ha1", 0)
#
# If you set "calculate_ha1" parameter to yes,
# uncomment also the following parameter)
#
#modparam("auth_db", "password_column", "password")

# -- rr params --
# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)

# ------------------------- request routing logic -------------------


# main routing logic

route{
# initial sanity checks -- messages with
# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};

if (msg:len >= 2048 ) {


sl_send_reply("513", "Message too big");
exit;
};

# we record-route all messages -- to make sure that


# subsequent messages will go through our proxy; that's
# particularly good if upstream and downstream entities
# use different transport protocol
if (!method=="REGISTER")
record_route();

# subsequent messages withing a dialog should take the


# path determined by record-routing
if (loose_route()) {
# mark routing logic in request
append_hf("P-hint: rr-enforced\r\n");
route(1);
};

#CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans()) t_relay();

5 | Autenticao com MySQL 86


exit;
}

t_check_trans();

if (method=="REGISTER") {
route(2);
} else {
route(3);
};
}

route[1] {
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
exit;
}

route[2] {
#
# -- Register request handler --
#
if (is_uri_host_local()) {
if (!www_authorize("", "subscriber")) {
www_challenge("", "1");
exit;
};

if (!check_to()) {
sl_send_reply("40=3", "Forbidden");
exit;
};

save("location");
exit;
} else if {
sl_send_reply("403", "Forbidden");
};
}

route[3] {
#
# -- INVITE request handler --
#
if (is_from_local()){
# From an internal domain -> check the credentials and the
FROM
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","1");
exit;

87 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
} else if (!check_from()) {
sl_send_reply("403", "Forbidden, use From=ID");
exit;
};

consume_credentials();

# Verify aliases
lookup("aliases");

if (is_uri_host_local()) {
# -- Inbound to Inbound
route(10);
} else {
# -- Inbound to outbound
route(11);
};
} else {
# From an external domain -> do not check credentials
#Verify aliases, if found replace R-URI.
lookup("aliases");
if (is_uri_host_local()) {
#-- Outbound to inbound
route(12);
} else {
# -- Outbound to outbound
route(13);
};
};
}

route[10] {
#from an internal domain -> inbound
#Native SIP destinations are handled using the location table
append_hf("P-hint: inbound->inbound \r\n");
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

route[11] {
# from an internal domain -> outbound
# Simply route the call outbound using DNS search
append_hf("P-hint: inbound->outbound \r\n");
route(1);
}

route[12] {
# From an external domain -> inbound
# Verify aliases, if found replace R-URI.
lookup("aliases");
if (!lookup("location")) {

5 | Autenticao com MySQL 88


sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

route[13] {
#From an external domain outbound
#we are not accepting these calls
append_hf("P-hint: outbound->inbound \r\n");
sl_send_reply("403", "Forbidden");
exit;
}

Melhorando a segurana
Passo 1: Tente registrar o seu telefone com a nova configurao. Voc,
provavelmente, vai perceber um erro no registro do seu telefone.
Passo 2: A configurao acima agora usa o mdulo DOMAIN. Com isto preciso que
todos os domnios servidos estejam cadastrados no banco de dados.
#mysql
Mysql> use openser
mysql> insert into domain (domain) VALUES(seuendereoip");
mysql> insert into domain (domain) VALUES(seudominio);
Passo 3: Tente novamente registrar o telefone. Voc vai ver agora que o registro se
completa.

Aliases
Passo 1: Adicione um alias ao assinante 1000
#openserctl alias add john@seuendereoip sip:1000@seuenderecoip
database engine 'MYSQL' loaded
Control engine 'FIFO' loaded
MySql password for user 'openser@localhost':
Obs: Use openserrw como senha.
Passo 2: Do softfone registrado como 1001 disque john.
A chamada foi completada?
Porque?

Sumario
Neste captulo voc aprendeu como integrar o MySQL com o OpenSER. Agora nosso
script est autenticando usurios, checando os campos TO e FROM e gerenciando
adequadamente as chamadas de entrada e sada. importante lembrar que os
domnios agora tem de ser inseridos no banco de dados, por causa do suporte
mltiplos domnios. Se voc mudar o seu domnio ou endereo IP, lembre-se de
atualizar o seu banco de dados.

89 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
5 | Autenticao com MySQL 90
6
Portal de usurios com
serMyAdmin

No ltimo captulo ns implantamos a autenticao usando uma base de dados


MySQL. Agora, ns vamos precisar de uma ferramenta para nos ajudar a administrar
o OpenSER. Esta ferramenta, claro, deve ser mais simples que o openserctl. O
serMyAdmin foi criado especificamente para ajudar voc a construir o portal de
usurios. Nosso objetivo foi substituir a antiga ferramenta SerWEB que deixou de
operar a partir da verso 1.1 do OpenSER.
No final deste captulo voc deve estar apto ;
Identificar porque voc precisa de um portal para administrao dos
usurios
Instalar o serMyAdmin e suas dependncias
Configurar recursos como acesso usurio e administrador
Adicionar e remover domnios
Customizar o portal com as cores e logos de sua empresa

SerMyAdmin
Originalmente, este material foi escrito para o SerWEB que foi originalmente
desenvolvido para o projeto SER. Infelizmente, o SerWEB se tornou incompatvel
com verses mais recentes do OpenSER (a partir da 1.2). Outro aspecto importante do
SerWEB a ser considerado so suas vulnerabilidades. Existem algumas opes de
interfaces Web para o OpenSER. Uma destas ferramentas, desenvolvida em Ruby in
Rails, o OpenSER Administrator. Pareceu-me uma boa ferramenta para administrar
o OpenSER, no entanto faltava o suporte multi-domnio e o provisionamento de
usurios que j existiam no SerWEB. O OpenSER Admin pode ser encontrado no
endereo URL http://sourceforge.net/projects/openseradmin.
Sem uma ferramenta para construir um portal de usurios para o OpenSER, decidimos
desenvolver uma ferramenta prpria chamada serMyAdmin usando Java. Aps um
comeo tortuoso, ela agora est na sua primeira verso beta e ns estamos usando
para este livro. Desenvolvida em Grails (Groovy on Rails) ela pode ser descarregada
em http://sourceforge.net/projects/sermyadmin.
O projeto SerMyAdmin pode ser encontrado em http://sermyadmin.sourceforge.net
A idia facilitar a administrao da base de dados OpenSER. O SerMyAdmin
licenciado de acordo com a licena GPL v2.
Instalando o SerMyAdmin
O serMyAdmin usa o framework Grails. Para isto ser necessrio instalar um servidor
de aplicaes como o IBM Websphere, JBOSS, Jetty ou Tomcat. Neste material
vamos usar o Apache Tomcat porque ele gratuito e fcil de instalar. Como usamos
alguns recursos do Java 1.5, vamos precisar do JDK da Sun Microsystyems e no da
alternativa gratuita chamada GCJ.
Passo 1: Crie um administrador para o serMyAdmin
mysql u root
use openserINSERT INTO `subscriber` ( `id` , `username` , `domain` ,
`password` , `first_name` , `last_name` , `email_address` ,
`datetime_created` , `ha1` , `ha1b` , `timezone` , `rpid` , `version` ,
`password_hash` , `auth_username` , `class` , `domain_id` , `role_id`
)VALUES (NULL , 'admin', 'openser.org', 'senha', 'Admin', 'Admin',
'admin@openser.org', '0000-00-00 00:00:00', '1', '1', '1', '1', '1', NULL
, 'admin@openser.org', NULL , '1', '3');

Passo 2: O primeiro passo atualizar a lista de fonts para usar os pacotes do tipo
contrib., e non-free. O arquivo /etc/apt/sources.list deve ficar como mostrado abaixo.
# /etc/apt/souces.list
deb http://ftp.br.debian.org/debian/ etch main contrib non-free
deb-src http://ftp.br.debian.org/debian/ etch main contrib non-free
deb http://security.debian.org/ etch/updates main contrib non-free
deb-src http://security.debian.org/ etch/updates main contrib non-free
/etc/apt/sources.list
Note que ns adicionamos apenas as palavras chave contrib e non-free aps as nossas
definies de repositrio.
Passo 3: Atualize a lista de pacotes usando o seguinte comando:
openser:~# apt-get update

6 | Portal de usurios com serMyAdmin 92


Passo 4: Instale o Java 1.5 da Sun, executando o seguinte comando:
openser:~# aptitude install sun-java5-jdk
Passo 5; Certifique-se de estar usando o Java da Sun. Rode o comando abaixo para
dizer ao Debian que voc quer o java da Sun como sua implementao padro de Java
openser:~# update-java-alternatives -s java-1.5.0-sun
Passo 6: Se tudo correu bem, ao rodar o comando abaixo, voc deve receber uma
resposta semelhante.
openser:~# java -version
java version "1.5.0_14"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03)
Java HotSpot(TM) Client VM (build 1.5.0_14-b03, mixed mode, sharing)
Passo 7: Instale o Tomcat. Voc pode obter o Tomcat em
http://tomcat.apache.org/download-60.cgi. Para instalar o Tomcat, execute os
comandos abaixo.
openser:/usr/local/etc/openser# cd /usr/local
openser:/usr/local# wget http://mirrors.uol.com.br/pub/apache/tomcat/tomcat-
6/v6.0.16/bin/apache-tomcat-6.0.16.tar.gz
openser:/usr/local# tar zxvf apache-tomcat-6.0.16.tar.gz
openser:/usr/local# ln -s apache-tomcat-6.0.16 tomcat6
Passo 8: Para iniciar o Tomcat na inicializao do servidor, copie o script abaixo para
/etc/init.d/tomcat6.
#! /bin/sh e
#### BEGIN INIT INFO
# Provides: Apache's Tomcat 6.0
# Required-Start: $local_fs $remote_fs $network
# Required-Stop: $local_fs $remote_fs $network
# Default-Start: 2345
# Default-Stop: S016
# Short-Description: Tomcat 6.0 Servlet engine
# Description: Apache's Tomcat Servlet Engine
### END INIT INFO
#
# Author: Guilherme Loch Ges <glwgoes@gmail.com>
#
set -e

93 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
PATH=/bin:/usr/bin:/sbin:/usr/sbin:
CATALINA_HOME=/usr/local/tomcat6
CATALINA_BIN=$CATALINA_HOME/bin

test -x $DAEMON || exit 0

. /lib/lsb/init-functions

case "$1" in
start)
log_daemon_msg "Starting Tomcat 6" "Tomcat6"
$CATALINA_BIN/startup.sh
log_end_msg $?
;;
stop)
log_daemon_msg "Stopping Tomcat6" "Tomcat6"
$CATALINA_BIN/shutdown.sh
log_end_msg $?
;;
force-reload|restart)
$0 stop
$0 start
;;
*)
echo "Usage: /etc/init.d/tomcat6 {start|stop|restart}"
exit 1
;;
esac

exit 0
Passo 9: Instrua o Debian para executar este script na inicializao da mquina
usando:
openser:/etc/init.d# update-rc.d tomcat6 defaults 99

6 | Portal de usurios com serMyAdmin 94


Passo 10: Para certificar-se de que tudo est em perfeita ordem, reinicialize o servidor
e tente abrir o browser no endereo http://localhost:8080. Se tudo estiver correto, voc
ver a pgina de abertura do Tomcat.
Passo 11: Instale o driver MySQL para o Tomcat, de forma que o serMyAdmin para
permitir que o SerMyAdmin acesse a base de dados. O driver pode ser encontrado em
http://dev.mysql.com/downloads/connector/j/5.1.html. Descarregue e descompacte o
driver no diretrio compartilhado como explicado abaixo:
openser:/usr/src# tar zxf mysql-connector-java-5.1.5.tar.gz
openser:/usr/src# cp mysql-connector-java-5.1.5/mysql-connector-java-5.1.5-
bin.jar /usr/local/tomcat6/lib
Passo 12: Declare a fonte de dados do SerMyAdmin para conectar-se a base de dados
do OpenSER. Voc pode fazer isto no arquivo XML
/usr/local/tomcat6/conf/context.xml. O arquivo deve ficar como mostrado abaixo.
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/serMyAdmin">
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver"
maxActive="20" maxIdle="10" maxWait="-1" name="jdbc/openser_MySQL"
type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/openser"
username="sermyadmin" password="secret"/>
</Context>
No arquivo acima, por favor mude os parmetros em negrito de acordo com o seu
cenrio. O serMyAdmin pode ser instalado em um servidor diferente do servidor que
mantm a base de dados. Se puder, separe os servidores para obter uma melhor
escalabilidade. A instalao padro do MySQL no Debian aceita somente acesso do
localhost, se voc precisar de acesso atravs da rede, vai ter de alterar o arquivo
/etc/mysql/my.cnf. Consulte um especialista em banco de dados para ajud-lo com a
configurao do banco.
Passo 13: Crie um usurio para ser referenciado no arquivo context.xml.Este usurio
deve ter acesso ao banco de dados. Rode os comandos abaixo.
openser:/var/lib/tomcat5.5/conf# mysql -u root p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 5.0.32-Debian_7etch5-log Debian etch distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> grant all privileges on openser.* to sermyadmin@'%' identified by


'secret';

95 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Query OK, 0 rows affected (0.00 sec)
Passo 14: Estamos quase l. O prximo passo copiar o arquivo SerMyAdmin.war.
Por favor, descarregue e copie o arquivo sermyadmin.war para o diretrio de
aplicaes do Tomcat. Reinicie o Tomcat para ativar as mudanas.
openser:/usr/src# cp serMyAdmin-0.3.8.war
/usr/local/tomcat6/webapps/serMyAdmin.war
openser:/usr/src# invoke-rc.d tomcat6 restart
No se preocupe com as modificaes na base de dados, O SerMyAdmin ir
automagicamente faz-las por voc.
Passo 15: Configure o MTA do debian para permitir que o SerMyAdmin envie um e-
mail de confirmao para novos usurios. Rode o comando abaixo para configurar o
Exim4 (MTA padro do Debian). Pea ajuda ao administrador do e-mail da empresa
se necessrio.
Openser:/# aptitude install exim4
openser:/# dpkg-reconfigure exim4-config
Voc vai receber uma interface de configurao por menus. Neste menu importante
prestar ateno a duas opes: General type of mail configuration, que deve estar
como Internet Site de forma que possamos enviar e receber e-mail diretamente
atravs do protocolo SMTP. e Domains to relay mail for, que deve ser configurado
para o domnio do qual voc quer que os e-mails originem.
O primeiro parmetro a mudar o servidor que ns iremos usar para enviar e-mails.
Seguindo est o parmetro que indica de qual remetente os e-mails vo sair.
Passo 16: Personalize o arquivo /usr/local/apache-tomcat-
6.0.16/webapps/serMyAdmin-0.3/WEB-INF/spring/context.xml, o qual contm
parmetros que dizem qual servidor de e-mail ir enviar e-mails e de onde os e-mails
vo parecer vir. Abaixo, voc encontrar um exemplo do arquivo.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<bean id="mailSender"
class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host"><value>localhost</value></property>
</bean>

<!-- You can set default email bean properties here, eg: from/to/subject -->

6 | Portal de usurios com serMyAdmin 96


<bean id="mailMessage"
class="org.springframework.mail.SimpleMailMessage">
<property
name="from"><value>admin@sermyadmin.org</value></property>
</bean>

</beans>
Passo 17: Crie o administrador na base de dados
cd /usr/src
wget http://www.sermyadmin.org/openser/openser.sql
mysql -u root openser <openser.sql

Passo 18: Aponte o seu browser para o endereo http://<endereo do


servidor>:8080/serMyAdmin. Voc ver uma pgina de login semelhante a do incio
deste captulo.
username: admin@setup
password: secret
Passo 19: Todos os seus usurios existentes migraram para o domnio Setup. Por
favor, altere para o domnio apropriado.
Reinicie o Tomcat novamente e estamos prontos para comear. Quando voc apontar
o seu browser para http://<server address>:8080/serMyAdmin, voc deve receber a
pgina de login.

Tarefas bsicas
Voc pode usar o serMyAdmin para uma srie de tarefas. Neste captulo, ns iremos
apresent-lo como criar e administrar novos usurios e grupos. Nos prximos
captulos ns iremos usar o serMyAmin para outras tarefas, tais como gerenciar a
tabela de confiana e o mdulo LCR.

Registrando um novo usurio

Para registrar um novo usurio, na tela de login, simplesmente click no boto de


registro.

97 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Preencha os campos, username, password, domain, e-mail, first name, last name,
caller id e confirmation code. Pressione o boto create no fim da tela. O usurio ser
adicionado a base de dados. Ambos, o administrador do sistema e o usurio iro
receber um e-mail sobre o registro. Antes que o usurio possa comear a ligar, o
administrador deve aprov-lo.

Aprovando um novo usurio.

Siga o procedimento abaixo para aprovar um novo usurio.


Passo 1: Faa o login com a conta admin@localhost, senha openserrw criada durante a
instalao do OpenSER. O processo de instalao criou um novo atributo Role para
cada um dos usurios. O propsito deste campo diferenciar usurios normais de
administradores de domnio e administradores globais. O usurio admin j foi
automaticamente colocado como Global Administrator. Este novo campo vai nos
ajudar com o suporte de mltiplos domnios, essencial na operao com revendas.
Passo 2: Selecione o item do menu Registered Users.

6 | Portal de usurios com serMyAdmin 98


Na tela acima, selecione os usurios que voc quer adicionar e clique na caixa Approve.
O usurio ser removido da tabela register_user e movido para a tabela subscriber.
Aps isto ele estar apto a se registrar e fazer chamadas.

Passo 3: Verifique a insero de usurios na base de dados selecionando o item do


menu chamado Users. Os usurios agora devem aparecer na lista de assinantes.

Gerencia de usurios

Voc pode ver, adicionar, editar e deletar usurios no menu usurios. Quando voc
clica nele, ter todos os usurios sendo mostrados.

99 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que


pretende que aparea aqui.
Para adicionar um novo usurio, voc deve clicar no link New User. Voc ser
direcionado para a pgina abaixo, nela voc deve completar os campos e clicar no link
Create. Com isto o usurio ser adicionado diretamente base de dados. A seguinte
pgina ser mostrada aps o processo.

Nesta pgina, voc pode modificar as informaes inseridas clicando em Edit, ou


apagar o usurio clicando em Delete.
Na pgina User List voc pode pesquisar usurios baseado no nome do usurio,
domnio e e-mail. Clique no link Search e preencha apenas o critrio desejado. A
ttulo de exemplo, na pgina seguinte, ns iremos pesquisar por todos os usurios com
o nome de usurio jdoe. Clique pesquisar e voc ser direcionado a uma lista de
usurios que atende o seu critrio.

6 | Portal de usurios com serMyAdmin 100


Gerenciamento de domnios
Voc pode gerenciar seus domnios da mesma forma que gerencia seus usurios.
Clique em domnios para obter uma lista de domnios. L voc pode adicionar um
novo domnio, apagar um domnio existente e assim por diante. importante notar
que o serMyAdmin no permite que um usurio exista sem um domnio, de forma que
se voc deletar o domnio, deletar todos os usurios pertencentes quele domnio.

Customizao de interface
Para o layout da pgina web, o serMyAdmin usa um framework do tipo sitemesh, de
forma a tornar o processo de customizao da pgina bem simples. Sitemesh mostra
as pginas baseado em uma mscara encontrada em openser:/usr/local/apache-
tomcat-6.0.16/webapps/serMyAdmin-0.3/WEB-INF/grails-app/views/layouts. L,
voc ir encontrar os arquivos main.gsp e notLoggedin.gsp, estes arquivos so
pginas do servidor Groovy que controlam como as pginas so exibidas.
O Sitemesh usa metatags HTML para escolher que layout usar. Estas tags devem ser
colocadas entre os cabealhos <HEAD> de cada pgina. Se a pgina tiver um tag
<meta content="main" name="layout"/> dentro do tag, o sitemash ir usar o layout
main.gsp para mostr-la.
Voc pode mudar o main.gsp e o notLoggedin.gsp da forma que desejar, mas
importante entender que <g:layoutHead /> and <g:layoutBody /> iro manter os tags
HEAD and BODY das pginas usando este layout. Outra coisa importante saber que
o <g:render template="/menu" /> usado para construir os fragmentos de pgina que
so os arquivos GSP a seu nome de arquivo deve comear com um underscore (_).
Para substituir o logo do SerMyAdmin pelo seu. Coloque seu logo em
/usr/local/apache-tomcat-6.0.16/webapps/serMyAdmin-0.3/images, e edite os tags
que apontam para logo_voffice.png nos arquivos de layout. Como mostrado abaixo.
<div class="logo"><img
src="${createLinkTo(dir:'images',file:'my_new_logo.png')}" alt="Grails"
/></div>
No tag acima, ns trocamos o logo do serMyAdmin, trocando apenas o que est em
negrito.
Voc pode tambm mudar o look and feel do serMyAdmin modificando seu arquivo
CSS que podem ser encontradosem /usr/local/apache-tomcat-
6.0.16/webapps/serMyAdmin-0.3/css, no arquivo main.css voc encontrar todas as
classes para gerenciar a aparncia do serMyAdmin.
Por exemplo, se ns trocamos a classe background neste arquivo com os seguintes
parmetros.
body {
background: #00f;
color: #333;
font: 8px verdana, arial, helvetica, sans-serif;
}

101 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Ficamos com uma pgina como esta.

A pgina no a coisa mais bonita do planeta, mas estou certo de que voc pode fazer
bem melhor usando estes conceitos.

Sumrio
Neste captulo, voc aprendeu porque importante ter um portal de administrao.
um ponto onde voc vai ter de investir muitos recursos ao criar um provedor. Vrios
provedores esquecem-se de alocar tempo e recursos na construo do portal de
usurios dando toda importncia ao SIP Proxy. No entanto o SIP Proxy apenas um
dos componentes do provedor. Sem uma boa interface de administrao, um provedor
VoIP pode facilmente naufragar. serMyAdmin nossa contribuio ao projeto.
Desenvolvido usando Java e Groovy on Rails ele licenciado de acordo com a licena
GNU GPL. Voc aprendeu tambm como instalar, gerenciar usurios e domnios e
como customizar a aparncia. A ferramenta pode fazer muito mais e vamos mostrar
um pouco mais nos prximos captulos.

6 | Portal de usurios com serMyAdmin 102


7
Conectividade com a rede
pblica

No ltimo captulo ns preparamos o OpenSER para autenticar as chamadas usando o


MySQL. No entanto, nosso Proxy ainda no se comunica com a rede pblica. O
objetivo deste captulo permitir a conexo com a rede pblica para entrada e sada
de chamadas. At agora estivemos focados apenas em chamadas SIP, o que significa
que voc pode apenas enviar e receber chamadas entre telefones IP no seu SIP Proxy
ou para outros SIP Proxies. Em alguns casos os usurios vo querer fazer chamadas
para a rede pblica. Isto na arquitetura SIP feito por um PSTN Gateway.

Da rede IP para a rede pblica

Rede Pblica
PSTN
(Operadora)
Telefone
Dispositivo comum
Gateway
SIP Proxy
Server

Da rede pblica para a rede IP


Rede Pblica
PSTN
(Operadora)
Telefone
Dispositivo comum
Gateway
SIP Proxy
Server

Existem vrios fabricantes deste tipo de equipamento no mercado tais como a Cisco
Systems, AudioCodes e Nortel. O Asterisk tambm permite a criao de um bom
gateway PSTN usando entroncamento analgico ou digital.
Ao final deste captulo voc estar apto :
Conectar-se a rede pblica atravs de um gateway que suporte SIP
Controlar o acesso aos recursos do gateway
Controlar as permisses usando groups
Usar o mdulo LCR para controlar os gateways
Usar o serMyAdmin para gerenciar as mquinas autorizadas, gateways e rotas

Onde estamos?
Uma soluo de um provedor VoIP possui muitos componentes. Para evitar perder a
perspectiva, ns iremos mostrar esta figura em cada captulo. Neste captulo ns
estamos trabalhando com o componente chamado SIP Proxy. Trabalhando junto com
um gateway para a rede pblica.

The SIP provider MySQL/Postgres/


Big Picture Unixodbc Database

Ethernet

Media
User Radius
SIP PSTN Media Proxy CDRTool Monitoring
Portal Server Tools
Proxy Gateway Server Nat Rating
Provis. Traversal Acct.

Ethernet

CPE device (router)


Usually xDSL or
Cable
Internet Firewall
Customer Customer
Using an ATA Firewall
or Softphone

Neste captulo aprenderemos sobre uma srie de novos mdulos do OPENSER como
o GROUP e PERMISSIONS e tambm a construir expresses regulares que vo
permitir o roteamento das chamadas. No difcil encontrar um bom tutorial sobre
expresses regulares. Um carto de referncia rpida pode ser encontrado em:
http://www.visibone.com/regular-expressions. Temos dois desafios a serem vencidos
nesta configurao. Tratar as mensagens vindas do gateway e para o gateway.

Mensagens enviadas para o gateway


Nos pedidos enviados para os gateways, ns temos de verificar a que grupo um
usurio pertence. Isto vai nos dizer se ele est ou no autorizado para usar a PSTN.

7 | Conectividade com a rede pblica 104


if (uri=~"^sip:0[0-9]{8}@") {
if (is_user_in("credentials","local")) {
route(5);
exit;
} else {
sl_send_reply("403", "Sem perm. para lig. locais");
exit;
};
};
if (uri=~"^sip:00[1-9][1-9][0-9]{12}@") {
if (is_user_in("credentials","ld")) {
route(5);
exit;
} else {
sl_send_reply("403", "Sem perm. para longa distancia");
exit;
};
};
if (uri=~"^sip:000[1-9][1-9][0-9]*@") {
if (is_user_in("credentials","int")) {
route(5);
exit;
} else {
sl_send_reply("403", "Sem perm. para internacional");
};
};

Para isto vamos usar o mdulo GROUP. Este mdulo exporta a funo
is_user_in(credentials, grupo) para verificar se o usurio pertence ou no
um determinado grupo. No exemplo abaixo criamos trs grupos local, para ligaes
locais, ld para ligaes de longa distncia e int para ligaes internacionais. No
script abaixo usamos expresses regulares para verificar se as mensagens so locais,
longa distncia ou internacionais.
Voc tem de inserir os grupos na tabela MySQL antes de us-los. Voc pode
facilmente inserir, remover e mostrar os membros de um grupo usando:
openserctl acl show [<username>]
openserctl acl grant <username> <group>
openserctl acl revoke <username> [<group>]
possvel tambm gerenciar suas tabelas usando o SerMyAdmin. Para adicionar e
remover grupos, voc pode usar a seo User Groups. L. voc pode adicionar e
deletar grupos.

Para mudar um usurio de um grupo para outro, voc pode ir para o menu de usurio
mostrado aqui.

105 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Marque as caixas para selecionar os grupos especficos ao qual o usurio pertence.

Mensagens vindas do gateway


Agora. Ns vamos usar o mdulo PERMISSIONS para autorizar as chamadas
vindas do gateway sem usar o processo de autenticao por digest.

Trfego vindo do gateway

if (!allow_trusted()) {
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","0");
exit;
} else if (!check_from()) {
sl_send_reply("403", "Use From=ID");
exit;
};
};

A funo allow_trusted que vamos usar exportada pelo mdulo PERMISSIONS.


O mdulo PERMISSIONS pode ser usado ainda para autorizar pedidos de Registro,
REFER e INVITE. Ele pode ser regulado por arquivos texto como
permissions.allow, permissions.deny, register.allow, register.deny. No entanto a
funo allow_truted() que vamos usar verifica a tabela TRUSTED do banco de
dados em relao ao endereo IP de envio.
Quando a funo allow_trusted() chamada, ela tenta encontrar uma regra que
corresponde ao pedido. As regras contm os seguintes campos: <endereo fonte>,
<protocolo de transporte>, <expresso regular>.

7 | Conectividade com a rede pblica 106


Um pedido aceito se existir uma regra, onde:
O endereo fonte igual ao endereo fonte do pedido
O protocolo de transporte ou any ou igual ao protocolo de transporte do
pedido.
A expresso regular ou vazia ou bate com a URI do pedido.
muito comum que os gateways no se registrem no servidor SIP Proxy. Desta forma
as mensagens vindas do gateway no devem receber um pedido de autenticao. No
nosso script anterior, todas as mensagens de INVITE eram autenticadas. Entretanto se
uma mensagem vinda do gateway pedir autenticao, o gateway no ter as
credenciais necessrias e a ligao entrante falhar. Para contornar isso vamos usar a
funo allow_trusted() do mdulo PERMISSIONS. Ela permite que verifiquemos o
endereo IP do gateway ao invs de checarmos as credenciais. Para isto basta
cadastrar o IP dos gateways na tabela TRUSTED do banco de dados MySQL e
usaremos a lgica abaixo para pular a autenticao para pedidos vindos do gateway.

No se esquea de inserir o endereo IP liberado na tabela TRUSTED da sua


base de dados MySQL para que a lgica funcione.

Voc pode ver e atualizar a tabela TRUSTED hosts usando o utilitrio serMyAdmin.
Use o menu trusted hosts como abaixo.

Para adicionar novos hosts, simplesmente clique no item New trusted Host.

Para encaminhar uma chamada para um gateway, ns vamos usar a funo:


rewritehostport().

107 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Route the call to the PSTN
Gateway
route[4] {
##--
## Send the call to the PSTN
## Change the IP address below to reflect
## your network
##--
rewritehostport("10.1.30.45");
route(1);
}

Script de configurao

Croqui para a configurao

SIP Express Router Asterisk


Gateway 10.1.30.22 10.1.30.45
10.1.30.38
1 FXO

E1 (30 canais)

Rede Ethernet

O script de configurao encontra-se nomeado openser.chapter7-1 e pode ser


encontrado em HTTP://www.sermyadmin.org/openser. Uma cpia segue abaixo com
as diferenas em relao ao script anterior destacadas.
# ------------------ module loading ----------------------------------
#set module path
mpath="//lib/openser/modules/"

# Uncomment this if you want to use SQL database


#loadmodule "mysql.so"

loadmodule "mysql.so"
loadmodule "sl.so"
loadmodule "tm.so"

7 | Conectividade com a rede pblica 108


loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "uri.so"
loadmodule "uri_db.so"
loadmodule "domain.so"
loadmodule "permissions.so"
loadmodule "group.so"
loadmodule "mi_fifo.so"

# Uncomment this if you want digest authentication


# mysql.so must be loaded !
loadmodule "auth.so"
loadmodule "auth_db.so"

# ----------------- setting module-specific parameters ---------------

modparam("mi_fifo", "fifo_name", "/tmp/openser_fifo")


modparam("usrloc", "db_mode", 2)
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("rr", "enable_full_lr", 1)
modparam("auth_db|permissions|uri_db|usrloc","db_url","mysql://openser:opens
errw@localhost/openser")
modparam("permissions", "db_mode", 1)
modparam("permissions", "trusted_table", "trusted")

# ------------------------- request routing logic -------------------

# main routing logic

route{

#
# -- 1 -- Request Validation
#
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};

if (msg:len >= 2048 ) {


sl_send_reply("513", "Message too big");
exit;
};

#
# -- 2 -- Routing Preprocessing
#
## Record-route all except Register
if (!method=="REGISTER") record_route();

109 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
##Loose_route packets
if (loose_route()) {
# mark routing logic in request
append_hf("P-hint: rr-enforced\r\n");
route(1);
};

#
# -- 3 -- Determine Request Target
#
if (method=="REGISTER") {
route(2);
} else {
route(3);
};

route[1] {
#
# -- 4 -- Forward request to target
#
## Forward statefully
if (!t_relay()) {
sl_reply_error();
};
exit;
}

route[2] {
## Register request handler
if (is_uri_host_local()) {
if (!www_authorize("", "subscriber")) {
www_challenge("", "1");
exit;
};

if (!check_to()) {
sl_send_reply("403", "Forbidden");
exit;
};

save("location");
exit;
} else if {
sl_send_reply("403", "Forbidden");
};
}

route[3] {
## INVITE request handler
if (is_from_local()){

7 | Conectividade com a rede pblica 110


# From an internal domain -> check the credentials and the FROM
if(!allow_trusted()){
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","1");
exit;
} else if (!check_from()) {
sl_send_reply("403", "Forbidden, use From=ID");
exit;
};
} else {
log("Request bypassed the auth.using allow_trusted");
};

consume_credentials();

#Verify aliases, if found replace R-URI.


lookup("aliases");

if (is_uri_host_local()) {
# -- Inbound to Inbound
route(10);
} else {
# -- Inbound to outbound
route(11);
};

} else {
#From an external domain ->do not check credentials
#Verify aliases, if found replace R-URI.
lookup("aliases");
if (is_uri_host_local()) {
#-- Outbound to inbound
route(12);
} else {
# -- Outbound to outbound
route(13);
};
};
}

route[4] {
# routing to the public network
rewritehostport("10.1.30.45");
route(1);
}

route[10] {
#from an internal domain -> inbound
#Native SIP destinations are handled using the location table
#Gateway destinations are handled by regular expressions
append_hf("P-hint: inbound->inbound \r\n");

if (uri=~"^sip:[2-9][0-9]{6}@") {

111 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
if (is_user_in("credentials","local")) {
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for local calls");
exit;
};
};

if (uri=~"^sip:1[2-9][1-9]{9}@") {
if (is_user_in("credentials","ld")) {
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for long distance");
exit;
};
};

if (uri=~"^sip:011[0-9]*@") {
if (is_user_in("credentials","int")) {
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for international
calls");
};
};

if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

route[11] {
# from an internal domain -> outbound
# Simply route the call outbound using DNS search
append_hf("P-hint: inbound->outbound \r\n");
route(1);
}

route[12] {
# From an external domain -> inbound
# Verify aliases, if found replace R-URI.
lookup("aliases");
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

7 | Conectividade com a rede pblica 112


route[13] {
#From an external domain outbound
#we are not accepting these calls
append_hf("P-hint: outbound->inbound \r\n");
sl_send_reply("403", "Forbidden");
exit;
}

Dissecando o arquivo openser.cfg


O mdulo de permisses d ao OpenSER a habilidade de acessar a base de dados
MySQL. A tabela trusted um repositrio. Voc deve adicionar o seu gateway
PSTN na tabela para que ele no seja desafiado pelas suas credenciais de
autenticao. (pedido de nome e senha em algoritmo desafio/resposta).
O mdulo PERMISSIONS possui arquivos padro de permisso ou negao (permit,
deny). Por enquanto ns no estamos usando estes recursos. Para evitar mensagens no
log, por favor, copie os arquivos do diretrio de configurao do mdulo
PERMISSION para o diretrio /etc/openser.
cp /usr/src/openser-1.2.2/modules/permissions/config/* /etc/openser

Nos arquivos de permisso, possvel filtrar os pedidos usando expresses regulares e


assim melhorando a segurana do ambiente. Verifique os arquivos de exemplo pela
sintaxe correta.
O mdulo GROUP ser usado para verificar se um usurio est autorizado a ligaes
locais, de longa distncia ou internacionais, ou as trs juntas.
modparam("auth_db|permissions|uri_db|usrloc","db_url","mysql://openser:opens
errw@localhost/openser")

A instruo modparam instrui ao modulo PERMISSIONS onde est o banco de dados.


A linha abaixo diz ao openser para usar o modo caching no acesso ao banco de dados,
o que gera melhor desempenho.
modparam("permissions", "db_mode", 1)

Na recepo das mensagens de INVITE vindas de um cliente SIP, precisamos desafiar


(pedir as credenciais) das mensagens INVITE. Os gateways normalmente no
respondem ao pedido de autenticao. Por isto precisamos adotar um tratamento
especial. A funo allow_trusted() provida pelo mdulo PERMISSIONS. Ela vai
acessar a tabela trusted do MySQL para pegar a lista de endereos IP privilegiados.
Quando o Gateway enviar o INVITE, a funo allow_trusted() vai retornar
verdadeiro e impedir que o OpenSER envie a mensagem 401 Unauthorized pedindo
as credencias do Gateway.
if(!allow_trusted()){
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","0");
exit;
} else if (!check_from()) {`
sl_send_reply("403","proibido, use FROM=ID");
exit;
};

113 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
};

importante ento que o endereo do gateway esteja cadastrado no banco de


dados do OpenSER na tabela trusted.

Voc pode usar utilitrios como o serMyAdmin ou o phpMyAdmin para manter a


base de dados. Isto mais fcil de que faz-lo manualmente na linha de comando do
MySQL.
Na tabela trusted voc inclui o endereo fonte do gateway, o protocolo (udp, tcp, tls,
any) e o padro em formato de expresso regular.
Abaixo temos o roteamento das ligaes iniciadas com 0 com mais oito dgitos
(^sip:0[0-9]{8}@) enviadas para o gateway, bem como os dois padres seguintes para
longa distncia e internacional.
if (uri=~"^sip:0[0-9]{8}@") {
if (is_user_in("credentials","local")) {
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for local calls");
exit;
};
};

if (uri=~"^sip:0[1-9][0-9]{11}@") {
if (is_user_in("credentials","ld")) {
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for long distance");
exit;
};
};

if (uri=~"^sip:00[1-9][0-9]*@") {
if (is_user_in("credentials","int")) {
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for internat. calls");
exit;
};
};

O OpenSER assume que nmeros internacionais so prefixados com 00 + cdigo da


operadora ([1-9][0-9]) + cdigo do pas + cdigo de rea + nmero de telefone e que
nmeros domsticos comeam com 0 + cdigo da operadora ([1-9][0-9]) seguidos do
cdigo de rea mais o nmero de 10 dgitos. Com isto usamos expresses regulares
para corresponder com o nmero discado. Quando ocorrer uma correspondncia
expresso regular, vamos verificar se o usurio pertence ao grupo autorizado para
discagem (grupo local para ligaes locais, grupo ld para ligaes de longa

7 | Conectividade com a rede pblica 114


distncia e grupo int) para ligaes internacionais. Em qualquer um dos casos acima
o programa desviado para a rota 5.
Para que o script funcione preciso que os grupos estejam cadastrados. Aqueles que
estiverem no grupo local podero fazer ligaes locais, ld para longa distncia e int
para internacional. Voc pode fazer isto usando o utilitrio openserctl ou o
serMyAdmin.
Aqui temos o bloco de roteamento 4 para o tratamento dos destinos para PSTN. A
funo rewritehost() usada para alterar a R-URI de tal forma que a mensagem seja
encaminhada para nosso gateway PSTN. O OPENSER vai enviar a mensagem de
INVITE ao Gateway quando voc chamar o t_relay().
route[4] {
##--
## PSTN gateway handling
##--
rewritehostport("10.1.30.45");
route(1);
}

Usando Asterisk como um gateway


Use o grfico mostrado neste captulo para escrever um script que envia as chamadas
para a rede pblica de telefonia. Voc6e pode usar o serMyAdmin ou a linha de
comando do MySQL para inserir os dados no banco.
Passo 1 Adicione o endereo do gateway na tabela trusted usando o serMyAdmin.

Se desejado ou conveniente, voc pode ao invs disso usar a linha de comando do


MySQL para obter o mesmo resultado.
debianSer#mysql u openser p
-- enter your mysql password --
mysql> use openser;
mysql> INSERT INTO trusted ( src_ip , proto , from_pattern )
VALUES ( '10.1.30.22', 'any', '^sip:.*$');

A instruo acima diz ao OPENSER para permitir quaisquer protocolos (udp ou tcp)
de IP 10.1.30.22 (IP do gateway) sem pedir credenciais. Voc deve reiniciar o
OPENSER aps alterar a tabela. Voc pode usar tambm o comando abaixo se no
quiser reiniciar.
debianSER#openserctl fifo trusted_reload

115 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Passo 2 Inclua os seus domnios na tabela domains
debianSer#mysql u openser p
-- enter your mysql password --
mysql> use openser;
INSERT INTO domain ( domain , last_modified )
VALUES ( 'voffice.com.br', '0000-00-00 00:00:00');

Voc pode usar tambm o serMyAdmin para isto.

Certifique-se que o OPENSER est apropriadamente gravando as rotas (record-


routing) muitos gateways fazem contabilizao e se a mensagem de BYE no for
enviada isto pode afetar na contabilizao das chamadas.
Passo 3 Inclua os seus usurios nos grupos locais, ld e int.
#openserctl acl grant 1000@sermyadmin.org local
#openserctl acl grant 1000@sermyadmin.org ld
#openserctl acl grant 1000@sermyadmin.org int
#openserctl acl grant 1001@sermyadmin.org local

Se quiser usar o serMyadmin use o menu indicado abaixo:

Passo 4 Configurao do Gateway.


O gateway pode ser um servidor Asterisk ou um Gateway SIP de qualquer fabricante
que suporte a RFC3261. Cada gateway tem a sua prpria maneira de ser configurado.
Vamos ver como configurar alguns dos mais populares, Asterisk e Cisco.

CUIDADO: Os comandos abaixo para o Asterisk permitem que qualquer


usurio possa se conectar ao Asterisk sem autenticao. Se o Asterisk for

7 | Conectividade com a rede pblica 116


usado como Gateway recomendvel que ele no possa receber pacotes SIP
de nenhum outro equipamento alm do Proxy (OPENSER).

Passo 5 - Configurando o Asterisk


No Asterisk preciso editar dois arquivos, o sip.conf e o extensions.conf. Vamos
supor que o Asterisk est fazendo s vezes de gateway. Vamos fazer tudo o que entra
de ligaes pela rede pblica ser enviado ao Proxy e tudo que vier do proxy ser
enviado para a rede pblica.
Asterisk (sip.conf)
[general]
context=sipincoming
#calls incoming from the SIP proxy to be terminated in the PSTN lines

[sipproxy]
#calls incoming from the PSTN to be forwarded to clients behind the SIP
#proxy
type=peer
context=sipoutgoing
host=10.1.30.22
insecure=invite
disallow=all
allow=ulaw

Asterisk (extensions.conf)
[general]

[globals]

[sipincoming]
exten=>_[0-9].,1,Dial(Zap/g1/${EXTEN:1})
exten=>_[0-9].,2,hangup()

[sipoutgoing]
# If you have a digital interface use the lines below
exten=_[0-9].,1,Answer()
exten=_[0-9].,2,dial(SIP/${EXTEN}@sipproxy)
exten=_[0-9].,3,Hangup()

#If you have analog FXO interfaces use the lines below.
exten=s,1,Answer()
exten=s,2,dial(SIP/${EXTEN}@sipproxy)
exten=s,3,Hangup()

Gateway Cisco
voice class codec 1
codec preference 2 g711ulaw
!
interface Ethernet0/0
ip address 10.1.30.38 255.255.0.0
half-duplex

117 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
!
ip classless
ip route 0.0.0.0 0.0.0.0 10.1.0.1
no ip http server
ip pim bidir-enable
!
voice-port 1/0
!
voice-port 1/1
!
mgcp profile default
!
! Os comandos dial-peer pots vo permitir a entrada de chamadas
! jogando para rede publica os numeros vindos do proxy que
! comeam com 0.
!
dial-peer voice 1 pots
destination-pattern 0T
port 1/0
!
dial-peer voice 2 pots
destination-pattern 0T
port 1/1

!
! Nmeros entrando pela rede pblica com destino de 1000 1299 ! sero
encaminhados para o proxy (ramais).
!
dial-peer voice 123 voip
destination-pattern [1-9]T
session protocol sipv2
session target ipv4:10.1.30.22
dtmf-relay sip-notify

Passo 5 Teste as configuraes recebendo e fazendo chamadas.

Using LCR (least cost routes)


A ltima configurao feita funciona bem se voc tem alguns gateways e no altera
freqentemente as rotas. No entanto, normalmente um provedor SIP muda as rotas
com freqncia e tem mltiplos gateways e conexes para provedores de VoIP que
vendem minutagem no atacado. contraproducente mudar o script cada vez que
uma rota alterada. Desta forma, o mdulo LCR ser usado para transferir estas
configuraes para a base de dados e mud-las dinamicamente se necessrio. Imagine
uma situao onde voc tem dois provedores VoIP, um na Europa e outro na Asia e
quer tambm que caso houver uma falha em um dos gateways que as chamadas saiam
pelos prprios gateways.

O mdulo LCR
O modulo LCR implanta dois recursos. O mais importante encaminhamento
seqencial do pedido para um ou mais gateways (load_gws() and next_gw()). Estas
funes sero usadas para enviar chamadas para os gateways e no caso de uma falha
7 | Conectividade com a rede pblica 118
enviar para o gateway seguinte. Voc pode usar tambm o mdulo LCR para o
encaminhamento seqencial de contatos baseado no valor Q (normalmente setado no
telefone IP para permitir mltiplos registros) usando load_contacts() e
next_contacts().

Diagrama de configurao

usa1
10.1.30.45
SIP Proxy
10.1.30.22
PSTN

Local and Long


Router
Distance Calls Internet
usa2
10.1.30.46

200.31.31.31
200.61.61.61
Voip Provider
Voip Provider Asia
Europe
+61 Australia
+31 Netherlands
+81 Japan
+49 Germany

Para implantar um diagrama como acima, ns precisamos entender as trs tabelas


envolvidas, lcr, gw e gw_grp.

Plano de discagem para o OpenSER


hora de comear a elaborar um plano de discagem para nosso provedor VoIP. Ns
iremos implantar um esquema de numerao padro e164 para direcionar as chamadas
para os gateways corretos. Quando um cliente chama um nmero local, ns vamos
usar expresses regulares para transformar o nmero discado para o seu endereo
e164 antes de selecionar o gateway usando a funo load_gw().
Destino Numerao Descrio
Assinantes 8[0-9]{5} Seis dgitos comeando
com 8
Chamadas de longa 1[2-9][0-9]{9} 1+Cdigo de
distncia rea+Assinante(7 digitos)
Chamadas Internacionais +[0-9]* Qualquer nmero iniciando
com +
Chamadas Internacionais 011[0-9]* Qualquer nmero iniciando
com 011

A tabela LCR
Na tabela lcr voc ir implantar as rotas. Os campos lcr so descritos abaixo.
Chamadas locais e de longa distncia sero prefixadas com o nmero +1305.

119 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Prefix From_uri Grp_id Priority
+31 % 3 1
+49 % 3 1
+61 % 2 1
+81 % 2 1
+1 % 1 1
Prefix Este prefixo comparado com a parte usurio da URI (nmero do
telephone)
From_uri O campo From_URI pode conter caracteres especiais. Use o
% para bater com quaisquer nmeros e o _ para bater com um nico
caracter
Grp_id O Grp_id identifica o grupo de gateways
Priority Prioridade dos gateways

A tabela de gateways
gw_name grp_id ip_addr port uri_scheme transport strip Prefix
Usa1 1 756941066 5060 1 1 2
Usa2 1 773718282 5060 1 1 2
Asia1 2 1027423688 5060 1 1 0
Europe1 3 522133448 5060 1 1 0
gw_name Nome do Gateway
grp_id Identificao do grupo de gateways
ip_addr Endereo IP do gateway (notao decimal inversa)
port (porta UDP/TCP)
uri_scheme sip(1), sips(2)
transport udp(1), tcp(2), tls(3)
strip Nmero de caracteres a serem removidos
prefix Prefixo a ser aplicado antes de enviar para o gateway

A tabela grupo de gateways


A tabela grupo de gateways usada apenas para propsitos administrativos. Ela
associa o nome ao gateway.

Gerenciando rotas e gateways


Voc pode adicionar, remover, mostrar as tabelas LCR e Gateways usando o
openserctl ou o serMyAdmin. Voc pode faz-lo manualmente tambm.

Comandos openserctl relacionados


Comando Descrio
lcr show Mostra rotas, gateways e grupos

7 | Conectividade com a rede pblica 120


lcr reload Recarrega o gateway LCR
lcr addgw_grp <grp_name> Adiciona um grupo de gateways e cria
automticamente um grp_id
lcr addgw_grp <grp_name> <grp_id> Adiciona um grupo de gateways com o
grp_id
lcr rmgw_grp <grp_id> Apaga o gw_grp
lcr addgw <gw_name> <ip> <port> Adiciona um gateway
<scheme> <transport> <grp_id>
lcr addgw <gw_name> <ip> <port> Adiciona um gateway com prefixo
<scheme> <transport> <grp_id> <prefix>
lcr addgw <gw_name> <ip> <port> Adiciona um gateway com um prefix e strip
<scheme> <transport> <grp_id> <prefix> (remoo de nmeros)
<strip>
lcr rmgw <gw_name> Apaga um gateway
lcr addroute <prefix> <from> <grp_id> Adiciona uma rota
<prio>
lcr rmroute <prefix> <from> <grp_id> Apaga uma rota
<prio>

Notas:

Os endereos IP devem ser inseridos separados por pontos e.g. 1.2.3.4


Os campos <uri_scheme> e <transport> podem ser inseridos como inteiros
ou texto.
o transport '2' idntico transport 'tcp'
o scheme: 1=sip, 2=sips; transport: 1=udp, 2=tcp, 3=tls

Exemplos:

lcr addgw_grp usa 1


lcr addgw level3 1.2.3.4 5080 sip tcp 1
lcr addroute +1 % 1 1

121 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
LAB Usando o recurso de LCR

LCR Lab bench


usa1
192.168.1.171
SIP Proxy
PSTN 192.168.1.160

Local and Long


Distance Calls
(Group 1)

br1
192.168.1.177

Vamos executar um laboratrio simples com o LCR. Neste LAB ns iremos precisar
de um servidor OpenSER, dois gateways e um telefone IP. Voc pode simular
facilmente este laboratrio usando um servidor Asterisk como gateway.
Passo 1: Construa um laboratrio com os gateways. Configure o gateway usa1 para
Receber chamadas com o prefixo +1 e o gateway br1 para receber chamadas com o
prefixo +55. NO gateway voc pode prefixar e remover nmeros antes de enviar a
chamada para o gateway.
Passo 2: Faa o download do arquivo de configurao em
http://www.asteriskguide.com/openser/openser.lcr e copie o para openser.cfg.
cd /etc/openser
wget http://www.sermyadmin.org/openser/openser.chapter7-2
cp openser.chapter7-2 openser.cfg

O script pode ser visto abaixo com as modificaes destacadas.


# ------------------ module loading ----------------------------------
#set module path
mpath="//lib/openser/modules/"

loadmodule "mysql.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "uri.so"
loadmodule "uri_db.so"
loadmodule "domain.so"
loadmodule "permissions.so"
loadmodule "group.so"

7 | Conectividade com a rede pblica 122


loadmodule "mi_fifo.so"
loadmodule "lcr.so"

# Uncomment this if you want digest authentication


# mysql.so must be loaded !
loadmodule "auth.so"
loadmodule "auth_db.so"

# ----------------- setting module-specific parameters ---------------

modparam("mi_fifo", "fifo_name", "/tmp/openser_fifo")


modparam("usrloc", "db_mode", 2)
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("rr", "enable_full_lr", 1)
modparam("auth_db|permissions|uri_db|usrloc","db_url","mysql://openser:opens
errw@localhost/openser")
modparam("permissions", "db_mode", 1)
modparam("permissions", "trusted_table", "trusted")

# ------------------------- request routing logic -------------------

# main routing logic

route{

#
# -- 1 -- Request Validation
#
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};

if (msg:len >= 2048 ) {


sl_send_reply("513", "Message too big");
exit;
};

#
# -- 2 -- Routing Preprocessing
#
## Record-route all except Register
if (!method=="REGISTER") record_route();

##Loose_route packets
if (loose_route()) {
# marca a logica de roteamento no pedido
append_hf("P-hint: roteado por loose_route\r\n");
route(1);
};

123 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
# -- 3 -- Determine Request Target
#
if (method=="REGISTER") {
route(2);
} else {
route(3);
};
}

route[1] {
#
# -- 4 -- Forward request to target
#
## Forward statefully
t_on_failure("1");
if (!t_relay()) {
sl_reply_error();
};
exit;
}

route[2] {
## Register request handler
if (is_uri_host_local()) {
if (!www_authorize("", "subscriber")) {
www_challenge("", "1");
exit;
};

if (!check_to()) {
sl_send_reply("403", "Forbidden");
exit;
};

save("location");
exit;
} else if {
sl_send_reply("403", "Forbidden");
};
}

route[3] {
## INVITE request handler
if (is_from_local()){
# From an internal domain -> check the credentials and the FROM
if(!allow_trusted()){
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","1");
exit;
} else if (!check_from()) {
sl_send_reply("403", "Forbidden, use From=ID");
exit;
};

7 | Conectividade com a rede pblica 124


} else {
log("Request bypassed the auth.using allow_trusted");
};

consume_credentials();

#Verify aliases, if found replace R-URI.


lookup("aliases");

if (is_uri_host_local()) {
# -- Inbound to Inbound
route(10);
} else {
# -- Inbound to outbound
route(11);
};

} else {
#From an external domain ->do not check credentials

#Verify aliases, if found replace R-URI.


lookup("aliases");
if (is_uri_host_local()) {
#-- Outbound to inbound
route(12);
} else {
# -- Outbound to outbound
route(13);
};
};
}

route[4] {
# routing to the public network
if (!load_gws()) {
sl_send_reply("503", "Unable to load gateways");
exit;
}

if(!next_gw()){
sl_send_reply("503", "Unable to find a gateway");
exit;
}
route(1);
exit;
}

route[10] {
#from an internal domain -> inbound
#Native SIP destinations are handled using the location table
#Gateway destinations are handled by regular expressions
#In our example we will normalize the number to e164 +1305XXXXXX
#to facilitate the posterior billing.

125 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
append_hf("P-hint: inbound->inbound \r\n");

if (uri=~"^sip:[2-9][0-9]{6}@") {
if (is_user_in("credentials","local")) {
# Assuming your country is USA (+1) and area code (305)
prefix(+1305);
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for local calls");
exit;
};
};

if (uri=~"^sip:1[2-9][0-9]{9}@") {
if (is_user_in("credentials","ld")) {
prefix(+);
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for long distance");
exit;
};
};

if (uri=~"^sip:011[0-9]*@") {
if (is_user_in("credentials","int")) {
strip(2);
prefix(+);
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for international
calls");
};
};

if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

route[11] {
# from an internal domain -> outbound
# Simply route the call outbound using DNS search
append_hf("P-hint: inbound->outbound \r\n");
route(1);
}

route[12] {

7 | Conectividade com a rede pblica 126


# From an external domain -> inbound
# Verify aliases, if found replace R-URI.
lookup("aliases");
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

route[13] {
#From an external domain outbound
#we are not accepting these calls
append_hf("P-hint: outbound->inbound \r\n");
sl_send_reply("403", "Forbidden");
exit;
}

failure_route[1] {
if(!next_gw()) {
t_reply("503", "Service not available, no more gateways");
exit;
}
t_on_failure("1");
t_relay();

Passo 3: Use o utilitrio ngrep para capturar pacotes e se certificar que voc est
enviando as ligaes para os destinos corretos.
Passo 4: Adicione as rotas e gateways de acordo com a tabela abaixo. Use os
comandos openserctl lcr.

Rotas lcr

Prefix From_uri Grp_id Priority


+1 1 1
+55 2 1
+55 1 2

Grupos de gateways

127 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Voc pode usar o serMyAdmin para inserir os gatewyas.

grp_id grp_name
1 Usa
2 Br

Gateways

gw_name Ip port uri_scheme transport grp_id strip Prefix


usa1 192.168.1.171 5060 1 1 1 0
br1 192.168.1.177 5060 1 1 2 0

Passo 5: Teste as chamadas para qualquer nmero iniciando com +1 ou +55.


Passo 6 Desligue o gateway br1 e teste a chamada novamente para +55 e teste a
chamada novamente para o +55. Ela se completou?, porque?

Sumrio
Neste captulo voc aprendeu como configurar o OPENSER para encaminhar
chamadas para um gateway. Aprendeu que o mdulo PERMISSIONS permite que a
autenticao do OPENSER seja evitada para pacotes vindos de gateways que
normalmente no enviam credenciais de autenticao. O mdulo GROUP permite que
os usurios sejam organizados em grupos com direitos de acesso deferentes. Quando o
nmero de gateways e destinos para se gerenciar muito grande, o uso do mdulo
LCR se faz necessrio. Aprendemos no final do captulo como us-lo.

7 | Conectividade com a rede pblica 128


8
Encaminhamento de
chamadas

O encaminhamento de chamadas um recurso importante para os provedores de


VoIP, ele pode ser implantado de duas formas, ramificao ou redirecionamento. Na
ramificao, uma nova perna da chamada criada enviando-se um novo INVITE para
o novo destino, aps o primeiro destino falhar (ocupado, no disponvel). J no
redirecionamento, o Proxy envia uma mensagem de resposta ao originador da
chamada e fornece a ele o local para onde a chamada deve ser desviada. O originador
da chamada ento cria um novo INVITE para o local para o qual foi redirecionado.
Ao final deste captulo o leitor estar apto :
Descrever conceitos como ramificao e redirecionamento
Implantar o encaminhamento das chamadas
Implantar siga-me quando ocupado
Implantar siga-me se no atendido
Usar o recurso de AVP (Attribute Value Pair)
Usar o recurso de roteamento em falha (failure_route)
O redirecionamento deve ser usado com cuidado se um gateway PSTN estiver
acessvel. A razo que concebvel que o OpenSER possa enviar uma resposta de
redirecionamento ao gateway que ento poderia enviar uma nova mensagem de
INVITE para o novo destino e passar por fora do OpenSER. Isto vai fazer com que
esta mensagem esteja fora do controle doProxy e por isso ela pode acabar no sendo
tarifada. O que ocorre que quando um redirecionamento feito com uma mensagem
302 Movido Temporariamente (302 Moved Temporarily) o OpenSER fica fora
do caminho da sinalizao SIP.
A ramificao serial mais segura j que o OPENSER ir gravar as rotas de todas as
mensagens (record-route), o que significa que mesmo se o destino for um telefone
comum na rede pblica o OpenSER conseguir fazer a bilhetagem.

Verificando seu progresso?


Um provedor VoIP possui muitos componentes. Para voc poder se localizar, ns
vamos agora trabalhar com encaminhamento de chamadas e correio de voz. Existem
vrios servidores de mdia disponveis. Asterisk provavelmente o mais usado
atualmente. O projeto SER original possua o SEMS (Sip Express Media Server,
www.iptel.org/sems), mas tenho ouvido falar pouco dele ultimamente. Existm outros
que esto comeando a aparecer neste cenrio como o CallWeaver, FreeSwitch e
Yate. O recurso de encaminhamento importante para o uso de recursos como
Correio de voz, URA, conferncia, mensagens de voz e converso de texto para fala.

The SIP provider MySQL/Postgres/


Big Picture Unixodbc Database

Ethernet

Media
User Radius
SIP PSTN Media Proxy CDRTool Monitoring
Portal Server Tools
Proxy Gateway Server Nat Rating
Provis. Traversal Acct.

Ethernet

CPE device (router)


Usually xDSL or
Cable
Internet Firewall
Customer Customer
Using an ATA Firewall
or Softphone

Encaminhamento de Chamadas
Nesta seo vamos implantar trs tipos de encaminhamento de chamadas. Este
encaminhamento importante, por exemplo, para a operao do correio de voz:
Siga-me (Blind Call Forwarding) Todas as mensagens de INVITE enviadas ao
telefone sero interceptadas no roteador SIP. O roteador SIP ir criar uma nova perna
e enviar uma mensagem de INVITE ao novo destino. Isto significa que o telefone
programado com o siga-me no vai nem mesmo tocar. Isto tambm significa que no
importa se o telefone est registrado ou no.
Siga-me se ocupado (Forward on Busy) Se o telefone responder a mensagem de
INVITE com uma mensagem 486 Ocupado (486 Busy), o OPENSER ir
interceptar esta resposta e criar uma nova perna da chamada, e ento enviar uma
mensagem de INVITE ao destino final.
Siga-me se no atender (Forward No Answer) Se um telefone responder a uma
mensagem de INVITE com uma mensagem 408 tempo esgotado no pedido (408
Request Timeout), o OpenSER ir interceptar esta mensagem e criar uma nova perna
de chamada e enviar um novo INVITE ao destino final.
O siga-me processado de forma diferente do siga-me se ocupado e siga-me se no
atende, pois ele altera a mensagem original de INVITE para refletir a nova R-URI,
enquanto os outros dois mtodos precisam de bem mais esforo para funcionar. Nos
outros dois tipos, preciso processar a resposta do comando e alterar a R-URI,
adicionar o novo destino e finalmente encaminhar a mensagem.
Todas as configuraes de encaminhamento so armazenadas na tabela
USR_PREFERENCES. Ns vamos usar o mdulo AVPOPS para ler as configuraes
de encaminhamento de chamados. AVPOPS tambm ser usado para alterar a
seqncia de chamados e fazer a ramificao em srie necessria.
8 | Encaminhamento de chamadas 130
Pseudo-variveis
Pseudo-variveis, como o prprio nome diz, so variveis que voc pode usar no seu
script como parmetros para algumas funes. Estas variveis sero substitudas antes
da execuo da funo. Alguns dos mdulos que podem receber pseudo-variveis
como parmetros so:
Acc
Avpops
Textops
Uac
Xlog
Uma pseudo-varivel sempre iniciada com $. Se voc quiser usar o character $ no
seu script ter de referenci-lo como $$. Existe um conjunto pr-definido de pseudo-
variveis.

Tabela de pseudo-variveis do OpenSER verso 1.1


$ar Auth realm
$au Auth username
$br Requests first branch
$bR Requests all branches
$ci Call-ID header
$cl Content-length
$cs Cseq
$ct Contact-Header
$cT Content-Type
$dd Domain of destination URI
$di Diversion header URI
$dp Port of destination URI
$dP Transport protocol of destination URI
$ds Destination set
$du Destination URI
$fd From URI domain
$fn From display name
$ft From Tag
$fu From URI
$fU From URI username

131 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
$mb SIP message buffer
$mf Flags
$mF Flags in hexadecimal
$mi SIP message id
$ml SIP message length
$od Domain in SIP requests original URI
$op Port of Sip requests original URI
$oP Transport protocol of SIP requests original URI
$ou Requests original URI
$oU Username in SIP requests original URI
$pp Process id
$rd Domain in SIP requests URI
$rb Body of request/reply
$rc Returned code
$rm SIP requests method
$rp SIP requests port of R-URI
$rP Transport protocol of SIP request URI
$rr SIP reply reason
$rs SIP reply status
$rt Refer-to URI
$ru SIP requests URI
$rU Username in SIP requests URI
$Ri Received IP address
$Rp Received Port
$si IP source address
$sp Source port
$td To URI domain
$tn To display name
$tt To tag
$tu To URI
$tU To URI Username
$Tf String formatted time
$Ts Unix time stamp

8 | Encaminhamento de chamadas 132


$ua User agent header
$re Remote-Party-ID header URI

Viso geral dos pares atributo:valor (AVPairs)


As operaes com pares atributo:valor permitem o acesso e manipulao das
preferncias dos usurios. Isto pode ser visto como uma varivel que tem um
identificador (inteiro ou string) e um valor associado a este identificador (inteiro ou
string). No OpenSER um AVP ligado a uma transao SIP. O AVP
automaticamente destrudo quando o processamento da transao terminado.
O processamento de AVPs no OpenSER introduziu muitas possibilidades novas para
a implementao de servios e preferncias por usurio ou domnio. Os pares
atributo:valor podem ser usados diretamente do script de configurao e podem
carregar dinamicamente valores vindos de uma base de dados.
Um par atributo valor referenciado de forma semelhante s variveis.
$avp(id[N])

Onde o ID :
si:name O nome do identificador do AVP. s e i especificando string
ou inteiro
name O nome do alias AVP. Ele pode ser uma string ou um inteiro

Exemplos
$avp(i:700)

$avp(s:blacklist)

Para aqueles que conhecem o Asterisk, o mdulo AVPOPS est para o OpenSER da
mesma forma que o AstDB est para o Asterisk. Entretanto, a implantao bem
diferente. Alm disso, os AVPs so muito mais poderosos permitindo recursos
avanados tais como pesquisas na base de dados e enviar dados diretamente para os
cabealhos de um pacote SIP. Existem vrias funes associadas aos AVPs.
avp_db_load:Carrega os AVPs de uma base de dados para a memria
avp_db_store: Armazena os AVPs emu ma base de dados
avp_db_delete: Deleta os AVPs da base de dados
avp_db_query:Faz uma pesquisa no banco de dados e retorna o resultado
em um AVP.
avp_delete: Deleta os AVPs da memria
avp_pushto: Coloca o valor de um AVP em uma mensagem SIP
avp_check: Verifica o valor de um AVP usando um operador (=;<;>)
avp_copy: Copia um AVP para outro
avp_printf: Formata uma string em um AVP
avp_subst: Encontra e substitui valores em um AVP
avp_op: Permite operaes matemticas em um AVP

133 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
is_avp_set: Verifica se o nome de um AVP est sendo usado
avp_print: Imprime todos os AVPs na memria (para depurao)
Voc pode verificar a sintaxe para estas funes na documentao. Por enquanto,
vamos entender como usar as funes avp_db_load e avp_pushto que sero usadas no
nosso script. Existe um tutorial excelente sobre AVPs em http://www.voice-
system.ro/docs.

AVPs no so exatamente simples, mas se voc pensar neles como simples pares de
atributo:valor eles no so to complexos tambm. No entanto a carga destes AVPs a
partir do banco de dados pode parecer confusa a princpio. A tabela padro a
usr_preference (user preferences). Algumas vezes o valor que nos queremos no est
associado a um usurio especfico, mas ao domnio. De qualquer forma, todos os
AVPs sendo carregados da base de dados vm da tabela usr_preference.
Exemplo: Para o encaminhamento de chamadas, ns temos um atributo chamado call
forward associado ao usurio. Ele realmente uma preferncia do usurio. Vamos
verificar a estrutura da tabela usr_preference.
id uuid usernam domain attribute type value Last_modified
e
1001 callfwd 0 sip:1004@yourdomain
O id um campo auto-incrementvel.
uuid um identificador nico do usurio
username para nome do usurio
domain para domnio
attribute (O nome do AVP)
type (0Avp str|Val Str,1Avp str|Val Int,2Avp int|Val Str,3-Avp int|Val int)
value (O valor do AVP)
last modified (A data da ltima modificao)
Os AVPs podem estar associados a um usurio ou domnio. Isto permite que voc
carregue os AVPS associados com quaisquer destes parmetros. Voc pode associar
um AVP a um uuid (unique user id), a um nome de usurio (setup com nico
domnio) ou a um nome de usurio e domnio (mltiplos domnios).
Na funo avp_db_load o primeiro parmetro a fonte e o segundo o nome do AVP.
Desta forma, a funo abaixo ir carregar a AVP do tipo string chamada callfwd para
o usurio que corresponde a $ruri na coluna username.
(avp_db_load("$ruri/username","s:callfwd")

Mais tarde ns vamos colocar o valor deste AVP para o pacote SIP mudando a $ruri
original para a nova.
avp_pushto("$ruri","s:callfwd");

Em outras palavras, se existe um nmero de encaminhamento configurado para este


usurio, ao invs de chamar o usurio original, ns iremos chamar o usurio
armazenado na AVP s:callfwd. A mgica para o encaminhamento de chamadas
inserir os nmeros de siga-me na tabela usr_preference.
8 | Encaminhamento de chamadas 134
Carga e parametrizao do mdulo AVPOPS.
Na carga especificamos o mdulo, a base de dados e a tabela a ser usada pelo
AVPOPS.
loadmodule "/usr/lib/openser/modules/avpops.so"
modparam("avpops", "avp_url", "mysql://openser:openserrw@localhost/openser")
modparam("avpops", "avp_table", "usr_preferences")

Implantando siga-me incondicional


Em primeiro lugar vamos implantar o servio de encaminhamento de chamadas
incondicional. No momento do processamento do INVITE vamos verificar se no
banco de dados tem uma programao de siga-me criada pelo usurio.
if(avp_db_load("$ruri/username","s:callfwd")){
#Checa se o banco de dados de encaminhar incondicional
avp_pushto("$ruri","s:callfwd");
route(1);
exit;
};

Quando processamos uma mensagem de INVITE precisamos pesquisar a tabela


USR_PREFERENCES para ver se encontramos um registro que tenha uma poro do
campo R-URI e um atributo de callfwd. Isto feito com a funo avp_db_load. Ela
procura um atributo do tipo string s de nome callfwd que corresponda a RURI
(URI requisitada). Se for encontrado, a funo avp_pushto atribui a RURI o valor
correspondente ao atributo callfwd e encaminha para o roteamento.
Para que tudo isto funcione ainda necessrio programar o siga-me entrando com
dados na tabela USR_PREFERENCES do banco de dados.
Username Attribute Value
1001 callfwd sip:1004@seudominio.com
Voc pode modificar a tabela de preferncias dos usurios com a ajuda do
serMyAdmin, navegue pelo menu user preferences. L voc poder ver todas as
preferncias dos usurios, edit-las e criar algumas novas.

135 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Se voc estiver trabalhando em um ambiente multi-domnio, pro favor habilite o
parmetro multi-domnio do mdulo AVPOPS e insira os nomes de domnio tambm
a base de dados.
Com o registro acima estamos dizendo ao sistema para encaminhar todas as chamadas
do assinante 1001 para o assinante 1004 de forma incondicional.

LAB Implantando o recurso de siga-me


Passo 1: Vamos inserir os pares AVP usando a interface do serMyAdmin vista no
captulo 6. No seu browser acesse a interface de administrao serMyAdmin.
http://<your-ip-server-address>:8080/serMyAdmin

Passo 2: Faa o login na interface usando um usurio com papel de administrador


global
Passo 3: Clique na aba User Preferences. Neste menu clique no boto New Preference
e crie um AVP para o usurio o qual voc quer encaminhar chamadas. Neste caso ele
deve ser 1000@serMyAdmin.org. Seu atributo deve ser nomeado callfwd e o valor
para a URI para qual voc quer encaminhar as chamadas. Aqui vamos configurar para
1004@sermyadmin.org.

Passo 4: Edite o arquivo openser.cfg para incluir as instrues explicadas acima. O


arquivo deve estar como abaixo. Inclua as seguintes linhas no arquivo openser.cfg ou
simplesmente copie o arquivo openser.chapter8-1 de
http://www.sermyadmin.org/openser para o arquivo openser.cfg.

Na seo de carga de mdulos:


loadmodule "avpops.so"
loadmodule "xlog.so"

Na seo de parametrizao de mdulos:


modparam("avpops", "avp_url", "mysql://openser:openserrw@localhost/openser")
modparam("avpops", "avp_table", "usr_preferences")

Na seo route[3]:

8 | Encaminhamento de chamadas 136


route[3] {
#
# -- INVITE request handler --
#
if (is_from_local()){
# From an internal domain -> check the credentials and the FROM
if(!allow_trusted()){
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","1");
exit;
} else if (!check_from()) {
sl_send_reply("403", "Forbidden, use From=ID");
exit;
};
} else {
log("Request bypassed the auth. using allow_trusted");
};

if(avp_db_load("$ru/username","$avp(s:callfwd)")) {
avp_pushto("$ru", "$avp(s:callfwd)");
xlog("forwarded to: $avp(s:callfwd)");
route(1);
exit;
}

consume_credentials();

Passo 5: Registre os telefones 1001 e 1004. Chame de 1001 para o 1000. O sistema
deve encaminhar automaticamente para o telefone 1004 como, instrudo na tabela
usr_preferences.

Implantando siga-me (ocupado, no atende)


Nesta segunda parte vamos introduzir dois conceitos importantes. O primeiro da rota
de falha (failure_route) e o segundo o da funo append_branch() que usado para
ramificao.
Vamos tratar os seguintes tipos de mensagens:
408 - Timeout
486 Busy Here
487 Request Cancelled
O objetivo encaminhar para o valor contido no atributo fwdbusy para as mensagens
ocupadas, cancelar se foi recebido uma mensagem 487 e encaminhar para o valor
contido no atributo fwdnoanswer. Para que isto funcione vamos precisar criar a lgica
do tratamento de falhas.

137 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Failure Route
At the end of the file
Before the t_relay() failure_route[1] {
if (t_was_cancelled()) {
t_on_failure("1");
exit;
};
if (t_check_status("486")) {
revert_uri();
rewritehostport("192.168.1.171");
append_branch();
route(1);
exit;
};
if (t_check_status("408") ||
t_check_status("480")) {
revert_uri();
rewritehostport("192.168.1.171");
append_branch();
route(1);
exit;
};
}

Nesta lgica, logo antes de enviar o INVITE para o processamento padro, chamamos
a funo t_on_failure. Isto vai fazer com que possamos tratar as rotas na
failure_route(1).

Vamos usar como exemplo uma configurao mais parecida com a prtica possvel.
Ao receber uma chamada ocupada, vamos adicionar a letra b na frente da uri
original e despachar para um servidor Asterisk que vai processar a caixa de correio de
voz (voicemail(b${EXTEN}). Ao receber uma mensagem de timeout, vamos despachar
para o mesmo servidor Asterisk para o correio de voz, mas vamos adicionar a letra
u com a mensagem de no atendido (voicemail(u${EXTEN}).
Segue abaixo destacado as mudanas do script anterior para o novo.
#
# $Id: openser.cfg 1676 2007-02-21 13:16:34Z bogdan_iancu $
#
# simple quick-start config script
# Please refer to the Core CookBook at
http://www.openser.org/dokuwiki/doku.php
# for a explanation of possible statements, functions and parameters.
#

# ----------- global configuration parameters ------------------------

debug=3 # debug level (cmd line: -dddddddddd)


fork=yes
log_stderror=no # (cmd line: -E)
children=4
port=5060

# ------------------ module loading ----------------------------------


#set module path
mpath="//lib/openser/modules/"

# Uncomment this if you want to use SQL database


#loadmodule "mysql.so"

loadmodule "mysql.so"
loadmodule "sl.so"

8 | Encaminhamento de chamadas 138


loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "uri.so"
loadmodule "uri_db.so"
loadmodule "domain.so"
loadmodule "permissions.so"
loadmodule "group.so"
loadmodule "mi_fifo.so"
loadmodule "lcr.so"
loadmodule "avpops.so"
loadmodule "xlog.so"

# Uncomment this if you want digest authentication


# mysql.so must be loaded !
loadmodule "auth.so"
loadmodule "auth_db.so"

# ----------------- setting module-specific parameters ---------------

modparam("mi_fifo", "fifo_name", "/tmp/openser_fifo")


modparam("usrloc", "db_mode", 2)
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("rr", "enable_full_lr", 1)
modparam("auth_db|permissions|uri_db|usrloc","db_url","mysql://openser:opens
errw@localhost/openser")
modparam("permissions", "db_mode", 1)
modparam("permissions", "trusted_table", "trusted")
modparam("avpops", "avp_url", "mysql://openser:openserrw@localhost/openser")
modparam("avpops", "avp_table", "usr_preferences")

# ------------------------- request routing logic -------------------

# main routing logic

route{

#
# -- 1 -- Request Validation
#
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};

if (msg:len >= 2048 ) {


sl_send_reply("513", "Message too big");
exit;
};

139 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
#
# -- 2 -- Routing Preprocessing
#
## Record-route all except Register
if (!method=="REGISTER") record_route();

##Loose_route packets
if (loose_route()) {
# marca a logica de roteamento no pedido
append_hf("P-hint: roteado por loose_route\r\n");
route(1);
};

#
# -- 3 -- Determine Request Target
#
if (method=="REGISTER") {
route(2);
} else {
route(3);
};
}

route[1] {
#
# -- 4 -- Forward request to target
#
## Forward statefully
t_on_failure("1");
if (!t_relay()) {
sl_reply_error();
};
exit;
}

route[2] {
## Register request handler
if (is_uri_host_local()) {
if (!www_authorize("", "subscriber")) {
www_challenge("", "1");
exit;
};

if (!check_to()) {
sl_send_reply("403", "Forbidden");
exit;
};

if (!save("location"));
sl_reply_error();
};
exit;
}

8 | Encaminhamento de chamadas 140


route[3] {
## INVITE request handler
if (is_from_local()){
# From an internal domain->check the credentials and the FROM
if(!allow_trusted()){
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","1");
exit;
} else if (!check_from()) {
sl_send_reply("403", "Forbidden, use From=ID");
exit;
};
} else {
log("Request bypassed the auth-allow_trusted");
};

if(avp_db_load("$ru/username","$avp(s:callfwd)")) {
avp_pushto("$ru", "$avp(s:callfwd)");
xlog("$avp(s:callfwd)");
route(1);
exit;
}

consume_credentials();

#Verify aliases, if found replace R-URI.


lookup("aliases");

if (is_uri_host_local()) {
# -- Inbound to Inbound
route(10);
} else {
# -- Inbound to outbound
route(11);
};

} else {
#From an external domain ->do not check credentials
#Verify aliases, if found replace R-URI.
lookup("aliases");
if (is_uri_host_local()) {
#-- Outbound to inbound
route(12);
} else {
# -- Outbound to outbound
route(13);
};
};
}

route[4] {
# routing to the public network

141 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
if (!load_gws()) {
sl_send_reply("503", "Unable to load gateways");
exit;
}

if(!next_gw()){
sl_send_reply("503", "Unable to find a gateway");
exit;
}
route(5);
exit;
}

route[5] {
#
# -- 4 -- T_relay for gateways
#
## Forward statefully, if failure load other gateways
t_on_failure("2");
if (!t_relay()) {
sl_reply_error();
};
exit;
}

route[10] {
#from an internal domain -> inbound
#Native SIP dest.are handled using the location table
#Gateway destinations are handled by regular expressions
append_hf("P-hint: inbound->inbound \r\n");

if (uri=~"^sip:[2-9][0-9]{6}@") {
if (is_user_in("credentials","local")) {
prefix("+1305");
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for local calls");
exit;
};
};

if (uri=~"^sip:1[2-9][0-9]{9}@") {
if (is_user_in("credentials","ld")) {
strip(1);
prefix("+1");
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for long distance");
exit;
};
};

8 | Encaminhamento de chamadas 142


if (uri=~"^sip:011[0-9]*@") {
if (is_user_in("credentials","int")) {
strip(2);
prefix("+");
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for international
calls");
};
};

if (!lookup("location")) {
if (does_uri_exist()) {
## User not registered at this time.
## Use the IP Address of your e-mail server
revert_uri();
prefix("u");
rewritehostport("192.168.1.171"); #Use the IP address of your
voicemail server
route(1);
} else {
sl_send_reply("404", "Not Found");
exit;
}
sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

route[11] {
# from an internal domain -> outbound
# Simply route the call outbound using DNS search
append_hf("P-hint: inbound->outbound \r\n");
route(1);
}

route[12] {
# From an external domain -> inbound
# Verify aliases, if found replace R-URI.
lookup("aliases");
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

route[13] {
#From an external domain outbound
#we are not accepting these calls

143 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
append_hf("P-hint: outbound->inbound \r\n");
sl_send_reply("403", "Forbidden");
exit;
}

failure_route[1] {
##--
##-- If cancelled, exit.
##--
if (t_was_cancelled()) {
exit;
};
##--
##-- If busy send to the e-mail server, prefix the "b"
##-- character to indicate busy.
##--
if (t_check_status("486")) {
revert_uri();
prefix("b");
xlog("L_ERR","Stepped into the 486 ruri=<$ru>");
rewritehostport("192.168.1.171");
append_branch();
route(1);
exit;
};
##--
##-- If timeout (408) or unavailable temporarily (480),
##-- prefix the uri with the "u"character to indicate
##-- unanswered and send to the e-mail
##-- sever
##--
if (t_check_status("408") || t_check_status("480")) {
revert_uri();
prefix("u");
xlog("L_ERR","Stepped into the 480 ruri=<$ru>");
rewritehostport("192.168.1.171");
append_branch();
route(1);
exit;
};
}

failure_route[2] {
if (t_was_cancelled()) {
exit;
};
if(!next_gw()) {
t_reply("503", "Service not available, no more gateways");
exit;
}
t_on_failure("1");
t_relay();

8 | Encaminhamento de chamadas 144


Dissecando o arquivo de configurao
Este um script difcil de depurar, por isto vamos introduzir o mdulo XLOG. Ele
similar ao log, s que permite jogar no output as pseudo-variveis como a ruri.
loadmodule "xlog.so"
xlog("L_ERR","Passou no 480 ruri=<$ru>");

Acima vemos um exemplo de uso do xlog. Para lembrar, as mensagens ficam


armazenadas em /var/log/syslog. E as ltimas linhas registradas podem ser vistas
facilmente com o comando:
tail /var/log/syslog

importante entender que no siga-me incondicional, apenas a mensagem de INVITE


original ser processada, de forma que, ns podemos seguramente alterar e R-URI e a
chamada para o append_branch() no deve ser feita.
Por outro lado siga-me se ocupado e siga-me se no entender, ocorrem apenas aps a
mensagem de INVITE original ter falhado. De maneira a ramificar a chamada neste
ponto o comando append_branch() deve ser chamado.
t_on_failure("1");

O comando t_on_failure() avisa ao OpenSER que ele quer fazer um tratamento


especial quando uma condio de falha ocorrer. Condies de falha neste contexto se
referem a mensagens do tipo 4xx e 5xx. Ao chamar o t_on_failure() antes de
chamar o t_relay() faz com que o OpenSER passe o controle para o bloco de cdigo
definido como failure_route[1] que aparece no fim do script de configurao.
failure_route[1] {
##--
##-- If cancelled, exit.
##--
if (t_was_cancelled()) {
exit;

};

A primeira parte da seo failure_route trata as mensagens canceladas (487) e


simplesmente termina o processamento.
Em seguida processamos as mensagens de ocupado.
##--
##-- If busy send to the e-mail server, prefix the "b"
##-- character to indicate busy.
##--
if (t_check_status("486")) {
revert_uri();
prefix("b");
xlog("L_ERR","Stepped into the 486 ruri=<$ru>");
rewritehostport("192.168.1.171");
append_branch();
route(1);
exit;

145 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
};

Se o status for igual a 486 (busy here) ele reverte a uri original, adiciona a letra b na
uri para processamento no correio de voz. Reescreve o host para o servidor onde est
o correio, emite o comando append_branch para adicionar o destino e encaminha o
pedido.
A mesma lgica seguida para as mensagens 408 e 480.
##-- If timeout (408) or unavailable temporarily (480),
##-- prefix the uri with the "u"character to indicate
##-- unanswered and send to the e-mail
##-- sever
##--
if (t_check_status("408") || t_check_status("480")) {
revert_uri();
prefix("u");
xlog("L_ERR","Stepped into the 480 ruri=<$ru>");
rewritehostport("192.168.1.171");
append_branch();
route(1);
exit;

};

No Asterisk o arquivo extensions.conf para recepo do correio de voz fica como


abaixo. Contas de correio de voz devem ser criadas para bater com cada conta no
OpenSER. Voc pode integrar ambas as bases de dados evitando manter entradas
duplicadas usando o tutorial encontrado em: http://www.voip-
info.org/wiki/view/Realtime+Integration+Of+Asterisk+With+OpenSER.
#extensions.conf file
[default]
exten=>_9.,1,Dial(ZAP/g1/${EXTEN})
exten=>_9.,2,hangup()
exten=>_u.,1,Voicemail(u${EXTEN})
exten=>_u.,2,hangup()
exten=>_b.,1,Voicemail(b${EXTEN})

exten=>_b.,2,hangup()

Lab - Testando o encaminhamento de chamadas.


Este um laboratrio relativamente difcil de testar. Alguns telefones no do
ocupado, pois possuem vrias linhas. preciso ocupar vrias linhas at obter a
mensagem de 486 Busy. Reduzimos os tempos de timeout das mensagens de
INVITE para ter maior facilidade nos testes. Em ambientes de produo, remova estas
linhas.
Para criar este laboratrio preciso ter alguma experincia em configurar o Asterisk
para o correio de voz.
modparam("tm", "fr_timer", 5)
modparam("tm", "fr_inv_timer", 10)

Passo 1: Teste o siga-me se no atender:

8 | Encaminhamento de chamadas 146


ligue para o ramal 1002 a partir do 1000 e aguarde, ele deve cair no correio de voz
com a mensagem de no atende.
Passo 2: Teste o siga-me se ocupado:
Retire o fone 1003 do gancho. Ligue para o 1003 a partir do ramal 1000, ele deve ir
para o correio de voz com a mensagem de ocupado.

Sumrio
Neste captulo aprendemos como usar os pares atributo:valor para armazenarmos
dados referentes as preferncias dos usurios como siga-me. Usando o roteamento
em falhas, tratamos os trs tipos de situao mais comuns como usurio no
registrado, usurio no atende e usurio ocupado. Aprendemos como encaminhar
estes nmeros para uma mquina de correio de voz como o Asterisk.

147 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
9
Tcnicas de travessia de NAT

NAT, tambm conhecido como Network Address Translation, foi a soluo


encontrada para resolver a carncia de endereos IP prevista no meio dos anos 90. A
soluo consistia em usar uma pequena faixa de endereos IP (na maioria dos casos
um nico endereo) na porta externa de um firewall e uma faixa de endereos
invlidos (endereos reservados, definidos na RFC1918) na porta de dentro do
firewall.
Infelizmente o NAT atrapalha as comunicaes baseadas no protocolo SIP. Neste
captulo vamos explicar algumas formas de resolver o problema.
Ao final deste captulo voc estar apto :
Entender o problema causado pelo NAT nas comunicaes SIP
Descrever os vrios tipos de NAT e suas diferenas
Descrever os principais mecanismos de travessia de NAT
Diferenciar STUN, TURN e Alg.
Implantar um Media Relay Server
O NAT normalmente implantado em roteadores e firewalls. Um roteador NAT
mapeia seu endereo interno para um endereo externo mantendo uma tabela de
mapeamento. Algumas vezes, o Nat tambm chamado de PAT (Port Address
Translation). O PAT mantm um mapeamento de pares ip:porta permitindo que um
nico endereo externo seja usado para vrios endereos internos. Voc pode
pesquisar mais informaes na RFC1631.
A RFC1918 define uma alocao reservada para endereos privados. O espao de
endereamento privado definido como os blocos abaixo.
10.0.0.0 - 10.255.255.255 (10/8 prefix)
172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
Onde estamos?

The SIP provider MySQL/Postgres/


Big Picture Unixodbc Database

Ethernet

Media
User Radius
SIP PSTN Media Proxy CDRTool Monitoring
Portal Server Tools
Proxy Gateway Server Nat Rating
Provis. Traversal Acct.

Ethernet

CPE device (router)


Usually xDSL or
Cable
Internet Firewall
Customer Customer
Using an ATA Firewall
or Softphone

Tipos de NAT
Existem quatro tipos de NAT. Como definidos
Full Cone
Restricted Cone
Port Restricted Cone
Symmetric
Para um dado endereo interno, os trs primeiros tipos de NAT mantm um
mapeamento do seu endereo interno que independente do endereo de destino
sendo visto. O quarto tipo de NAT ir alocar um novo mapeamento para cada
endereo de destino de forma independente. A menos que haja uma tabela de
mapeamento esttico, o mapeamento aberto quando o primeiro pacote enviado de
um cliente atravs do NAT pode ser vlido apenas por certo tempo, tipicamente
alguns minutos, a menos que os pacotes continuem a ser enviados e recebidos em uma
porta IP.

Full Cone (Cone Completo)


No caso do Full Cone, o mapeamento bem estabelecido e qualquer um vindo da
Internet pblica que queira alcanar um cliente atrs do NAT, precisa apenas saber o
esquema de mapeamento de forma a mandar pacotes para ele.

149 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Por exemplo:
Um computador atrs de um NAT com IP 10.0.0.1 enviando e recebendo na porta
8000 mapeado para a porta externa IP no dispositivo NAT no endereo IP
200.180.4.168:1234. Qualquer um na Internet pode enviar pacotes para este endereo
e porta IP e estes pacotes sero passados para o cliente na mquina que est esperando
no endereo IP 10.0.0.1:8000.
o caso de Firewalls sem controle de sesso. Normalmente isto implantado atravs
de filtros de pacotes sendo o tipo menos seguro de firewall. Este tipo de firewall
cada vez menos comum nos dias de hoje.

Restricted Cone (Cone Restrito)


No caso de cone restrito, o par ip:porta externo s aberto uma vez que o
computador interno envie dados para um endereo IP de destino especfico.
Por exemplo:
No caso onde o cliente envia um pacote para um computador externo, o NAT mapeia
o cliente 10.0.0.1:8000 para o 200.180.4.168:1234. Assim o computador externo pode
enviar pacotes de volta. Entretanto o NAT ir bloquear pacotes vindos de outros
computadores externos.
Note que neste caso o Firewall tem controle sobre a sesso, esperando pacotes
pertencentes a uma sesso. Uma vez aberto, aquele computador pode iniciar qualquer
sesso independente da porta (200.210.1.1:3000 200.210.1.1:3001...).

Port Restricted Cone (Cone restrito por porta)


Um NAT do tipo port restricted quase idntico ao restricted Cone, mas neste
caso o NAT ir bloquear todos os pacotes a menos que o cliente tenha previamente
enviado um pacote para o IP e porta que est enviando para o NAT. Desta forma, se o
9 | Tcnicas de travessia de NAT 150
cliente enviar para um computador externo para a porta 1010, o NAT apenas ir
permitir pacotes de volta se eles vierem de 200.180.4.168 na porta 1010.
Neste caso o Firewall tem um controle maior da sesso, s permitindo que pacotes
pertencendo quela sesso possam retornar. Se o computador de destino resolver
enviar pacotes de um par ip:porta diferente, como por exemplo 200.210.1.1:10000,
estes no sero aceitos.

Simtrico

O ltimo tipo de NAT o simtrico, ele diferente dos trs primeiros. Um


mapeamento do ip:porta para um NAT pblico dependente do endereo de destino
para o qual o pacote enviado. Ento, por exemplo, se um cliente envia um pacote do
par ip:porta 10.0.0.1:8000 para o computador B, ele pode ser mapeado para o
ip:porta 200.180.4.168:1234. Se enviar da mesma porta para um endereo IP
diferente, ele mapeado de forma diferente 200.180.4.168:5678. Os computadores A
e B podem responder apenas para este mapeamento. Se qualquer um tentar enviar
para a outra porta mapeada, estes pacotes so descartados como no caso do tipo de
firewall conhecido como cone restrito. O par externo ip:porta aberto apenas
quando o computador interno envia dados para um destino especfico.

151 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Resumo dos tipos de Firewall
Tipos de NAT Precisa enviar possvel Ele restring os
dados antes de determinar o par pacotes de
receber ip:porta para os entrada para o
pacotes de retorno destino ip:porta

Cone No Sim No

Cone Restrito Sim Sim Apenas IP


Cone restrito na porta Sim Sim Sim

Simtrico Sim No Sim

Formas de Resolver o problema do NAT


Para resolver o problema de NAT precisamos dividir o problema em duas partes. A
primeira a sinalizao SIP, o que mais simples j que o SIP usa uma porta bem
conhecida (UDP 5060). A segunda resolver como passar a mdia atravs do
protocolo RTP. Este protocolo usa uma porta escolhida aleatoriamente o que torna
mais difcil a soluo. Os problemas com NAT podem ser resolvidos com solues
instaladas no cliente ou no servidor. As solues implantadas no cliente como STUN
e ICE s permitem resolver os problemas nos primeiros trs tipos de Firewall. J as
solues baseadas em servidor, tais como o Media Proxy e o RTP Proxy, permitem
que se resolva o problema em todos os tipos de firewall. No entanto as solues
baseadas em servidor exigem um maior investimento em equipamentos e banda
passante.

Soluo para a sinalizao SIP (RFC3581)


Independente do tipo de soluo adotada, vamos preparar nosso script para suportar
um padro bastante conhecido que a RFC3581.

RFC3581 and force_rport()


INVITE sip:4830258590@asteriskguide.com1 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.1:5060;;rport

INVITE sip:4830258590@asteriskguide.com SIP/2.0


Via: SIP/2.0/UDP 200.247.7.1:5060;branch=a5678432-fe567ea
Via: SIP/2.0/UDP 192.168.1.1:5060;received=200.215.1.1;rport=12400

SIP/2.0 200 OK
Via: SIP/2.0/UDP 200.247.7.1:5060;branch=a5678432-fe567ea
Via: SIP/2.0/UDP 192.168.1.1:5060;received=200.215.1.1;rport=12400
;branch=a5678432-fe567ea
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.1.1:5060;received=200.215.1.1;rport=12400
;branch=a5678432-fe567ea

200.215.1.1:12400
External address and port

Nat Device Nat Device

SIP Proxy
192.168.1.1:5060
UAC 200.247.7.1 UAC

9 | Tcnicas de travessia de NAT 152


Quando um cliente compatvel com a RFC3581, ele coloca um parmetro rport no
campo VIA do pedido SIP. O Proxy ao verificar a existncia do campo, inclui os
campos received= e rport= com o endereo e porta do qual recebeu o pacote. Com
isto fcil para o Proxy saber como encaminhar de volta para os dispositivos SIP. A
RFC3581 orienta tambm que se caso no ocorra uma resposta em um determinado
item, um novo pedido INVITE deve ser enviado permitindo que o dispositivo NAT
continue aberto. Na nossa soluo foraremos o uso do rport, mesmo que o cliente
no solicite. Isto resolve a discagem, mas no resolve a recepo de chamadas.

Resolvendo o problema de travessia dos pacotes RTP


O problema do SIP foi resolvido com as solues acima. Isto foi possvel porque o
protocolo SIP usa uma porta nica e previamente conhecida. J o RTP usa portas
dinmicas descritas no protocolo SDP (Session Description Protocol). Quando se usa
um dispositivo operando como NAT simtrico, um novo mapeamento ser criado para
cada destino. Desta forma no possvel informar de antemo ao UAC qual a porta
UDP que ser alocada para a comunicao. A soluo neste caso enviar ambas as
sesses de RTP diretamente para um dispositivo chamado Media Proxy com um
endereo IP e porta conhecidos. Neste dispositivo faz se uma ponte de udio de forma
que a comunicao seja possvel. Veja a figura abaixo.

Traversal of UDP over relay NAT


SIP Proxy
Valid IP with SIP UDP and TCP ports open
Symmetric NAT Device

Symmetric NAT Device

SIP SIP
SI
P P
SI
SDP
manipulation

RT P
P RT
RTP RTP

Media Proxy
Bridges de RTP flows
(registered IP address)

Quando voc usa um Media Proxya, que tambm conhecido como Media Relay
Server, ele conecta os dois fluxos de mdia vindo dos UACs. Por enquanto, o nico
meio de passar por um dispositivo operando como NAT simtrico. O script ir mudar
o endereo SDP para forar os pacotes de RTP sobre o Media Proxy usando a funo
use_media_proxy().

O Media Proxy desenvolvido pela AG-projects (www.ag-projects.com) no a nica


soluo para o componente chamado Media Relay Server. Voc pode tambm usar
outra soluo desenvolvida por Maxim Sobolev chamada RTP Proxy. O RTP Proxy
est sendo ativamente desenvolvido e mantido pela Sippy Software Inc.
(www.sippysoft.com), de onde voc pode fazer a descarga. Existem tambm
dispositivos chamados SBC (Session Border Controllers) que podem ser usados para
este propsito. Alguns so muito sofisticados e escalveis tais como aqueles
desenvolvidos pela Voice-Systems (VNT-10), ACME, NextPoint e Newport
Networks. O produto da Voice-System baseado em OpenSER (VNT-10).
153 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Eles podem conectar milhares de chamadas, mas no sem pagar um preo
normalmente bem salgado. Se voc est planejando ser um grande provedor de voz
eu recomendo que voc verifique as solues de SBC cuidadosamente.
Eu escolhi inicialmente o Media Proxy para este material por ele ser capaz de
balancear carga e desta forma suportar milhares de usurios. Ele pode ser integrado
com o mdulo de contabilizao para produzir resultados mais precisos. O nico
seno deste software que ele escrito em Python, uma linguagem interpretada, e
isto limita bastante o nmero de sesses simultneas em um nico servidor. O RTP
Proxy foi desenvolvido usando linguagem C e pode suportar at 10 vezes mais
usurios que o MediaProxy, infelizmente ele no possui uma forma de corrigir a
bilhetagem (dilogos sem a transao de BYE final). Ns no iremos cobrir o RTP
Proxy neste material, mas voc pode encontrar um arquivo compatvel com ele em:
www.sermyadmin.org/openser.rtpproxy.

O arquivo de instalao do MediaProxy informa que o sistema suporta cerca


de 80 sesses simultneas para cada Ghz de processamento.

Recebendo pedidos de registro atrs de NAT.


Para receber chamadas atrs de NAT precisamos usar alguns truques. O primeiro
modificar a forma de registro para os clientes que esto atrs de NAT. Abaixo as
principais modificaes necessrias.
1. Testar se o UAC est atrs de NAT, isto pode ser feito usando a funo
client_nat_test() e tambm se o pedido no para remover o registro de
todos os contatos (usando * no campo CONTACT do cabealho do pacote SIP).
2. Forar o uso do campo rport para obter o endereo IP correto na resposta do
UAC. Ver RFC3581.
3. Se o UAC estiver atrs de NAT corrigir o pedido de REGISTER com a funo
fix_nated_register(). Esta funo vai inserir o endereo IP recebido e porta
UDP na tabela de localizao.
4. Mantenha os mapeamentos de NAT usando o parmetro natping do mdulo
Media Proxy. Este parmetro usado para configurar um intervalo de tempo
entre o envio de pacotes UDP para manter os mapeamentos de NAT abertos.
5. Configurar um marcador (flag) especfico (seis no nosso exemplo) a ser salvo na
tabela de localizao. Isto ir ajudar mais tarde a determinar se o destino est
atrs de NAT.
Cdigo exemplo de tratamento do um pedido do tipo REGISTER
if (!search("^Contact:[ ]*\*") && client_nat_test("7")) {
setflag(6);
fix_nated_register();
force_rport();
}

Determinando se o cliente est atrs de NAT.


Existem duas funes que poderiam ser usadas para testar se um cliente est atrs de
NAT. Uma exportada pelo mdulo NATHELPER (parte da soluo RTP Proxy) e

9 | Tcnicas de travessia de NAT 154


outra exportada pelo mdulo MEDIAPROXY (parte da soluo Media Proxy). Note
que os primeiros trs testes para ambos os mdulos so semelhantes.
Funo client_nat_test()
o Exportada pelo mdulo MEDIAPROXY
o Parmetros
1 testa se o cliente tem um endereo RFC1918 no campo
CONTACT.
2 testa se o cliente contatou o OpenSER de um endereo
que diferente daquele encontrado no seu campo VIA.
4 testa se o cliente tem um endereo RFC1918 no seu
campo VIA mais alto.
Funo nat_uac_test()
o Exportado pelo modulo NATHELPER
o Parmetros
1 testa se o cliente tem um endereo RFC1918 no campo
CONTACT.
2 testa se o cliente contatou o OpenSER de um endereo
que diferente daquele encontrado no seu campo VIA.
4 testa se o cliente tem um endereo RFC1918 no seu
campo VIA mais alto.
8 Procura um endereo RFC1918 no cabealho SDP
16 Testa se a porta de origem diferente da porta
encontrada no campo VIA.

Voc deve especificar a soma dos testes a serem feitos. A funo ira retornar
verdadeiro se qualquer um dos testes der positivo. Se voc quiser fazer os testes 1,
2 e 4, por exemplo, especifique a soma, 7, como o parmetro da funo.

Mensagem do tipo INVITE atrs de NAT

INVITE request handling behind NAT


Step 1: test if the client is behind NAT
Step 2: Fix the contact() header field
Step 3: Force the rport (received port) in the VIA header field

if (client_nat_test("3")) {
xlog("L_INFO", "Route[3] M=$rm RURI=$ru F=$fu T=$tu IP=$si ID=$ci\n");
append_hf("P-hint: Route(3)- setflag7,forcerport,fix_contact \r\n");
setflag(7);
force_rport();
fix_contact()
};

155 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Nos pedidos do tipo REGISTER ns lidvamos apenas com o protocolo SIP. Agora
nas mensagens de INVITE temos de lidar com mensagens de SIP e RTP. Para isto
teremos de modificar os cabealhos SIP e SDP. Alm disso, a informao de contato
est errada, ela aponta para um endereo RFC1918. A funo fix_nated_contact()
exportada pelo modulo NATHELPER vai mudar o endereo do campo CONTACT
para o seu correspondente pblico. Outras mensagens como ACK, BYE e CANCEL
tambm precisam ser corrigidas.

RTP Handling behind NAT


Step 1: Force the RTP ,changing the line c= to the
mediaproxy server IP address

if (isflagset(6) || isflagset(7)) {
xlog("L_INFO", "Use mediaproxy: M=$rm RURI=$ru F=$fu T=$tu IP=$si ID=$ci\n");
append_hf("P-hint: Route[6]: mediaproxy \r\n");
use_media_proxy();
};

Quando uma mensagem de INVITE enviada, ela contem um cabealho SDP


embutido identificando o contedo da sesso (udio, vdeo, chat, named events...). O
cabealho SDP descreve vrias coisas sobre o UAC como, por exemplo, os tipos de
sesso que ele suporta, endereos IP e de porta UDP onde a outra parte pode encontr-
lo.
Exemplo:
Um UAC descreve o par ip:porta 192.168.0.1;23000 como o ponto onde ele quer
receber o fluxo de mdia atravs do protocolo RTP. No momento do pedido de
INVITE, no existe um mapeamento NAT correspondente ao par ip:porta. As linhas
do cabealho SDP descrevendo o endereo IP e a porta UDP esto descritas abaixo:
c=IN IP4 192.168.0.1.
m=audio 23767 RTP/AVP 0 101.

Para gerenciar as sesses de udio, o OpenSER ir fazer uma coisa antes de


encaminhar o INVITE para o usurio final, forar os pacotes com protocolo RTP
atravs do Media Proxy mudando a linha c para c=<endereo-ip-do-media-proxy>
RTP/AVP 0 101

No se esquea de configurar o Media Proxy com um endereo IP pblico em que


ambos os UACs podem contatar. Com o Media Proxy voc usa um salto adicional o
que tem implicaes na latncia e no jitter. Infelizmente a nica soluo prtica
disponvel no caso de um NAT simtrico.

9 | Tcnicas de travessia de NAT 156


Tratando as respostas
A mensagem 200 Ok retornada do UAC precisa ser manipulada tambm. Desta
forma o tratamento de NAT precisa ser includo na seo on_reply_route[]. Um
marcador (flag) foi configurado na mensagem de INVITE para indicar que esta
transao para ou de um cliente atrs de NAT. No tratamento da resposta, se
encontramos o marcador 6 ou 7 arrumamos o campo CONTACT usando o
fix_nated_contact() e foramos o RTP atravs do Media Proxy. importante
enfatizar que a mensagem 200 OK contm um cabealho SDP descrevendo os
parmetros da sesso acordados.

Instalao e configurao do Media Proxy


O Media Proxy ir permitir um processamento especializado dos clientes atrs de Nat.
O servidor Media Proxy de AG-Project possui as seguintes caractersticas:
Usa registros do tipo DNS SRV para balancear a carga dos pedidos
Ele pode ser executado em um servidor separado aliviando o SIP Proxy
Monitoramento pela Web
O servidor Media Proxy no est includo com o OpenSER. A distribuio do
OpenSER tem apenas o mdulo mediaproxy.so que se integra com o servidor media
Proxy. Para funcionar, voc precisa instalar o software e um endereo IP pblico.
Normalmente o Media Proxy no instalado no mesmo servidor do SIP Proxy.

Instalao propriamente dita


Baixe o arquivo de instalao do Media Proxy em:

cd /usr/local
wget http://mediaproxy.ag-projects.com/mediaproxy-1.8.2.tar.gz
tar xzvf mediaproxy-1.8.2.tar.gz

Coloque ele no boot usando :


cd /usr/local/mediaproxy/boot
cp mediaproxy.debian /etc/init.d/mediaproxy
update-rc.d mediaproxy defaults 20 90

O mediaproxy configurado atravs do arquivo mediaproxy.ini


cd /usr/local/mediaproxy
cp mediaproxy.ini.sample mediaproxy.ini
vi mediaproxy.ini

Edite o arquivo mediaproxy.ini e remova os comentrios


; Configuration file for MediaProxy

[Dispatcher]
;Section for configuring the proxy dispatcher
;
;The following options are available here:
;;start Boolean value that specifies if to start the dispatcher.
; Default value: Yes
;

157 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
; socket Path to the UNIX socket where the dispatcher receives commands
; from SER. This should match the value for mediaproxy_socket in
; openser.cfg. Use the keyword None to disable listening on a
; local socket.
; Default value: /var/run/proxydispatcher.sock
;
; listen Network address where the dispatcher receives commands from
; a remote Mediaproxy to close sessions for which media did
; timeout.
; Valid values for this are:
; - Default
; when using this keyword it will listen on 0.0.0.0:25061
; - address[:port]
; listen on the specified address and port
; address can be an IP a hostname or the keyword Any
; (in which case it will listen on 0.0.0.0). If address is
; a hostname, that should map in DNS to an IP address
; present on the machine, through an A record.
; If port is missing assume 25061.
;
; Default value: Default
;
; group Put the socket in this group and make it group writable.
; Default value: openser
;
; defaultProxy Default mediaproxy to use in case the From/To domains
; involved in the call don't define any.
; Valid values for this are:
;
; -None
; don't use any default proxies. domains without
; mediaproxy SRV records won't work
; -/path/to/unix/socket
; use a single MediaProxy server identified by the given
; UNIX socket path
; -IP_or_hostname[:port]
; use a single MediaProxy server identified by its network
; address. The network address consists of an IP address
; or a hostname and an optional port number separated by
; a double colon. If port is missing 25060 will be
; assumed.
; Examples:
; 10.0.0.1 (connect to 10.0.0.1 on port 25060)
; 10.0.0.1:90 (connect to 10.0.0.1 on port 90)
; mp1.mydomain.com
; mp1.mydomain.com:7000
; -domain://domain_name
; Use all MediaProxies defined by domain_name, honoring
; their priority and weight to create a cluster of
; proxies with fallback and load balancing capabilities.
;
; Default value: /var/run/mediaproxy.sock
;
;start = yes

9 | Tcnicas de travessia de NAT 158


;socket = /var/run/proxydispatcher.sock
;group = openser
;defaultProxy = /var/run/mediaproxy.sock

[MediaProxy]
;
; Section for configuring the MediaProxy server
;
; The following options are available here:
;
; start Boolean value that specifies if to start the RTP proxy server.
; Default value: Yes
;
; socket Path to the UNIX socket where MediaProxy receives commands
; from the dispatcher or SER. Use the keyword None to disable
; listening on a local socket.
; Default value: /var/run/mediaproxy.sock
;
; group Put the socket in this group and make it group writable.
; Default value: openser
;
; listen Network address where MediaProxy receives commands from
; a remote dispatcher.
; Valid values for this are:
;
; - None
; don't listen for network connections at all
; - address[:port]
; listen on the specified address and port
; address can be an IP a hostname or the keyword Any
; (in which case it will listen on 0.0.0.0). If address is
; a hostname, that should map in DNS to an IP address
; present on the machine, through an A record.
; If port is missing assume 25060.
;
; Default value: None
;
; allow List of addresses that are allowed to connect to this
; MediaProxy server and send commands.
; They are specified as a comma separated list of entries, with
; each entry being specified in the CIDR network/mask notation
; (ex. 10.0.0.0/8)
;
; In addition simple IP addresses or hostnames are allowed, in
; which case the mask is considered to be 32.
;
; In addition to network ranges/addresses 2 keywords can be used
; for this option:
; None to specify that none is allowed to connect (not very
; useful but this is the default for security reasons)
; Any to specify that anyone is allowed to connect
; (dangerous!)
;

159 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
; Example: allow = 10.0.0.0/24, home-pc.mydomain.com, 1.2.3.4
;
; Default value: None
;
; proxyIP IP address to use to talk to the phones. If not specified, the
; first found will be used. However first found usually means
; first defined in /etc/hosts which may not be what you want.
; If you find that the address that's automatically selected is
; not the one you want, you can specify the right one using this
; option. The address must be one that's present on one of the
; host's interfaces.
;
; portRange The range of ports to use for proxying the rtp streams.
; This option is specified as minport:maxport with minport and
; maxport being even numbers in the range 1024-65536
; Default value: 60000:65000
;
; TOS Mark all forwarded RTP packets with this specific TOS value.
; Unless you know what TOS means, leave this option alone.
; The TOS value can be specified either as a decimal number or
; as a hex number in the 0xnn format.
; Default value: 0xb8
;
; idleTimeout Expire idle sessions after this much time.
; Default 60 seconds
;
; holdTimeout Expire calls on hold after this much time.
; Default value is 3600 seconds
;
; forceClose Forcibly close a RTP session after this many seconds even
; if it's still active. If forceClose is 0, then
a session
; is never closed no matter how long it lasts.
; Default value: 0
;
start = yes
socket = /var/run/mediaproxy.sock
group = openser
;listen = None
;allow = None
proxyIP = 10.0.0.1
;portRange = 60000:65000
;TOS = 0xb8
;idleTimeout = 60
;holdTimeout = 3600
;forceClose = 0

[Accounting]
; one of none, radius or database
accounting = none

[Database]
user = dbuser
password = dbpass

9 | Tcnicas de travessia de NAT 160


host = dbhost
database = radius
table = radacct

[Radius]
secret = secret
server = localhost
authport = 1812
acctport = 1813
dictionaries = /etc/radiusclient-ng/dictionary,
/etc/openser/radius/dictionary, /usr/local/mediaproxy/dictionary
retries = 2

timeout = 3

A seo proxydispatcher uma seo avanada usada quando se deseja fazer


balanceamento de carga em servidores MediaProxy. Para o nosso caso vamos apenas
habilitar o MediaProxy para o socket /var/run/mediaproxy.

Anlise do arquivo openser.cfg


Copie o arquivo openser.chapter9 para openser.cfg. Vamos analisar as alteraes
necessrias no arquivo openser.cfg

Carga dos mdulos


Estes dois mdulos so responsveis pelas funes de tratamento de NAT. Do mdulo
NATHELPER usaremos as funes de testes de cliente para nat (nat_uac_test). As
outras funes viro do mediaproxy.

loadmodule "/usr/lib/openser/modules/nathelper.so"
loadmodule "/usr/lib/openser/modules/mediaproxy.so"

Parametrizao dos mdulos:


Como ns usamos o Media Proxy e no o RTP Proxy precisamos dizer ao mdulo
NATHELPER para no tentar executar um processo do rtpproxy. Se no fizermos isso
vamos ver vrias mensagens no log dizendo que o RTP Proxy no est carregado.
Alm disso, vamos desabilitar o mecanismo de ping do mdulo NATHELPER j que
vamos usar o disponvel no mdulo MEDIAPROXY.
modparam("nathelper", "rtpproxy_disable", 1)

modparam("nathelper", "natping_interval", 0)

Em seguida passamos alguns parmetros de configurao. A configurao abaixo


controla a freqncia com que nosso SIP Proxy pinga clientes SIP registrados. A
maioria dos NATs mantm os mapeamentos por um ou dois minutos, ento
especificamos 30 segundos na configurao. O OpenSER vai enviar a cada 30
segundos um pacote UDP de 4 bytes para os clientes.
modparam("mediaproxy","natping_interval", 30)

161 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
O OpenSER e o controlador do Media Proxy se comunicam via um socket padro do
Unix que especificado aqui.
modparam("mediaproxy","mediaproxy_socket", "/var/run/mediaproxy.sock")

O Media Proxy pode precisar conhecer quando um SIP UA assimtrico com respeito
sua porta SIP. A maioria dos UAs simtrica, em outras palavras eles recebem e
enviam as mensagens na mesma porta. Se voc encontrar clientes assimtricos que
no so manuseados corretamente, voc pode especificar seus cabealhos de User-
Agent neste local.
modparam("mediaproxy","sip_asymmetrics","/etc/openser/sip-clients")

O Media Proxy pode precisar saber se o UA assimtrico em relao a sua porta


RTP. Se voc encontrar clientes assimtricos que no so manuseados corretamente,
voc pode especificar seus cabealhos neste arquivo.
modparam("mediaproxy","rtp_asymmetrics","/etc/openser/rtp-clients")

Usamos o parmetro abaixo para permitir que o mdulo Registrar armazene o flag de
nmero 6 (arbitrariamente escolhido). Isto vai indicar na tabela de localizao que
este cliente est atrs de NAT
modparam("registrar", "nat_flag", 6)

Tratamento das mensagens de REGISTER


route[2] {
##--
# Register message handling
##--
sl_send_reply("100", "Trying");
if (!search("^Contact:[ ]*\*") && client_nat_test("7")) {
setflag(6);
fix_nated_register();
force_rport();

};

No tratamento do REGISTER se o client_nat_test() retorna verdadeiro, ento ns


devemos configurar o flag 6 para informar ao mdulo de registro que o cliente est
atrs de NAT. importante lembrar que ns s devemos invocar o
client_nat_test() se a mensagem SIP sendo processada contm um cabealho
CONTACT, seno devemos registrar um erro. Um ponto interessante a expresso
regular para o cabealho CONTACT que ^Contact:[ ]*\*. No apndice A voc
pode ter uma viso geral sobre expresses regulares.
Se o cliente est mesmo atrs de NAT, ento devemos registr-lo com seu verdadeiro
endereo IP, que o Endereo IP e Porta de onde a mensagem SIP veio. Esta
informao usada pelas chamadas subseqentes para encontrar o endereo pblicos
dos clientes SIP usando a funo lookup(location).
A funo fix_nated_register() usada especificamente para o processamento das
mensagens de REGISTER de clientes atrs de NAT. Esta funo diferente do
fix_nated_contact(), pois no vai alterar a URI no cabealho CONTACT. A funo
fix_nated_register() s vai adicionar alguns parmetros no cabealho CONTACT.

9 | Tcnicas de travessia de NAT 162


A funo force_rport() adiciona a porta IP recebida no cabealho mais alto da
mensagem SIP. Isto permite que mensagens subseqentes do SIP retornem a porta
apropriada em uma transao SIP posterior.

Tratamento das mensagens de INVITE


if (client_nat_test("3")) {
setflag(7);
force_rport();
fix_nated_contact();

};

As mensagens de INVITE tm um tratamento de NAT um pouco diferente em relao


s mensagens de REGISTER. Aqui testamos apenas para ver se as mensagens SIP
tm um endereo RFC1918 no campo CONTACT e se o UA contatou o OpenSER
por uma porta e endereo IP diferente do especificado no campo VIA. Se for
determinado que o cliente SIP esteja atrs de NAT, ento a flag 7 configurada para
referncia futura.
O client_nat_test() apenas determina se o emissor est atrs de NAT. Neste ponto
no openser.cfg ainda no determinamos se o receptor da mensagem est atrs de
NAT ou no. Adicionamos a porta recebida no cabealho VIA usando
force_rport(). Agora re-escrevemos o cabealho CONTACT com o par IP:Porta de
lado pblico do cliente SIP que est atrs do NAT.
if (!lookup("location")) {
sl_send_reply("404", "User Not Found");
exit;
};
route(6);

route(1);

Verificamos se o contato existe na nossa base de localizao antes de mand-lo para o


tratamento do NAT na seo route(4) e em seguida para o roteamento na seo
route(1).
route[6] {
##--
## Seo de travessia do NAT
##--
if (isflagset(6) || isflagset(7)) {
use_media_proxy();
};

A seo route[6] um bloco usado para habilitar o uso do Media Proxy no caso do
emissor (flag 7) ou o recipiente da mensagem (flag 6) estarem atrs de NAT.

Tratamento das mensagens de BYE e CANCEL


##--
## BYE and CANCEL message handling
##--
163 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
if (method=="BYE" || method=="CANCEL") {
end_media_session();

};

A qualquer hora que recebermos um BYE ou um CANCEL, devemos assumir que


para uma chamada que usou o Media Proxy. Ento, precisamos derrubar a sesso do
Media Proxy correspondente. seguro chamar a funo end_media_session() mesmo
para chamadas que no usam o Media Proxy.

Tratamento dos RE-INVITES


Ns usamos um recurso de embutir um indicador de NAT no cabealho original da
mensagem de INVITE. Fazendo isto ns olhamos para esta etiqueta especial no
reprocessamento das mensagens de RE-INVITE. Se encontramos esta etiqueta,
sabemos que temos de usar um Proxy para o protocolo RTP.
O modulo uri introduzido aqui para acessar a funo has_totag(). Esta funo
necessria para processar as mensagens de RE-INVITE e descrita mais a frente.
if(!is_method("REGISTER")){
if(nat_uac_test("19")){
record_route(";nat=yes");
} else {
record_route();
};

};

Se a mensagem recebida um INVITE e de um cliente SIP que esta atrs de um


NAT ns precisamos embutir uma flag especial para o NAT, que ser retornada ao
nosso SIP Proxy para o caso de um re-INVITE. Esta flag embutida pode ento ser
localizada na nossa lgica de processamento para determinar se o originador da
mensagem est atrs de NAT ou no.
Se a mensagem no um INVITE de um cliente SIP atrs de um NAT tambm no
e um REGISTER, ento chamamos apenas a funo record_route() para assegurar
que as futuras mensagens retornem pelo SIP Proxy.
# subsequent messages withing a dialog should take the
# path determined by record-routing
if (loose_route()) {
if(!has_totag()){
sl_send_reply("403", "Initial Loose-Routing Rejected");
exit;
};
if(nat_uac_test("19") || search("^Route:.*;nat=yes")){
append_hf("P-hint: Loose-Route - fixcontact,setflag6,mediaproxy
\r\n");
fix_contact();
setflag(6);
use_media_proxy();
};
route(1);

};

9 | Tcnicas de travessia de NAT 164


Nossa configurao precisar tratar as mensagens de RE-INVITE de forma a prevenir
que as sesses de RTP sejam derrubadas durante um RE-INVITE. De forma a
assegurar que estamos lidando apenas com re-INVITEs, ns usamos as funes
has_totag() e loose_route(). possvel para um INVITE original possuir
cabealhos de roteamento definidos, e isto faria com que a funo loose_route()
retornasse verdadeiro, assim para certificarmos que a mensagem um RE-INVITE,
devemos nos certificar que a o resultado da funo has_totag() tambm verdadeiro,
pois apenas chamadas conectadas tem uma etiqueta tag= no cabealho TO da
mensagem.
Em seguida verificamos o status do NAT de um RE-INVITE para ver se o originador
da mensagem est atrs de NAT ou no, chamando o teste client_nat_test(3).
Tambm verificamos se o cabealho ROUTE possui uma etiqueta embutida com o
texto ;nat=yes. Ela foi includa pela funo record_route() discutida anteriormente.
Se for descoberto que o cliente est atrs de NAT, configuramos o flag 6 para
referncia posterior. Este flag pode ento ser verificado na seo on_reply_route().
Em seguida fazemos o fluxo passar pelo RTP Proxy chamando a funo
use_media_proxy(). Isto vai fazer a comunicao com o Media Proxy externo fazendo
com que fiquem abertas ambas as portas UDP dos clientes, ou mantendo uma sesso
RTP existente baseado no cabealho CALL-ID. Quando voc usa a funo
use_media_proxy() isto faz com que o cabealho SDP seja re-escrito com o endereo
IP do Media Proxy com as respectivas portas alocadas.

Tratamento de mensagens para fora do nosso domnio


route[11] {
# from an internal domain -> outbound
# Simply route the call outbound using DNS search
append_hf("P-hint: inbound->outbound \r\n");
route(6);
route(1);

No evento de nossa mensagem no mais ser gerenciada pelo nosso SIP router,
chamamos nossa rotina de manuseio do NAT para habilitar o Media Proxy se
necessrio antes de enviar a mensagem para o seu destino.

Tratamento das respostas (on_reply_route).


Agora, ns teremos de gerenciar as mensagens de resposta (200, 180 e 183). Vamos
usar blocos do tipo onreply_route[] para isto. A primeira coisa a fazer marcar as
transaes para tratamento pelo bloco onreply_route[] antes de chamar a funo
t_relay(). Se a mensagem no pode ser encaminhada e a transao do tipo INVITE
ou ACK, preciso encerrar a sesso de mdia usando a funo end_media_session()
para liberar os recursos do servidor. .
route[1] {
t_on_reply("1");
if (!t_relay()) {
if (method=="INVITE" || method=="ACK") {
end_media_session();

165 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
};
sl_reply_error();
};
exit;

Nosso bloco on_reply_route[1] ir tratar as respostas geradas da rota 1. Quaisquer


mensagens tratadas aqui so respostas de uma transao existente. Vamos verificar
atravs de uma expresso regular das flags se a origem ou o destino esto atrs de
NAT e tambm se o contedo do tipo application/sdp (contm dados descritivos da
sesso). Se estas condies forem preenchidas chamaremos a funo
use_media_proxy() forando a passagem dos pacotes RTP atravs do Media Proxy.
onreply_route[1] {
if ((isflagset(6) || isflagset(7)) && (status=~"(180)|(183)|2[0-9][0-9]"))
{
if (!search("^Content-Type:[ ]*application/sdp")) {
use_media_proxy();
};
};
if (client_nat_test("1")) {
fix_nated_contact();
};

Roteamento
#
# $Id: openser.cfg 1676 2007-02-21 13:16:34Z bogdan_iancu $
#
# simple quick-start config script
# Please refer to the Core CookBook at
http://www.openser.org/dokuwiki/doku.php
# for a explanation of possible statements, functions and parameters.
#

# ----------- global configuration parameters ------------------------

debug=3 # debug level (cmd line: -dddddddddd)


fork=yes
log_stderror=no # (cmd line: -E)
children=4
port=5060

# ------------------ module loading ----------------------------------


#set module path
mpath="//lib/openser/modules/"

# Uncomment this if you want to use SQL database


#loadmodule "mysql.so"

loadmodule "mysql.so"
loadmodule "sl.so"

9 | Tcnicas de travessia de NAT 166


loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "uri.so"
loadmodule "uri_db.so"
loadmodule "domain.so"
loadmodule "permissions.so"
loadmodule "group.so"
loadmodule "mi_fifo.so"
loadmodule "lcr.so"
loadmodule "avpops.so"
loadmodule "xlog.so"
loadmodule "nathelper.so"
loadmodule "mediaproxy.so"

# Uncomment this if you want digest authentication


# mysql.so must be loaded !
loadmodule "auth.so"
loadmodule "auth_db.so"

# ----------------- setting module-specific parameters ---------------

modparam("mi_fifo", "fifo_name", "/tmp/openser_fifo")


modparam("registrar", "received_avp", "$avp(i:42)")
modparam("usrloc", "db_mode", 2)
modparam("usrloc", "nat_bflag", 4)
modparam("auth_db", "calculate_ha1", 1)
modparam("auth_db", "password_column", "password")
modparam("rr", "enable_full_lr", 1)
modparam("auth_db|permissions|uri_db|usrloc","db_url","mysql://openser:opens
errw@localhost/openser")
modparam("permissions", "db_mode", 1)
modparam("permissions", "trusted_table", "trusted")
modparam("avpops", "avp_url", "mysql://openser:openserrw@localhost/openser")
modparam("avpops", "avp_table", "usr_preferences")
modparam("nathelper","rtpproxy_disable", 1)
modparam("nathelper","natping_interval", 0)
modparam("nathelper","received_avp", "$avp(i:42)")
modparam("mediaproxy","natping_interval",20)
modparam("mediaproxy","mediaproxy_socket", "/var/run/mediaproxy.sock")
modparam("mediaproxy","sip_asymmetrics","/etc/openser/sip-clients")
modparam("mediaproxy","rtp_asymmetrics","/ect/openser/rtp-clients")

# ------------------------- request routing logic -------------------

# main routing logic

route{

167 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
# -- 1 -- Request Validation
#
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};

if (msg:len >= 2048 ) {


sl_send_reply("513", "Message too big");
exit;
};

#
# -- 2 -- Routing Preprocessing
#
## Record-route all except Register
## Mark packets with nat=yes
## This mark will be used to identify the request in the loose
## route section
if(!is_method("REGISTER")){
if(nat_uac_test("19")){
record_route(";nat=yes");
} else {
record_route();
};
};

##Loose_route packets
if (has_totag()) {
#sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
#Check authentication of re-invites
if(method=="INVITE" && (!allow_trusted())) {
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","1");
exit;
} else if (!check_from()) {
sl_send_reply("403", "Forbidden, use From=ID");
exit;
};
};
if(method=="BYE" || method=="CANCEL") {
end_media_session();
};
##Detect requests in the dialog behind NA, flag with 6
if(nat_uac_test("19") || search("^Route:.*;nat=yes")){
append_hf("P-hint: LR|fixcontact,setflag6\r\n");
fix_contact();
setbflag(6);
};
route(1);
} else {
sl_send_reply("404","Not here");

9 | Tcnicas de travessia de NAT 168


}
exit;
}

#CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans()) {
end_media_session();
t_relay();
};
exit;
}

t_check_trans();
#
# -- 3 -- Determine Request Target
#
if (method=="REGISTER") {
route(2);
} else {
route(3);
};
}

route[1] {
#
# -- 4 -- Forward request to target
#
# Forward statefully
t_on_reply("1");
t_on_failure("1");
if (!t_relay()) {
sl_reply_error();
};
exit;
}

route[2] {
## Register request handler
if (is_uri_host_local()) {
if (!www_authorize("", "subscriber")) {
www_challenge("", "1");
exit;
};

if (!check_to()) {
sl_send_reply("403", "Forbidden");
exit;
};

if(!search("^Contact:[ ]*\*") && client_nat_test("7")) {


setbflag(6);

169 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
fix_nated_register();
force_rport();
};
save("location");
exit;

} else if {

sl_send_reply("403", "Forbidden");

};
}

route[3] {
## Requests handler
if (is_from_local()){
# From an internal domain -> check the credentials and the FROM
if(!allow_trusted()){
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","0");
exit;
} else if(!check_from()) {
sl_send_reply("403", "Forbidden, use From=ID");
exit;
};
};

if (client_nat_test("3")) {
append_hf("P-hint: setflag7|forcerport|fix_contact\r\n");
setbflag(7);
force_rport();
fix_contact();
};

#unconditional call forward


if(avp_db_load("$ru/username","$avp(s:callfwd)")) {
avp_pushto("$ru", "$avp(s:callfwd)");
route(1);
exit;
}

consume_credentials();

#verify aliases, if found replace R-URI.


lookup("aliases");

if (is_uri_host_local()) {
# -- Inbound to Inbound
route(10);
} else {
# -- Inbound to outbound
route(11);
};

9 | Tcnicas de travessia de NAT 170


} else {

#From an external domain ->do not check credentials


#Verify aliases, if found replace R-URI.
lookup("aliases");
if (is_uri_host_local()) {
#-- Outbound to inbound
route(12);
} else {
# -- Outbound to outbound
route(13);
};
};
}

route[4] {
# routing to the public network
if (!load_gws()) {
sl_send_reply("503", "Unable to load gateways");
exit;
}

if(!next_gw()){
sl_send_reply("503", "Unable to find a gateway");
exit;
}
t_on_failure("2");
if (!t_relay()) {
sl_reply_error();
};
exit;
}

route[6] {
#
# -- NAT handling --
#
if (isbflagset(6) || isbflagset(7)) {
append_hf("P-hint: Route[6]: mediaproxy \r\n");
use_media_proxy();
};
}

route[10] {
#from an internal domain -> inbound
#Native SIP destinations are handled using the location table
#Gateway destinations are handled by regular expressions
append_hf("P-hint: inbound->inbound \r\n");

if (uri=~"^sip:[2-9][0-9]{6}@") {
if (is_user_in("credentials","local")) {
prefix("+1305");
route(6);

171 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for local calls");
exit;
};
};

if (uri=~"^sip:1[2-9][0-9]{9}@") {
if (is_user_in("credentials","ld")) {
strip(1);
prefix("+1");
route(6);
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for long distance");
exit;
};
};

if (uri=~"^sip:011[0-9]*@") {
if (is_user_in("credentials","int")) {
strip(3);
prefix("+");
route(6);
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for international calls");
};
};

if (!lookup("location")) {
if (does_uri_exist()) {
## User not registered at this time.
## Use the IP Address of your e-mail server
revert_uri();
prefix("u");
rewritehostport("192.168.1.171"); #Use the IP address of your
voicemail server
route(6);
route(1);
} else {
sl_send_reply("404", "Not Found");
exit;
}
sl_send_reply("404", "Not Found");
exit;
};
route(6);
route(1);
}

9 | Tcnicas de travessia de NAT 172


route[11] {
# from an internal domain -> outbound
# Simply route the call outbound using DNS search
append_hf("P-hint: inbound->outbound \r\n");
route(1);
}

route[12] {
# From an external domain -> inbound
# Verify aliases, if found replace R-URI.
lookup("aliases");
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

route[13] {
#From an external domain outbound
#we are not accepting these calls
append_hf("P-hint: outbound->inbound \r\n");
sl_send_reply("403", "Forbidden");
exit;
}

failure_route[1] {
##--
##-- If cancelled, exit.
##--
if (t_was_cancelled()) {
exit;
};
##--
##-- If busy send to the e-mail server, prefix the "b"
##-- character to indicate busy.
##--
if (t_check_status("486")) {
revert_uri();
prefix("b");
rewritehostport("192.168.1.171");
append_branch();
route(1);
exit;
};
##--
##-- If timeout (408) or unavailable temporarily (480),
##-- prefix the uri with the "u"character to indicate
##-- unanswered and send to the e-mail
##-- sever
##--
if (t_check_status("408") || t_check_status("480")) {
revert_uri();

173 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
prefix("u");
rewritehostport("192.168.1.171");
append_branch();
route(1);
exit;
};
}

failure_route[2] {
if(!next_gw()) {
t_reply("503", "Service not available, no more gateways");
exit;
};
t_on_failure("2");
t_relay();
}

onreply_route[1] {
#
#-- On-replay block routing --
#
if (client_nat_test("1")) {
append_hf("P-hint: Onreply-route - fixcontact \r\n");
fix_contact();
};

if ((isbflagset(6) || isbflagset(7)) && (status=~"(180)|(183)|2[0-9][0-


9]")) {
if (search("^Content-Type:[ ]*application/sdp")) {
append_hf("P-hint: onreply_route|usemediaproxy \r\n");
use_media_proxy();
};
};
exit;
}

9 | Tcnicas de travessia de NAT 174


Representao grfica do script

Seqncia dos pacotes


U 8.8.3.80:62003 -> 8.8.3.48:5060
INVITE sip:1000@8.8.3.48 SIP/2.0.
Via: SIP/2.0/UDP 192.168.0.111:5060;branch=z9hG4bK31390;rport.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 1 INVITE.
Contact: <sip:1001@192.168.0.111:5060>.
max-forwards: 70.
supported: 100rel.
user-agent: Voip Phone 1.0.
Allow: INVITE, ACK, OPTIONS, BYE, CANCEL, REFER, NOTIFY, SUBSCRIBE, PRACK,
UPDATE.
Content-Type: application/sdp.
Content-Length: 295 .
.
v=0.
o=sdp_admin 30472538 21739392 IN IP4 192.168.0.111.
s=A conversation.
c=IN IP4 192.168.0.111.
t=0 0.
m=audio 10050 RTP/AVP 0 4 18 8 101.
a=rtpmap:0 PCMU/8000.
a=rtpmap:4 G723/8000.
a=rtpmap:18 G729/8000.
a=rtpmap:8 PCMA/8000.
a=rtpmap:101 telephone-event/8000.

175 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
a=fmtp:101 0-15.
a=sendrecv.

U 8.8.3.48:5060 -> 8.8.3.80:62003


SIP/2.0 407 Proxy Authentication Required.
Via: SIP/2.0/UDP
192.168.0.111:5060;branch=z9hG4bK31390;rport=62003;received=8.8.3.80.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>;tag=50304af8547890328f8e4533797682df.822e.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 1 INVITE.
Proxy-Authenticate: Digest realm="8.8.3.48",
nonce="4682071833d18d202024678d258908fef07a049b", qop="auth".
Server: OpenSer (1.1.0-notls (i386/linux)).
Content-Length: 0.
Warning: 392 8.8.3.48:5060 "Noisy feedback tells: pid=3053
req_src_ip=8.8.3.80 req_src_port=62003 in_uri=sip:1000@8.8.3.48
out_uri=sip:1000@8.8.3.48 via_cnt==1".
.

U 8.8.3.80:62003 -> 8.8.3.48:5060


ACK sip:1000@8.8.3.48 SIP/2.0.
Via: SIP/2.0/UDP 192.168.0.111:5060;branch=z9hG4bK31390;rport.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>;tag=50304af8547890328f8e4533797682df.822e.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 1 ACK.
max-forwards: 70.
Content-Length: 0.
.

U 8.8.3.80:62003 -> 8.8.3.48:5060


INVITE sip:1000@8.8.3.48 SIP/2.0.
Via: SIP/2.0/UDP 192.168.0.111:5060;branch=z9hG4bK28696;rport.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 2 INVITE.
Contact: <sip:1001@192.168.0.111:5060>.
Proxy-Authorization: Digest username="1001", realm="8.8.3.48",
nonce="4682071833d18d202024678d258908fef07a049b", uri="sip:1000@8.8.3.48",
response="04e92e136fc8143af3c0992b01777688", algorithm=MD5,
cnonce="234abcc436e26670", qop=auth, nc=00000001.
max-forwards: 70.
supported: 100rel.
user-agent: Voip Phone 1.0.
Allow: INVITE, ACK, OPTIONS, BYE, CANCEL, REFER, NOTIFY, SUBSCRIBE, PRACK,
UPDATE.
Content-Type: application/sdp.
Content-Length: 295 .
.

9 | Tcnicas de travessia de NAT 176


v=0.
o=sdp_admin 30472538 21739392 IN IP4 192.168.0.111.
s=A conversation.
c=IN IP4 192.168.0.111.
t=0 0.
m=audio 10050 RTP/AVP 0 4 18 8 101.
a=rtpmap:0 PCMU/8000.
a=rtpmap:4 G723/8000.
a=rtpmap:18 G729/8000.
a=rtpmap:8 PCMA/8000.
a=rtpmap:101 telephone-event/8000.
a=fmtp:101 0-15.
a=sendrecv.

U 8.8.3.48:5060 -> 8.8.3.80:62003


SIP/2.0 100 trying -- your call is important to us.
Via: SIP/2.0/UDP
192.168.0.111:5060;branch=z9hG4bK28696;rport=62003;received=8.8.3.80.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 2 INVITE.
Server: OpenSer (1.1.0-notls (i386/linux)).
Content-Length: 0.
Warning: 392 8.8.3.48:5060 "Noisy feedback tells: pid=3052
req_src_ip=8.8.3.80 req_src_port=62003 in_uri=sip:1000@8.8.3.48
out_uri=sip:1000@192.168.0.100:5060 via_cnt==1".
.

U 8.8.3.48:5060 -> 8.8.3.91:60166


INVITE sip:1000@192.168.0.100:5060 SIP/2.0.
Record-Route: <sip:8.8.3.48;lr=on;ftag=2824524117;nat=yes>.
Via: SIP/2.0/UDP 8.8.3.48;branch=z9hG4bK3094.efbe1187.0.
Via: SIP/2.0/UDP
192.168.0.111:5060;received=8.8.3.80;branch=z9hG4bK28696;rport=62003.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 2 INVITE.
Contact: <sip:1001@8.8.3.80:62003>.
max-forwards: 69.
supported: 100rel.
user-agent: Voip Phone 1.0.
Allow: INVITE, ACK, OPTIONS, BYE, CANCEL, REFER, NOTIFY, SUBSCRIBE, PRACK,
UPDATE.
Content-Type: application/sdp.
Content-Length: 290.
P-hint: route[3] - setflag7,forcerport,fix_contact .
P-hint: route[5] - usemediaproxy .
.
v=0.

177 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
o=sdp_admin 30472538 21739392 IN IP4 192.168.0.111.
s=A conversation.
c=IN IP4 8.8.3.48.
t=0 0.
m=audio 60012 RTP/AVP 0 4 18 8 101.
a=rtpmap:0 PCMU/8000.
a=rtpmap:4 G723/8000.
a=rtpmap:18 G729/8000.
a=rtpmap:8 PCMA/8000.
a=rtpmap:101 telephone-event/8000.
a=fmtp:101 0-15.
a=sendrecv.

U 8.8.3.91:60166 -> 8.8.3.48:5060


SIP/2.0 100 Trying.
Via: SIP/2.0/UDP 8.8.3.48;branch=z9hG4bK3094.efbe1187.0.
Via: SIP/2.0/UDP
192.168.0.111:5060;received=8.8.3.80;branch=z9hG4bK28696;rport=62003.
Record-Route: <sip:8.8.3.48;lr=on;ftag=2824524117;nat=yes>.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 2 INVITE.
Content-Length: 0.
.

U 8.8.3.91:60166 -> 8.8.3.48:5060


SIP/2.0 180 Ringing.
Via: SIP/2.0/UDP 8.8.3.48;branch=z9hG4bK3094.efbe1187.0.
Via: SIP/2.0/UDP
192.168.0.111:5060;received=8.8.3.80;branch=z9hG4bK28696;rport=62003.
Record-Route: <sip:8.8.3.48;lr=on;ftag=2824524117;nat=yes>.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>;tag=914020329.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 2 INVITE.
Contact: <sip:1000@192.168.0.100:5060>.
Content-Length: 0.
.

U 8.8.3.48:5060 -> 8.8.3.80:62003


SIP/2.0 180 Ringing.
Via: SIP/2.0/UDP
192.168.0.111:5060;received=8.8.3.80;branch=z9hG4bK28696;rport=62003.
Record-Route: <sip:8.8.3.48;lr=on;ftag=2824524117;nat=yes>.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>;tag=914020329.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 2 INVITE.
Contact: <sip:1000@8.8.3.91:60166>.
Content-Length: 0.

9 | Tcnicas de travessia de NAT 178


P-hint: Onreply-route - fixcontact .
.

U 8.8.3.91:60166 -> 8.8.3.48:5060


SIP/2.0 200 OK.
Via: SIP/2.0/UDP 8.8.3.48;branch=z9hG4bK3094.efbe1187.0.
Via: SIP/2.0/UDP
192.168.0.111:5060;received=8.8.3.80;branch=z9hG4bK28696;rport=62003.
Record-Route: <sip:8.8.3.48;lr=on;ftag=2824524117;nat=yes>.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>;tag=914020329.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 2 INVITE.
Contact: <sip:1000@192.168.0.100:5060>.
supported: replaces.
Content-Type: application/sdp.
Content-Length: 239 .
.
v=0.
o=sdp_admin 30091196 10973278 IN IP4 192.168.0.100.
s=A conversation.
c=IN IP4 192.168.0.100.
t=0 0.
m=audio 10052 RTP/AVP 0 4 18 8.
a=rtpmap:0 PCMU/8000.
a=rtpmap:4 G723/8000.
a=rtpmap:18 G729/8000.
a=rtpmap:8 PCMA/8000.
a=sendrecv.

U 8.8.3.48:5060 -> 8.8.3.80:62003


SIP/2.0 200 OK.
Via: SIP/2.0/UDP
192.168.0.111:5060;received=8.8.3.80;branch=z9hG4bK28696;rport=62003.
Record-Route: <sip:8.8.3.48;lr=on;ftag=2824524117;nat=yes>.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>;tag=914020329.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 2 INVITE.
Contact: <sip:1000@8.8.3.91:60166>.
supported: replaces.
Content-Type: application/sdp.
Content-Length: 234.
P-hint: Onreply-route - fixcontact .
P-hint: Onreply-route - usemediaproxy .
.
v=0.
o=sdp_admin 30091196 10973278 IN IP4 192.168.0.100.
s=A conversation.
c=IN IP4 8.8.3.48.
t=0 0.

179 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
m=audio 60012 RTP/AVP 0 4 18 8.
a=rtpmap:0 PCMU/8000.
a=rtpmap:4 G723/8000.
a=rtpmap:18 G729/8000.
a=rtpmap:8 PCMA/8000.
a=sendrecv.

U 8.8.3.80:62003 -> 8.8.3.48:5060


ACK sip:1000@8.8.3.91:60166 SIP/2.0.
Via: SIP/2.0/UDP 192.168.0.111:5060;branch=z9hG4bK17145.
Route: <sip:8.8.3.48;lr=on;ftag=2824524117;nat=yes>.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>;tag=914020329.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 2 ACK.
max-forwards: 70.
user-agent: Voip Phone 1.0.
Content-Length: 0.
.

U 8.8.3.48:5060 -> 8.8.3.91:60166


ACK sip:1000@8.8.3.91:60166 SIP/2.0.
Record-Route: <sip:8.8.3.48;lr=on;ftag=2824524117;nat=yes>.
Via: SIP/2.0/UDP 8.8.3.48;branch=z9hG4bK3094.efbe1187.2.
Via: SIP/2.0/UDP 192.168.0.111:5060;received=8.8.3.80;branch=z9hG4bK17145.
From: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
To: 1000 <sip:1000@8.8.3.48>;tag=914020329.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 2 ACK.
max-forwards: 69.
user-agent: Voip Phone 1.0.
Content-Length: 0.
P-hint: Loose-Route - fixcontact,setflag6 .
.

U 8.8.3.91:60166 -> 8.8.3.48:5060


BYE sip:1001@8.8.3.80:62003 SIP/2.0.
Via: SIP/2.0/UDP 192.168.0.100:5060;branch=z9hG4bK29815;rport.
Route: <sip:8.8.3.48;lr=on;ftag=2824524117;nat=yes>.
From: 1000 <sip:1000@8.8.3.48>;tag=914020329.
To: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 1 BYE.
max-forwards: 70.
user-agent: Voip Phone 1.0.
Content-Length: 0.
.

U 8.8.3.48:5060 -> 8.8.3.80:62003


BYE sip:1001@8.8.3.80:62003 SIP/2.0.

9 | Tcnicas de travessia de NAT 180


Record-Route: <sip:8.8.3.48;lr=on;ftag=914020329;nat=yes>.
Via: SIP/2.0/UDP 8.8.3.48;branch=z9hG4bK6094.da62cfc5.0.
Via: SIP/2.0/UDP
192.168.0.100:5060;received=8.8.3.91;branch=z9hG4bK29815;rport=60166.
From: 1000 <sip:1000@8.8.3.48>;tag=914020329.
To: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 1 BYE.
max-forwards: 69.
user-agent: Voip Phone 1.0.
Content-Length: 0.
P-hint: Loose-Route - fixcontact,setflag6 .
.

U 8.8.3.80:62003 -> 8.8.3.48:5060


SIP/2.0 200 OK.
Via: SIP/2.0/UDP 8.8.3.48;branch=z9hG4bK6094.da62cfc5.0.
Via: SIP/2.0/UDP
192.168.0.100:5060;received=8.8.3.91;branch=z9hG4bK29815;rport=60166.
Record-Route: <sip:8.8.3.48;lr=on;ftag=914020329;nat=yes>.
From: 1000 <sip:1000@8.8.3.48>;tag=914020329.
To: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 1 BYE.
Contact: <sip:1001@192.168.0.111:5060>.
Content-Length: 0.
.

U 8.8.3.48:5060 -> 8.8.3.91:60166


SIP/2.0 200 OK.
Via: SIP/2.0/UDP
192.168.0.100:5060;received=8.8.3.91;branch=z9hG4bK29815;rport=60166.
Record-Route: <sip:8.8.3.48;lr=on;ftag=914020329;nat=yes>.
From: 1000 <sip:1000@8.8.3.48>;tag=914020329.
To: 1001 <sip:1001@8.8.3.48>;tag=2824524117.
Call-ID: 38476419-134726572@192.168.0.111.
CSeq: 1 BYE.
Contact: <sip:1001@8.8.3.80:62003>.
Content-Length: 0.

P-hint: Onreply-route - fixcontact

LAB Usando o mediaproxy para travessia de NAT.


Testar a travessia de NAT no das tarefas mais fceis. Este laboratrio pode ser feito
de duas formas. A primeira em bancada usando um Firewall simples como abaixo:

181 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Ambiente do Laboratrio
PC com Linux
Instalado e
OpenSER
SIP - Proxy

Internet
Firewall 1 Firewall 2

Adaptador de
Telefonia
Analgica

Estao de
trabalho com
Softfone

Passo 1: Copie o arquivo openser.chapter9 para /etc/openser/openser.cfg


cd /etc/openser
wget http://www.sermyadmin.org/openser/openser.chapter9
cp openser.chapter9 openser.cfg

Passo 2: Descarregue e descompacte o servidor Media Proxy da AG-projects para o


diretrio /usr/src.
cd /usr/arc
wget http://mediaproxy.ag-projects.com/mediaproxy-1.8.2.tar.gz
tar xzvf mediaproxy-1.8.2.tar.gz

Passo 3: Instale o Python se ele j no estiver instalado.


apt-get install python

Passo 4: Edite o arquivo mediaproxy.ini conforme descrito na seo anterior


vi mediaproxy.ini

Passo 5: Inicie o processo do mediaproxy


./mediaproxy.py

Passo 6: Monte o seu laboratrio e register os telephones 1000 e 1001 atrs dos
dispositivos NAT.
Passo 7: Use o ngrep para capturar todos os pacotes
ngrep p q W byline port 5060

Passo 8: Teste a configurao discando do telefone 1000 para o 1001


Passo 9: Verifique a passagem dos fluxos RTP usando:
/usr/local/mediaproxy/sessions.py

Usando STUN
A travessia simples do UDP sobre NAT ou simplesmente STUN um dos mtodos
mais comuns para travessia de NAT implantada nos clientes. Ele definido na

9 | Tcnicas de travessia de NAT 182


RFC3489. A maior vantagem de usar o STUN que os clientes parecem estar na
Internet do ponto de vista do SIP Proxy. Nenhum tratamento especial necessrio no
servidor. A grande desvantagem do STUN no permitir a passagem por dispositivos
com NAT simtrico.
O protocolo STUN permite que os dispositivos finais descubram seus endereos IP e
portas. Com esta informao o dispositivo pode informar a outra parte em que
endereo se encontra e pode ser contatado.
O protocolo relativamente complexo, com vrias mensagens. Ele permite que se
verifique se o cliente est:
Em uma Internet aberta
Atrs de um firewall que bloqueia o UDP
Se ele est atrs de NAT e que tipo de dispositivo este.
No diagrama abaixo, todos os resultados em caixas vermelhas pode ser contornados
usando STUN. As outras situaes podem apenas ser atravessadas com a soluo de
Media Proxy

How STUN works


(excerpt adapted from the RFC3489)
Test I. Send a binding request without any flag. The server responds in the same IP:port sent.
Test II.Send a binindg request with change IP and change port flags. Respond with different IP and port
Test III. Send a binindg request with just the change port flag. Response in a different port

Test I

No yes yes
No
UDP Blocked Response? Same IP? Test II
NAT
No

No
NAT Symmetric
Full Cone Response?
Detected Firewall
Yes
Yes
Test I No
2nd IP Response? Test II Open Internet
Address

yes
yes
Symmetric No Test
Same IP? Response Restricted
NAT III
No

Port restricted

Voc pode implantar o STUN usando um servidor Linux com o software da


VOVIDA. Voc vai precisar de um servidor e dois endereos pblicos. O servidor
STUN da VOVIDA pode ser baixado de www.vovida.org.
possvel testar o STUN sem instalar um servidor, simplesmente use um servidor
STUN pblico. Uma pequena lista de servidores pblicos pode ser encontrada em
http://www.voip-info.org/wiki-STUN.

183 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Se voc usar o STUN no cliente, no ser necessrio fazer quaisquer
mudanas no script openser.cfg. Ele trabalha como se os clientes estivessem
conectados Internet

Porque o STUN no funciona com NAT simtrico?


A principal caracterstica de um dispositivo de NAT simtrico criar um novo
mapeamento para cada dispositivo externo conectado. Ento, se voc entrar em
contato com o dispositivo STUN ele ir informar a voc o par ip:porta do qual ele foi
contatado. Infelizmente este no ser o par ip:porta que ser criado para contatar
quaisquer outros dispositivos.
Nos primeiros trs tipos de NAT (Cone, restricted e port restricted) o mapeamento
criado para um dispositivo exatamente o mesmo para os outros, desde que o par
ip:porta interno permanea o mesmo.

ALG Application Layer Gateways


Outro mtodo muito comum o ALG. Vrios dispositivos NAT principalmente os
Firewalls implantar algum tipo de tratamento dos pacotes de SIP. Neste caso o
dispositivo NAT altera os cabealhos para fazer com que os pacotes paream estar
vindos da interface externa. Da minha experincia pessoal, as implantaes do ALG
no so muito boas. Existem casos onde o pacote SIP corrompido e alguns onde o
gateway tem o seu desempenho comprometido pela soluo. importante estar atento
para dispositivos com ALG na sua rede. Quando algo no est funcionando bem, este
um lugar importante para se verificar.

ICE (Interactive Connection Establishment)


O ICE um dos protocolos mais novos usados na travessia do NAT. O ICE usa todos
os endereos disponveis para verificar que endereos possuem conectividade. Ele usa
a melhor soluo possvel evitando a reconfigurao do cliente.

Sumrio
Neste captulo voc foi apresentado os diferentes tipos de NAT. Voc entendeu as
implicaes de dispositivos com NAT simtrico e tambm quando usar STUN ou
TURN. No final teve a oportunidade de implantar uma soluo baseada no software
Media Proxy que resolve os problemas mais comuns de travessia de NAT.

9 | Tcnicas de travessia de NAT 184


Pgina deixada intencionalmente em branco

185 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
10
Bilhetagem usando Radius e
CDRTool

Neste captulo vamos primeiro aprender a instalar a contabilizao. Ela vai medir a
durao das ligaes a partir do estabelecimento da chamada at o seu encerramento.
Vamos comear com a contabilizao das chamadas usando o MySQL por ser mais
simples. Depois vamos aumentar o grau de dificuldade contabilizando as chamadas
em um servidor Radius. importante entender que a contabilizao s computa o
nmero de minutos da chamada. preciso uma ferramenta de tarifao (rating) que
permita aplicar valores as chamadas. Na ltima parte deste captulo vamos instalar
uma ferramenta de tarifao no nosso servidor.
Ao final deste captulo o leitor deve estar apto :
Habilitar a bilhetagem no MySQL
Habilitar a bilhetagem em um servidor Radius
Fazer a tarifao dos bilhetes usando CDRTool

Onde estamos?
Ns vamos trabalhar na parte de bilhetagem do sistema. O Proxy j est funcionando
bem, completando chamadas entre usurios e gateways. No entanto, ns ainda no
estamos bilhetando as chamadas. A bilhetagem um processo em duas fases. Na
primeira, determinamos a durao da chamada. Isto feito atravs de Radius ou
MySQL. A segunda fase colocar um preo na chamada. Ns iremos usar o
CDRTool, uma ferramenta em cdigo livre para nos ajudar com esta tarefa.
The SIP provider MySQL/Postgres/
Big Picture Unixodbc Database

Ethernet

Media
User Radius
SIP PSTN Media Proxy CDRTool Monitoring
Portal Server Tools
Proxy Gateway Server Nat Rating
Provis. Traversal Acct.

Ethernet

CPE device (router)


Usually xDSL or
Cable
Internet Firewall
Customer Customer
Using an ATA Firewall
or Softphone

Como feita a contabilizao


O servidor VoIP usa o conceito de AAA (Autenticao, Autorizao e Bilhetagem).
At agora, ns usamos o MySQL apenas para autenticar e autorizar os usurios. Ns
podemos usar o MySQL ou o Radius para armazenar os dados de contabilizao.
mais fcil trabalhar com o Radius, porque ele usa um pacote de inicio da bilhetagem
(account-start) para cada INVITE e um pacote de finalizao da bilhetagem (account-
stop) para cada transao BYE escrevendo um nico registro com a durao da
chamada. Quando voc usa MySQL, dois registros so criados e voc tem de
manualmente correlacionar as transaes de INVITEs e BYEs.

Autenticao e
Contabilizao no MySQL

UAC

Servidor SIP AAA via SQL


Base de dados OpenSER
MySQL
UAC

UAC

187 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Configurando e Instalando a Bilhetagem
A bilhetagem uma forma excepcional de verificao das mensagens, j que ela traz
o status das transaes. importante ressaltar que o SIP transacional, ento a
bilhetagem traz o resultado das transaes de INVITE e BYE. Correlacionar elas fica
a cargo de um software externo. Um SIP Proxy no o local ideal para contabilizar as
ligaes, uma ligao onde o BYE no tenha sido recebido ficar em aberto. O local
apropriado para contabilizar so os gateways PSTN onde possvel configurar um
timeout de uma ligao que no tenha recebido a transao BYE. De qualquer
forma habilitar a bilhetagem no difcil ela vai contabilizar corretamente a maioria
das ligaes e uma ferramenta de depurao excepcional.
Para contabilizar usaremos o mdulo ACC. Ele vai contabilizar dentro do banco de
dados MySQL na tabela ACC. O mdulo ACC para a verso 1.2 um pouco diferente
do existente na verso 1.1. O mdulo registra por default apenas os seguintes dados:
id method from_tag to_tag callid sip_code sip_reason time
1 INVITE 5d09d45a 27095f70 ZTY5ND. 200 OK 2008-04-07
09:13:21
2 BYE 5d09d45a 27095f70 ZTY5ND. 200 OK 2008-04-07
09:13:30

Ento para conseguir identificar a origem e o destino, precisamos adicionar alguns


dados extras.
O que faremos no script abaixo habilitar o mdulo ACC, vamos adapt-lo para a
nossa situao. Feito isto vamos marcar as transaes com a serem contabilizadas com
um flag.

LAB Implementando a contabilizao com MySQL.


Para evitar um script muito grande e complexo, vamos implantar inicialmente a
contabilizao usando o MySQL sobre o script do captulo 7.
Passo 1: Adicione os seguintes campos na tabela ACC
mysql -u root
USE OPENSER;
ALTER TABLE `acc` ADD `from_uri` VARCHAR( 64 ) NOT NULL ;

ALTER TABLE `acc` ADD `to_uri` VARCHAR( 64 ) NOT NULL ;

Passo 2: Use o script abaixo (openser.chapter10-1):


#
# $Id: openser.cfg 1676 2007-02-21 13:16:34Z bogdan_iancu $
#
# simple quick-start config script
# Please refer to the Core CookBook at
http://www.openser.org/dokuwiki/doku.php
# for a explanation of possible statements, functions and parameters.
#

# ----------- global configuration parameters ------------------------

debug=3 # debug level (cmd line: -dddddddddd)

10 | Bilhetagem usando Radius e CDRTool 188


fork=yes
log_stderror=no # (cmd line: -E)
children=4
port=5060

# ------------------ module loading ----------------------------------


#set module path
mpath="//lib/openser/modules/"

# Uncomment this if you want to use SQL database


#loadmodule "mysql.so"

loadmodule "mysql.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "uri.so"
loadmodule "uri_db.so"
loadmodule "domain.so"
loadmodule "permissions.so"
loadmodule "group.so"
loadmodule "acc.so"

# Uncomment this if you want digest authentication


# mysql.so must be loaded !
loadmodule "auth.so"
loadmodule "auth_db.so"

# ----------------- setting module-specific parameters ---------------

modparam("usrloc", "db_mode", 2)
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("rr", "enable_full_lr", 1)
modparam("auth_db|permissions|uri_db|usrloc","db_url","mysql://openser:opens
errw@localhost/openser")
modparam("permissions", "db_mode", 1)
modparam("permissions", "trusted_table", "trusted")
modparam("acc", "db_flag", 2)
modparam("acc", "db_missed_flag", 3)
modparam("acc", "db_url", "mysql://openser:openserrw@localhost/openser")
modparam("acc", "db_extra", "from_uri=$fu; to_uri=$tu")

# ------------------------- request routing logic -------------------

# main routing logic

route{

189 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
#
# -- 1 -- Request Validation
#
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};

if (msg:len >= 2048 ) {


sl_send_reply("513", "Message too big");
exit;
};

#
# -- 2 -- Routing Preprocessing
#
## Record-route all except Register
if (!method=="REGISTER") record_route();

##Loose_route packets
if (has_totag()) {
#sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
if(method=="BYE") {
#Account BYE transactions
setflag(2);
};
#Check authentication of re-invites
if(method=="INVITE" && (!allow_trusted())) {
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","1");
exit;
} else if (!check_from()) {
sl_send_reply("403", "Forbidden, use From=ID");
exit;
};
};
route(1);
} else {
sl_send_reply("404","Not here");
}
exit;
}

#CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans()) t_relay();
exit;
};

t_check_trans();

10 | Bilhetagem usando Radius e CDRTool 190


#
# -- 3 -- Determine Request Target
#
if (method=="REGISTER") {
route(2);
} else {
route(3);
};
}

route[1] {
#
# -- 4 -- Forward request to target
#
## Forward statefully
if (!t_relay()) {
sl_reply_error();
};
exit;
}

route[2] {
## Register request handler
if (is_uri_host_local()) {
if (!www_authorize("", "subscriber")) {
www_challenge("", "1");
exit;
};

if (!check_to()) {
sl_send_reply("403", "Forbidden");
exit;
};

save("location");
exit;
} else if {
sl_send_reply("401", "Forbidden");
};
}

route[3] {
## Non-Register request handler
if (method=="INVITE") {
# Account INVITE packets
setflag(2);
# Account Missed calls
setflag(3);
};
if (is_from_local()){
# From an internal domain -> check the credentials and the FROM
if(!allow_trusted()){
if (!proxy_authorize("","subscriber")) {

191 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
proxy_challenge("","1");
exit;
} else if (!check_from()) {
sl_send_reply("403", "Forbidden, use From=ID");
exit;
};
} else {
log("Request bypassed the auth.using allow_trusted");
};

consume_credentials();

#Verify aliases, if found replace R-URI.


lookup("aliases");

if (is_uri_host_local()) {
# -- Inbound to Inbound
route(10);
} else {
# -- Inbound to outbound
route(11);
};

} else {
#From an external domain ->do not check credentials

#Verify aliases, if found replace R-URI.


lookup("aliases");
if (is_uri_host_local()) {
#-- Outbound to inbound
route(12);
} else {
# -- Outbound to outbound
route(13);
};
};
}

route[4] {
# routing to the public network
rewritehostport("10.125.123.177");
route(1);
}

route[10] {
#from an internal domain -> inbound
#Native SIP destinations are handled using the location table
#Gateway destinations are handled by regular expressions
append_hf("P-hint: inbound->inbound \r\n");

if (uri=~"^sip:[2-9][0-9]{6}@") {
if (is_user_in("credentials","local")) {
prefix("+1305");
route(4);

10 | Bilhetagem usando Radius e CDRTool 192


exit;
} else {
sl_send_reply("403", "No permissions for local calls");
exit;
};
};

if (uri=~"^sip:[2-9][1-9]{9}@") {
if (is_user_in("credentials","ld")) {
prefix("+1");
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for long distance");
exit;
};
};

if (uri=~"^sip:011[0-9]*@") {
if (is_user_in("credentials","int")) {
strip(3);
prefix("+");
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for international
calls");
};
};

if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

route[11] {
# from an internal domain -> outbound
# Simply route the call outbound using DNS search
append_hf("P-hint: inbound->outbound \r\n");
route(1);
}

route[12] {
# From an external domain -> inbound
# Verify aliases, if found replace R-URI.
lookup("aliases");
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);

193 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
}

route[13] {
#From an external domain outbound
#we are not accepting these calls
append_hf("P-hint: outbound->inbound \r\n");
sl_send_reply("403", "Forbidden");
exit;

Passo 3: Faa uma chamada entre dois telefones SIP.


Step 4: Verifique os dados na tabela MySQL usando a interface de linha de comando
do MySQL.
#mysql u root
mysql>use openser

mysql>select * from acc;

Dissecando o arquivo openser.cfg


A linha abaixo faz a carga do mdulo de contabilizao. Este mdulo simples de
implantar. Basicamente so trs passos, o primeiro a carga do mdulo descrita
abaixo:
loadmodule "acc.so"

O segundo passo a configurao dos parmetros do mdulo. O primeiro parmetro


db_flag diz ao OpenSER para contabilizar em um banco de dados quando a flag 2
estiver configurada. O parmetro db_missed_flag seguinte diz ao OpenSER para
contabilizar em um banco de dados s chamadas perdidas. O parmetro db_extra
permite que voc inclua novos campos na contabilizao. Use o nome de um campo
que voc tenha previamente criado (from_uri) e um valor tirado de uma pseudo-
varivel, avp ou cabealho SIP.
modparam("acc", "db_flag", 2)
modparam("acc", "db_missed_flag", 3)
modparam("acc", "db_url", "mysql://openser:openserrw@localhost/openser")

modparam("acc", "db_extra", "from_uri=$fu; to_uri=$tu")

Vamos modificar nosso script para contabilizar as transaes de INVITE e BYE.


if (loose_route()) {
if(method=="BYE") {
#Account BYE transactions
setflag(2);

};

As transaes BYE so marcadas dentro da seo loose_route porque estamos


usando o recurso de Record Routing. Os INVITEs so marcados o incio do
tratamento das requisies. Voc no precisa e no deve marcar as transaes de RE-
INVITE.
if (method=="INVITE") {

10 | Bilhetagem usando Radius e CDRTool 194


# Account INVITE packets
setflag(2);
# Account Missed calls
setflag(3);

};

Voc pode verificar as tabelas de contabilizao usando o utilitrio phpMyAmdin.


Veja a tabela ACC na base de dados OpenSER e selecione Browse.

Contabilizao usando um servidor Radius


Funcionamento do Radius
No nosso exemplo

UAC
Servidor SIP RADIUS
UAC (Radius Client) SERVER
Contabilizao
A L
Ba ute TCP(1646) SQ
se ntic o
s
O a a iu
UAC pe o b i l i z ra d
nS SQ
n t a se
a
ER L
Co B

MySQL

Radius (Remote Authentication Dial in User Service) um servio do tipo AAA


(Authentication, Authorization and Accounting). Ele o protocolo padro para
provedores de acesso Internet. Nos ltimos anos o Radius vem ganhando
importncia fazendo parte de infra-estruturas de autenticao para controle de acesso
(802.1x) rede e bilhetagem em VoIP. Ele usado por inmeros servios de rede. Ele
pode ser implementado por diversos softwares pagos como o ACS da Cisco ou
gratuitos como o FreeRadius.
O Radius separado em duas RFCs
RFC2865 Autenticao
RFC2866 Contabilizao.
Neste captulo vamos usar o Radius apenas para contabilizao. O MySQL continuar
a ser usado para autenticao. Vamos instalar o FreeRadius em conformidade com a
ferramenta CDRTools de forma que possamos us-la mais tarde para fazer a tarifao.

195 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Instalao do FreeRadius.
A instalao do Freeradius sem dvida um desafio. Diversos passos precisam ser
seguidos a risca para que possamos ter uma instalao funcional. Por isso, vamos
separar a instalao do Freeradius em quatro etapas:
1. Instalao dos pacotes necessrios ao funcionamento
2. Configurao do banco de dados
3. Configurao do Freeradius server
4. Configurao do Radiusclient-ng
5. Configurao do OpenSER

Instalao dos pacotes


Instale o Freeradius, Freeradius-mySQL
apt-get install freeradius freeradius-mysql

Crie e configure a base de dados do Freeradius


Passo 1:Crie a base de dados para o FreeRadius.
mysqladmin -u root p create radius

Digite a senha de root sempre que necessrio.

Fornea a senha de root do mysql quando solicitada.


Passo 2: Crie as tabelas do Radius usando o script abaixo:
cd /usr/share/doc/freeradius/examples
gunzip mysql.sql.gz
mysql -u root radius <mysql.sql

Passo 3: Aplique o patch para contabilizao no Radius que vem junto com o
CDRTool. Este patch corrige um problema com o pacote de contabilizao do tipo 15.
O outro patch, chamado radacct-patch, modifica as instrues SQL de envio dados
para a base de dados SQL do Radius.
Faa o download dos patchs do freeradius
wget http://download.dns-hosting.info/CDRTool/freeradius/freeradius.patch

Aplique o patch.
apt-get build-dep freeradius
apt-get source freeradius
apt-get install devscripts
cd freeradius-1.1.3
patch -p1 -s < ../freeradius.patch
debuild
cd ../
dpkg -i freeradius*.deb

Passo 4: Instale o CDRTool para usar os arquivos de suporte ao Radius


wget http://download.dns-hosting.info/CDRTool/cdrtool_6.4.1_all.deb
dpkg i cdrtool_6.4.1_all.deb
apt-get f install

10 | Bilhetagem usando Radius e CDRTool 196


Por favor, verifique a verso, ela freqentemente muda.

Passo 5: aplique o patch da contabilizao que vem com o CDRTool


cd /var/www/CDRTool/setup/radius/OpenSER
./radacct-patch.sh

Passo 6: Edite os parmetros de conexo do banco de dados do arquivo sql.conf


vi /var/www/CDRTool/setup/radius/sql.conf
#
# Configuration for the Freeradius SQL module using MySQL and a
# central radacct table. To use monthly tables with auto-rotation
#. see radius_accounting.conf and radius_accounting.proc
#
sql {
driver = "rlm_sql_mysql"
server = "127.0.0.1"
login = "root"
password = ""
radius_db = "radius"
acct_table = "radacct"
sqltrace = no
sqltracefile = ${logdir}/sqltrace-%Y%m%d.log
num_sql_socks = 25
connect_failure_retry_delay = 60

Em um ambiente de produo no use o usurio root sem senha

Passo 7: Copie o arquivo sql.conf para o diretrio /etc/freeradius


cp sql.conf /etc/freeradius/sql.conf

Configurao do Freeradius server


Passo 1: Adicione o OpenSER como cliente do servidor Radius.
Adicione os clientes ao radius.conf. No Radius, clientes so dispositivos que fazem a
autenticao e bilhetagem com ele. Normalmente servidores de acesso remoto e
gateways. No nosso caso o cliente o servidor OpenSER.
Edite o arquivo clients.conf do radius.
vi /etc/freeradius/clients.conf

Exemplos:
client 127.0.0.1 {
secret=openser
shortname=OpenSER
nastype=other
}

Passo 2:Habilite a contabilizao MySQL no Freeradius. Edit o radiusd.conf e


descomente ou adicione se necessrio.

197 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Accounting {
acct_unique
detail
sql
unix
radutmp

Passo 3: Copie o dicionrio do OpenSER para /etc/freeradius.


cp /var/www/CDRTool/setup/radius/OpenSER/dictionary.ser /etc/freeradius

Passo 4: Inclua o dicionrio do OpenSER na configurao do servidor Radius.


cd /etc/freeradius
vi dictionary

Passo 5: Inclua a linha destacada no arquivo dictionary.ser


# The filename given here should be an absolute path.
#
$INCLUDE /usr/share/freeradius/dictionary

$INCLUDE /etc/freeradius/dictionary.ser

Certifique-se de incluir na ordem correta.

Configure o client do Radius (radiusclient-ng)


Passo 1: Copie o arquivo de dicionrio do OpenSER para o Radiusclient-ng
#cp /etc/openser/dictionary.radius /etc/radiusclient-ng/

Passo 2: Edite o arquivo /etc/radiusclient-ng/dictionary


Adicione a seguinte linha:
$INCLUDE /etc/freeradius/dictionary.ser

Step 3: Edit the file /etc/radiusclient-ng/servers


Passo 3: Edite o arquivo /etc/radiusclient-ng/servers
Configure o seu servidor radius com a chave (Key) correspondente.
#Server Name or Client/Server pair Key
#---------------- ---------------
#portmaster.elemental.net hardlyasecret
#portmaster2.elemental.net donttellanyone

127.0.0.1 openser

Passo 4: Edite o arquivo /etc/radiusclient-ng/radiusclient.conf


Adicione o endereo IP do seu servidor Radius.
# RADIUS server to use for accouting requests. All that I
# said for authserver applies, too.
Acctserver 127.0.0.1

10 | Bilhetagem usando Radius e CDRTool 198


Configure o OpenSER
O modulo de contabilizao tem suporte para Radius, mas por default ele no est
habilitado. Ento vamos habilit-lo agora. Ns teremos de re-compilar o OpenSER
com suporte a Radius para isto.
Passo 1: edite o arquivo Makefile do modulo ACC.
vi /usr/src/openser-1.2.2-tls/modules/acc/Makefile

Remova os comentrios das linhas em destaque


# uncomment the next two lines if you wish to enable RADIUS accounting
DEFS+=-DRAD_ACC -I$(LOCALBASE)/include
LIBS=-L$(LOCALBASE)/lib $(RADIUS_LIB)

Passo 2: Recompile o OpenSER


cd /usr/src/openser-1.2.2-tls
make prefix=/ clean
make prefix=/ all
make prefix=/install

Passo 3: Adicione as seguintes entradas no arquvio openser.cfg.


modparam("acc", "radius_config", "/etc/radiusclient-
ng/radiusclient.conf")
modparam("acc", "radius_flag", 2)
modparam("acc", "radius_missed_flag", 3)
modparam("acc", "radius_extra", "User-Name=$Au; \
Calling-Station-Id=$from; \
Called-Station-Id=$to; \
Sip-Translated-Request-URI=$ruri; \
Sip-RPid=$avp(s:rpid); \
Source-IP=$si; \
Source-Port=$sp; \
Canonical-URI=$avp(s:can_uri); \
Billing-Party=$avp(s:billing_party); \
Divert-Reason=$avp(s:divert_reason); \
X-RTP-Stat=$hdr(X-RTP-Stat); \
Contact=$hdr(contact); \
Event=$hdr(event); \
SIP-Proxy-IP=$avp(s:sip_proxy_ip); \

ENUM-TLD=$avp(s:enum_tld)")

Passo 4: Reinicie o servidor OpenSER.

Teste a configurao fazendo uma ligao

Verifica a contabilizao na base de dados Radius na tabela radacct. Voc pode usar
o utilitrio phpmyadmin para isto.

A contabilizao SIP composta por dois registros start e stop. O evento de


start corresponde ao pedido INVITE (inicio da chamada) e stop corresponde ao
pedido BYE (fim da chamada).

199 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
No evento inicial, o atributo Calling-Station-Id identifica a origem da chamada e o
Called-Station-Id identifica o destino da chamada. A durao da chamada dada
pela diferena dos timestamps nos eventos incio e fim.
Exemplo de contabilizao:
Sun Mar 12 17:29:21 2006

Acct-Status-Type = Start

Service-Type = Sip-Session

Sip-Response-Code = 200

Sip-Method = INVITE

User-Name = "101@openser.org"

Calling-Station-Id = "sip:101@openser.org"

Called-Station-Id = "sip:102@openser.org"

Sip-Translated-Request-URI = "sip:102@192.168.0.12:5066"

Acct-Session-Id = "1dbe198c82543fa2@192.168.0.11"

Sip-To-Tag = "00D0E90101B8_T9513"

Sip-From-Tag = "111aa0fda452c726"

Sip-Cseq = "4435"

Sip-Src-IP = "192.168.0.11"

Sip-Src-Port = "5068"

NAS-IP-Address = 127.0.0.1

NAS-Port = 5060

Acct-Delay-Time = 0

Client-IP-Address = 10.10.10.10

Acct-Unique-Session-Id = "37fb00358437ff4d"

Timestamp = 1142177361

Sun Mar 12 17:29:28 2006

Acct-Status-Type = Stop

Service-Type = Sip-Session

Sip-Response-Code = 200

Sip-Method = BYE

User-Name = "102@openser.org"

Calling-Station-Id = "sip:102@openser.org"

Called-Station-Id = "sip:101@openser.org"

Sip-Translated-Request-URI = "sip:101@192.168.0.11:5068"

Acct-Session-Id = "1dbe198c82543fa2@192.168.0.11"

Sip-To-Tag = "111aa0fda452c726"

Sip-From-Tag = "00D0E90101B8_T9513"

Sip-Cseq = "3305"

Sip-Src-IP = "192.168.0.12"

10 | Bilhetagem usando Radius e CDRTool 200


Sip-Src-Port = "5066"

NAS-IP-Address = 127.0.0.1

NAS-Port = 5060

Acct-Delay-Time = 0

Client-IP-Address = 10.10.10.10

Acct-Unique-Session-Id = "597f048f3aa62ca0"

Timestamp = 1142177368

Tarifao com o CDRTool


Um dos aspectos mais importantes em um provedor de voz sobre IP a tarifao.
Neste captulo vamos abordar uma ferramenta de bilhetagem e mediao chamada
CDRTool da Ag-projects que est disponvel sob uma licena GPL.
O CDRtool uma ferramenta WEB de bilhetagem para provedores de servios SIP. O
CDR-Tool permite a tarifao em tempo real, o pr-pago e o acesso WEB aos
registros detalhados de chamada gerados por SIP proxies, gateways e outros
equipamentos de rede que geram informao no protocolo Radius.
Alm da bilhetagem, ela d aos seus usurios acesso imediato a informaes de uso
SIP e traces do nvel de bilhetagem at o nvel de protocolo e estatsticas agrupadas
por critrio de resultado da chamada, destino, ou itens da bilhetagem e pode ajudar a
encontrar os fluxos de chamada SIP/ISDN e razes de falha.
Tendo acesso as informaes do servio usado extrado de ambos a sinalizao e
fluxo de mdia, o CDRTool pode ser usado para implantar vrios modelos de
bilhetagem baseados em qualquer combinao de banda, destino, tipo de aplicao e
durao.
O CDRTool pode oferecer tambm 100% de preciso para os registros detalhados das
chamadas quando usado em conjunto com o Mediaproxy, no importando a
disponibilidade das mensagens SIP.
possvel fornecer um mecanismo anti-fraude para bloquear contas SIP que
excederam uma quota pr-definida.
O CDRTool tambm permite funes via rede de forma que voc possa usar a
ferramenta de tarifao para aplicaes ps-pagas ou em combinao com B2BUAs
para aplicaes pr-pagas. Estas funes esto disponveis via socket TCP.

LAB. Instalao do CDRtool


A instalao do CDRTool bastante trabalhosa. Para instal-la siga rigorosamente os
passos abaixo.
Passo 1: Crie base de dados do CDRTool
V para o diretrio /var/www/CDRTool/setup/mysql
cd /var/www/CDRtool/setup/mysql

Edite o arquivo create_users.mysql


GRANT ALL ON cdrtool.* TO cdradmin@'localhost' IDENTIFIED by 'password';

201 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
GRANT ALL ON cdrtool.* TO cdradmin@'192.168.1.%' IDENTIFIED by 'password';
GRANT ALL ON cdrtool.* TO locker@'localhost' IDENTIFIED by 'password';

GRANT ALL ON cdrtool.* TO locker@'192.168.1.%' IDENTIFIED by 'password';

Execute o script de instalao do banco de dados:


#/var/www/CDRtool/setup/mysql/setup_mysql.sh localhost

O script ir criar os bancos de dados cdrtool. Ele tambm cria uma conta inicial para
login com o usurio admin e senha admin.
Passo 2: Crie o arquivo de configurao global.inc.
cd /var/www/CDRTool
cp setup/global.inc.new.installation global.inc

Edite o global.inc e configure suas variveis para baterem com seu sistema. Para cada
fonte diferente de dados voc deve criar uma nova instncia.
<?

#
# 1. Change all hostnames and passwords according to the installation
# 2. Copy this file to /var/www/CDRTool/global.inc
#

###########################################
# System and web paths

$CDRTool['tld'] = "/CDRTool";
$CDRTool['Path'] = "/var/www/CDRTool";
$_PHPLIB['libdir'] = $CDRTool['Path']. "/phplib/";
include($_PHPLIB["libdir"] . "prepend.php3");
$global_local = $CDRTool['Path']."/global.inc.local";

###########################################
# PHP Error reporting

$errorReporting = (E_ALL & ~E_NOTICE);


$errorReporting = 1; // comment this out to enable PHP warnings
error_reporting($errorReporting);

###########################################
# Service provider information

$CDRTool['provider']['name'] = "VOFFICETel";
$CDRTool['provider']['service'] = "SIP service";
$CDRTool['provider']['timezone'] = "Sao Paulo";
$CDRTool['provider']['fromEmail'] = "flavio@voffice.com.br";
$CDRTool['provider']['toEmail'] = "support@voffice.com.br";
$CDRTool['provider']['sampleLoginSubscriber'] = "number@voffice.com.br";
$CDRTool['provider']['sampleLoginDomain'] = "voffice.com.br";

###########################################
# Where the rating engine listens for network requests:

10 | Bilhetagem usando Radius e CDRTool 202


$RatingEngine=array("socketIP" => "192.168.1.170",
"socketPort" => "9024",
"CDRS_class" => "ser_radius");

$memcache_server = "127.0.0.1:11212";

###########################################
# Normalize engine settings

$CDRTool['normalize']['defaultCountryCode'] = "55";
$CDRTool['normalize']['CountryNumberLength'] = "10";

###########################################
# Anti-fraud settings
# create group quota in SER and deny calls to users in this group
$UserQuota["default"]["traffic"] = 5000; // MBytes
$UserQuota["default"]["cost"] = 1000; // Euro

###########################################
# CDRTool datasources

class DB_CDRTool extends DB_Sql {


var $Host = "localhost";
var $Database = "cdrtool";
var $User = "cdradmin";
var $Password = "senha";
var $Halt_On_Error ="no";
}

class DB_Locker extends DB_Sql {


var $Host = "localhost";
var $Database = "cdrtool";
var $User = "locker";
var $Password = "senha";
var $Halt_On_Error ="no";
}

class DB_radius extends DB_Sql {


var $Host = "localhost";
var $Database = "radius";
var $User = "radius";
var $Password = "senha";
var $Halt_On_Error ="no";
}

class DB_ser extends DB_Sql {


var $Host = "localhost";
var $Database = "openser";
var $User = "openser";
var $Password = "openserrw";
var $Halt_On_Error ="no";
}

203 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
class DomainAuthLocal extends DomainAuth { // defined in
phplib/local.inc
}

class PageLayoutLocal extends PageLayout { // defined in


phplib/local.inc
}

$DATASOURCES=array(
"unknown"=>array(
"class" => "CDRS_unknown" // leave it here
),
"ser_radius"=>array(
"name" => "OpenSER",
"class" => "CDRS_ser_radius",
"table" => "radacct",
"db_class" => "DB_radius",
"db_class_readonly" => "DB_radius",
"db_class_siponline" => "DB_ser",
"rateField" => "Rate",
"rating" => "1",
"priceField" => "Price",
"normalize0SecCalls" => "1",
"DestinationIdField" => "DestinationId",
"normalizedField" => "Normalized",
"BillingPartyIdField"=> "UserName",
"AccountsDBClass" => "DB_ser",
"intAccessCode" => "00",
"sipTraceDataSource" => "sip_trace",
"traceOutURL" => array(
"sipvm.example.com"=>"asterisk",
"pstn.example.com"=>"cisco"
),
"UserQuotaClass" => "SERQuota",
"UserQuotaTable" => "user_quota",
"UserQuotaVerbose" => "",
"UserQuotaNotify" => "0",
"MinPstnNumLen" => "9",
"EnableSIPOnline" => "0",
"EnableNetworkRating"=> "1",
"domainTranslation" => array(
"gw02.example.com" =>
"pstn.example.com"
),
"EnableSIPOnline" => 1,
"RotateTables" => "Ym",
"RotateThisMonth" => 0,
"purgeCDRsAfter" => 120 // how many days to keep the
CDRs
),
"asterisk_vm" =>array("name" => "Voicemail server",
"class" => "CDRS_asterisk",

10 | Bilhetagem usando Radius e CDRTool 204


"table" => "asterisk_cdr",
"db_class" => "DB_radius",
"rateField" => "Rate",
"rating" => "1",
"priceField" => "Price",
"DestinationIdField" => "DestinationId",
"normalizedField" => "Normalized",
"normalize0SecCalls" => "1",
"contexts" => array(

"SIP"=>array("WEBName"=>"OpenSER"),
),
"traceInURL" => array(
"SIP"=>"ser_radius"
),
"traceOutURL" => array(),
"purgeCDRsAfter" => 180 // how many days to keep the
CDRs
),
"sip_trace" =>array(
"name" => "SIP trace",
"db_class" => "DB_ser",
"table" => "sip_trace",
"purgeRecordsAfter" => "7"
)
);

// load CDRTool libraries


$CDRToolModules=array("ser","asterisk","rating");

if ($REMOTE_ADDR=="192.168.1.209") {
//$verbose=1;
} else {
// prevent set of verbose via post/get
unset($verbose);
}

?>

Passo 4: Habilitar o servidor de rating.


Edite o arquivo /etc/default/cdrtool e configure:
RUN_ratingEngine=yes

Para reiniciar o servidor de rating use:


/etc/init.d/cdrtool restart

Passo 5: Configure o Apache para suportar o CDRTool


No final do arquivo /etc/apache2/apache2.conf, adicione as seguintes instrues:
DirectoryIndex index.phtml index.php index.html index.htm
AddType application/x-httpd-php .php

AddType application/x-httpd-php .phtml

205 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Re-inicie o Apache:
/etc/init.d/apache2 restart

Passo 6: Acesse o seu CDRTool usando seu browser no seguinte endereo:


http://ip_address_of_your_server/CDRTool or
http://name_of_your_server/CDRTool

Passo 7: Faa o login usando o usurio admin com senha admin. Mude a senha logo
que puder para evitar problemas de segurana

Os parmetros de instalao freqentemente mudam. Por favor, verifique o


arquivo de instalao do CDRTool. Ele pode ser encontrado como
INSTALL.txt no diretrio CDRTool (/var/www/CDRTool/doc/INSTALL.txt)

LAB Usando o CDRTool.


Mude o seu script para a verso final (openser.chapter10-2) incluindo a travessia de
NAT e bilhetagem em RADIUS.
#
# $Id: openser.cfg 1676 2007-02-21 13:16:34Z bogdan_iancu $
#
# simple quick-start config script
# Please refer to the Core CookBook at
http://www.openser.org/dokuwiki/doku.php
# for a explanation of possible statements, functions and parameters.
#

# ----------- global configuration parameters ------------------------

debug=3 # debug level (cmd line: -dddddddddd)


fork=yes
log_stderror=no # (cmd line: -E)
children=4
port=5060

# ------------------ module loading ----------------------------------


#set module path
mpath="//lib/openser/modules/"

# Uncomment this if you want to use SQL database


#loadmodule "mysql.so"

loadmodule "mysql.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "uri.so"
loadmodule "uri_db.so"

10 | Bilhetagem usando Radius e CDRTool 206


loadmodule "domain.so"
loadmodule "permissions.so"
loadmodule "group.so"
loadmodule "mi_fifo.so"
loadmodule "lcr.so"
loadmodule "avpops.so"
loadmodule "xlog.so"
loadmodule "nathelper.so"
loadmodule "mediaproxy.so"
loadmodule "acc.so"

# Uncomment this if you want digest authentication


# mysql.so must be loaded !
loadmodule "auth.so"
loadmodule "auth_db.so"

# ----------------- setting module-specific parameters ---------------

modparam("mi_fifo", "fifo_name", "/tmp/openser_fifo")


modparam("registrar", "received_avp", "$avp(i:42)")
modparam("usrloc", "db_mode", 2)
modparam("usrloc", "nat_bflag", 4)
modparam("auth_db", "calculate_ha1", 1)
modparam("auth_db", "password_column", "password")
modparam("rr", "enable_full_lr", 1)
modparam("auth_db|permissions|uri_db|usrloc","db_url","mysql://openser:opens
errw@localhost/openser")
modparam("permissions", "db_mode", 1)
modparam("permissions", "trusted_table", "trusted")
modparam("avpops", "avp_url", "mysql://openser:openserrw@localhost/openser")
modparam("avpops", "avp_table", "usr_preferences")
modparam("nathelper","rtpproxy_disable", 1)
modparam("nathelper","natping_interval", 0)
modparam("nathelper","received_avp", "$avp(i:42)")
modparam("mediaproxy","natping_interval",20)
modparam("mediaproxy","mediaproxy_socket", "/var/run/mediaproxy.sock")
modparam("mediaproxy","sip_asymmetrics","/etc/openser/sip-clients")
modparam("mediaproxy","rtp_asymmetrics","/ect/openser/rtp-clients")
modparam("acc", "radius_config", "/etc/radiusclient-
ng/radiusclient.conf")
modparam("acc", "radius_flag", 2)
modparam("acc", "radius_missed_flag", 3)
modparam("acc", "radius_extra", "User-Name=$Au; \
Calling-Station-Id=$from; \
Called-Station-Id=$to; \
Sip-Translated-Request-URI=$ruri; \
Sip-RPid=$avp(s:rpid); \
Source-IP=$si; \
Source-Port=$sp; \
Canonical-URI=$avp(s:can_uri); \
Billing-Party=$avp(s:billing_party); \
Divert-Reason=$avp(s:divert_reason); \

207 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
X-RTP-Stat=$hdr(X-RTP-Stat); \
Contact=$hdr(contact); \
Event=$hdr(event); \
SIP-Proxy-IP=$avp(s:sip_proxy_ip); \
ENUM-TLD=$avp(s:enum_tld)")

# ------------------------- request routing logic -------------------

# main routing logic

route{

#
# -- 1 -- Request Validation
#
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};

if (msg:len >= 2048 ) {


sl_send_reply("513", "Message too big");
exit;
};

#
# -- 2 -- Routing Preprocessing
#
## Record-route all except Register
## Mark packets with nat=yes
## This mark will be used to identify the request in the loose
## route section
if(!is_method("REGISTER")){
if(nat_uac_test("19")){
record_route(";nat=yes");
} else {
record_route();
};
};

##Loose_route packets
if (has_totag()) {
#sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
if(method=="BYE") {
#Account BYE transactions
setflag(2);
};
#Check authentication of re-invites
if(method=="INVITE" && (!allow_trusted())) {
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","1");
exit;

10 | Bilhetagem usando Radius e CDRTool 208


} else if (!check_from()) {
sl_send_reply("403", "Forbidden, use From=ID");
exit;
};
};
if(method=="BYE" || method=="CANCEL") {
end_media_session();
};
##Detect requests in the dialog behind NAT,flag with 6
if(nat_uac_test("19") || search("^Route:.*;nat=yes")){
append_hf("P-hint: LR|fixcontact,setflag6\r\n");
fix_contact();
setbflag(6);
};
route(1);
} else {
sl_send_reply("404","Not here");
}
exit;
}

#CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans()) {
end_media_session();
t_relay();
};
exit;
}

t_check_trans();
#
# -- 3 -- Determine Request Target
#
if (method=="REGISTER") {
route(2);
} else {
route(3);
};
}

route[1] {
#
# -- 4 -- Forward request to target
#
# Forward statefully
t_on_reply("1");
t_on_failure("1");
if (!t_relay()) {
sl_reply_error();
};
exit;

209 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
}

route[2] {
## Register request handler
if (is_uri_host_local()) {
if (!www_authorize("", "subscriber")) {
www_challenge("", "1");
exit;
};

if (!check_to()) {
sl_send_reply("403", "Forbidden");
exit;
};

if(!search("^Contact:[ ]*\*") && client_nat_test("7")) {


setbflag(6);
fix_nated_register();
force_rport();
};
save("location");
exit;

} else if {

sl_send_reply("403", "Forbidden");

};
}

route[3] {
## Requests handler
if (method=="INVITE") {
# Account INVITE packets
setflag(2);
# Account Missed calls
setflag(3);
# Radius Extra
$avp(s:sip_proxy_ip)="127.0.0.1";
};
if (is_from_local()){
# From an internal domain -> check the credentials and the FROM
if(!allow_trusted()){
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","0");
exit;
} else if(!check_from()) {
sl_send_reply("403", "Forbidden, use From=ID");
exit;
};
};

if (client_nat_test("3")) {

10 | Bilhetagem usando Radius e CDRTool 210


append_hf("P-hint:
route(3)|setflag7,forcerport,fix_contact\r\n");
setbflag(7);
force_rport();
fix_contact();
};

#unconditional call forward


if(avp_db_load("$ru/username","$avp(s:callfwd)")) {
avp_pushto("$ru", "$avp(s:callfwd)");
route(1);
exit;
}

consume_credentials();

#verify aliases, if found replace R-URI.


lookup("aliases");

if (is_uri_host_local()) {
# -- Inbound to Inbound
route(10);
} else {
# -- Inbound to outbound
route(11);
};

} else {

#From an external domain ->do not check credentials


#Verify aliases, if found replace R-URI.
lookup("aliases");
if (is_uri_host_local()) {
#-- Outbound to inbound
route(12);
} else {
# -- Outbound to outbound
route(13);
};
};
}

route[4] {
# routing to the public network
if (!load_gws()) {
sl_send_reply("503", "Unable to load gateways");
exit;
}

if(!next_gw()){
sl_send_reply("503", "Unable to find a gateway");
exit;
}

211 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
t_on_failure("2");
if (!t_relay()) {
sl_reply_error();
};
exit;
}

route[6] {
#
# -- NAT handling --
#
if (isbflagset(6) || isbflagset(7)) {
append_hf("P-hint: Route[6]: mediaproxy \r\n");
use_media_proxy();
};
}

route[10] {
#from an internal domain -> inbound
#Native SIP destinations are handled using the location table
#Gateway destinations are handled by regular expressions
append_hf("P-hint: inbound->inbound \r\n");

if (uri=~"^sip:[2-9][0-9]{6}@") {
if (is_user_in("credentials","local")) {
prefix("+1305");
route(6);
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for local calls");
exit;
};
};

if (uri=~"^sip:1[2-9][0-9]{9}@") {
if (is_user_in("credentials","ld")) {
strip(1);
prefix("+1");
route(6);
route(4);
exit;
} else {
sl_send_reply("403", "No permissions for long distance");
exit;
};
};

if (uri=~"^sip:011[0-9]*@") {
if (is_user_in("credentials","int")) {
strip(3);
prefix("+");
route(6);
route(4);

10 | Bilhetagem usando Radius e CDRTool 212


exit;
} else {
sl_send_reply("403", "No permissions for international calls");
};
};

if (!lookup("location")) {
if (does_uri_exist()) {
## User not registered at this time.
## Use the IP Address of your e-mail server
revert_uri();
prefix("u");
rewritehostport("192.168.1.171"); #Use the IP address of your
voicemail server
route(6);
route(1);
} else {
sl_send_reply("404", "Not Found");
exit;
}
sl_send_reply("404", "Not Found");
exit;
};
route(6);
route(1);
}

route[11] {
# from an internal domain -> outbound
# Simply route the call outbound using DNS search
append_hf("P-hint: inbound->outbound \r\n");
route(1);
}

route[12] {
# From an external domain -> inbound
# Verify aliases, if found replace R-URI.
lookup("aliases");
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);
}

route[13] {
#From an external domain outbound
#we are not accepting these calls
append_hf("P-hint: outbound->inbound \r\n");
sl_send_reply("403", "Forbidden");
exit;
}

213 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
failure_route[1] {
##--
##-- If cancelled, exit.
##--
if (t_was_cancelled()) {
exit;
};
##--
##-- If busy send to the e-mail server, prefix the "b"
##-- character to indicate busy.
##--
if (t_check_status("486")) {
revert_uri();
prefix("b");
rewritehostport("192.168.1.171");
append_branch();
route(1);
exit;
};
##--
##-- If timeout (408) or unavailable temporarily (480),
##-- prefix the uri with the "u"character to indicate
##-- unanswered and send to the e-mail
##-- sever
##--
if (t_check_status("408") || t_check_status("480")) {
revert_uri();
prefix("u");
rewritehostport("192.168.1.171");
append_branch();
route(1);
exit;
};
}

failure_route[2] {
if(!next_gw()) {
t_reply("503", "Service not available, no more gateways");
exit;
};
t_on_failure("2");
t_relay();
}

onreply_route[1] {
#
#-- On-replay block routing --
#
if (client_nat_test("1")) {
append_hf("P-hint: Onreply-route - fixcontact \r\n");
fix_contact();
};

10 | Bilhetagem usando Radius e CDRTool 214


if ((isbflagset(6) || isbflagset(7)) && (status=~"(180)|(183)|2[0-
9][0-9]")) {
if (search("^Content-Type:[ ]*application/sdp")) {
append_hf("P-hint: onreply_route|usemediaproxy \r\n");
use_media_proxy();
};
};
exit;

Arquitetura do CDRTool
Esta ferramenta usa duas bases de dados. A base de dados do Radius, mais
especificamente a tabela RADACCT e a prpria base de dados chamada CDRTool. O
principal processo o engenho de tarifao (rating engine)
(/var/www/CDRTool/scripts/ratingEngine.php). Este software responsvel por
pegar a durao de chamadas e calcular o preo de acordo com uma srie de
parmetros para atribuir um valor a uma chamada em particular. O software expo6e
algumas funes permitindo a voc acesso online a dados como o balano atual,
essencial para a bilhetagem pr-paga. Vamos explicar nesta seo como as tarifas so
calculadas.

RatingEngine Functions
Calculate the price of a finished session
Show the maximum time allowed based on caller
info
Add Balance to a prepaid customer
Get Current balance for a prepaid customer
Get last calls for a subscriber
Reload rating tables

Radius Normalization and Rating CDRTool


Database process Database

Accounting Rates, Destination and


Call Duration Normalization Process Profiles Table
Remove international and national access codes

Como o CDRTool tarifa uma chamada


O software tarifa as chamadas instantaneamente, baseado em um plano de tarifao, a
partir de mltiplas fontes tais como o Asterisk, Cisco e o OpenSER. O CDRTool usa a
base de dados do Radius, mais especificamente a tabela RADACCT que contm a
durao, origem e destino e informaes sobre a mdia se voc estiver usando o
Mediaproxy. A ferramenta calcula o preo da sesso em tempo real e salva esta
informao na tabela radacct.

215 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
As tarifas esto relacionadas diretamente com a hora do dia, dia da semana e feriados.
Uma chamada pode iniciar e terminar em perfis diferentes e ainda assim ser
corretamente tarifada. Cada cliente pode ter designado um plano de tarifao
dedicado.
A tarifao do CDRTool segue o seguinte fluxo.
1. Determinao da parte a ser bilhetada (billig-party)
O CDRTool identifica o plano de tarifao pela seguinte ordem.
Conta SIP user@domain
Domnio SIP da conta
IP fonte da sesso
Padro

Para tal ele usa o campo radacct.username

2. Determinao do destino
O CDRTool identifica o destino usado no processo de rating pela ordem
Canonical-URI
SIPTranslated RequestURI
CalledStationID
3. Tarifao da rede pblica de telefonia
3.1 Pesquisa o perfil de bilhetagem na tabela pela ordem abaixo e usa o perfil ou
perfis que correspondam ao dia da semana ou hora.
Subscriber
Domain
Gateway
3.2 Usando o perfil, determina a identificao da tarifa (RateID) usada por um destino
especifico e uma determinada aplicao (a nica suportada no momento udio).
3.3 Calcula o preo baseado na durao ou no Array de durao baseado nos
parmetros relacionados abaixo. Estes parmetros podem ser alterados no arquivo
global.inc e alguns so especficos por cliente (customer).
"priceDenominator" => 10000, // e.g. 1 Eur = 10000 units
"priceDecimalDigits" => 4, // how many digits to round the prices to
"minimumDurationCharged" => 0, // Only calls greater than this
duration will be charged
"durationPeriodRated" => 60, // the prices from the rating table are
calculated per this period
"trafficSizeRated" => 1024, // same as above but for data traffic
"reportMissingRates" => 0, // send email notifications if rates are
missing from the ratingEngine

10 | Bilhetagem usando Radius e CDRTool 216


"minimumDuration" => 0 // minimum duration to rate, if call
duration is shorter the price is zero
O denominador de preo usado para calcular os centavos. Uma tarifa de 200
com um denominador de preo de 10000 equivalente a 0,02 centavos. A durao
mnima usada para calcular o preo mnimo cobrado. s vezes os provedores
VoIP chamam isto de tarifao 60/6. A durao mnima cobrada de 60 segundos,
mas taxa incremental de 6 em 6 segundos (durationPeriodRated). Voc pode
aplicar taxas de conexo e trfego tambm. O sistema bem completo quando se
trata de ps-pago.
3.4 Clculo do preo.

3.5 Salvar o preo calculado na tabela RADACCT.

Mais detalhes podem ser encontrados no diretrio DOC


(/var/www/CDRTool/doc/RATING.txt)

Lab. Criando e aplicando um plano de tarifao


Passo 1: Se logue na ferramenta CDRTool e v para o menu das tabelas de rating.
Passo 2: Escolha a tabela de clientes (customers)

217 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Passo 3: Insira seu domnio como um cliente (customer). Todas as chamadas vindas
deste domnio sero tarifadas de acordo com os perfis inseridos. O primeiro perfil
(551) sera usado para tarifar as chamadas em dias da semana. O segundo (552) para
os fins de semana. No se esquea de configurar corretamente o fuso horrio e
recarregar as tabelas aps terminar.

Passo 4: Insira um perfil para tarifar as chamadas baseado em diferentes horrios do


dia.

O primeiro perfil (551) para dias da semana e o segundo(552) para os fins de


semana. Nesta tabela voc pode designar diferentes tarifas para diferentes horas do
dia. At quatro intervalos podem ser designados. No exemplo acima, voc designou a
tarifa (rateID) identificada como 551 para os horrios de 00:00 at as 18:00 nos dias
de semana, e 552 para as tarifas aps as 18:00 e nos fins de semana.
Passo 5:Designe preos aos identificadores de tarifa

Crie dois novos identificadores de taifas (551 e 552). Os identificadores das tarifas
so diferentes dos identificadores dos perfis. Neste caso ambos foram configurados
com o mesmo valor para tornar mais fcil a leitura. No exemplo acima, voc est
designando uma taxa de 150 (1,5 centavos) para cada chamada durante o horrio
normal e (1 centavo) para chamadas aps as 18:00. A aplicao sempre udio e o
parmetro de conexo permite que voc aplique tarifas de conexo.
Passo 6: Designe nomes para os identificadores de destino (Destination Id)

10 | Bilhetagem usando Radius e CDRTool 218


Voc pode rambm usar o utilitrio importRatingTables.php localizado no diretrio
/var/www/CDRTool/setup/scripts. Veja as instrues no arquivo RATING.TXT no
diretrios doc.
Passo 7: Faa uma chamada para o destino 00554834567890 e verifique o CDR.

Sumrio
Neste captulo voc aprendeu a implantar um dos componentes mais sensveis de um
provedor de voz, a bilhetagem. Esta bilhetagem pode ser feita em MySQL muito
embora correlacionar os eventos manualmente no seja uma idia simples. Usando o
Radius voc facilita a bilhetagem e pode integrar a ferramenta de tarifao chamada
CDRTool. Esta ferramenta tem um papel muito importante no provedor de voz e no
clculo de preo das tarifas.

219 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
11
Ferramentas de resoluo de
problemas

Aps instalar o sistema como um todo, agora hora de iniciar os testes de stress para
verificarmos nossa configurao. Ns iremos usar o utilitrio SIPp para testar nosso
sistema. Antes de ns usarmos o SIPp para testar o site importante reconhecer as
ferramentas tais como o openserctl moni, openserctl online e o mdulo
SIPTRACE. As ferramentas de captura de pacotes so usadas no dia a dia da operao
de um provedor de VoIP, desta forma, teremos de aprender como usa-las. O
Wireshark, Tshark e o Ngrep so algumas das ferramentas mais usadas, por isto
vamos nos concentrar nelas primeiro. Mais tarde iremos checar o Sipsak, que se
intitula o canivete suo do VoIP. Ns podemos us-lo em conjunto com o Nagius e o
Monit para monitorar o OpenSER.

Objetivos
Ao final deste captulo voc estar apto :
Reconhecer as principais ferramentas usadas para gerenciar o OpenSER
Entender como usar ferramentas como o openserctl
Capturar e analisar pacotes usando Wireshark e o Ngrep
Resolver problemas de sinalizao do cliente usando o mdulo
SIPTRACE.
Testar o OpenSER sob condies de stress
Testar o OpenSER usando o Sipsak.

Onde estamos?
No ultimo captulo, ns terminamos a instalao do provedor VoIP. Agora hora de
colocar o sistema em produo. No dia-a-dia algumas ferramentas so necessrias
para lidar com os clientes reclamando de problemas de conectividade e qualidade de
voz.
The SIP provider MySQL/Postgres/
Big Picture Unixodbc Database

Ethernet

Media
User Radius
SIP PSTN Media Proxy CDRTool Monitoring
Portal Server Tools
Proxy Gateway Server Nat Rating
Provis. Traversal Acct.

Ethernet

CPE device (router)


Usually xDSL or
Cable
Internet Firewall
Customer Customer
Using an ATA Firewall
or Softphone

Ferramentas prprias do OpenSER


O OpenSER possui algumas ferramentas prprias que so o openserctl e o mdulo
SIPTRACE. O openserctl foi criado para monitorar os usurios online usando
openserctl online. Voc pode tambm usar o comando openserctl ping para pingar
um usurio registrado. Para verificar o estado atual do servidor use openserctl moni.

Certifique-se que seu modulo mi_fifo esteja corretamente configurado ou o


openserctl no funcionar para as estatsticas do OpenSER. Por favor,
verifique o seu arquivo openserctl para ver se o parmetro FIFO est
apontando para o arquivo /tmp/openser_fifo.

Ao emitir o comando openserctl moni ser exibida a tela abaixo


Server:: OpenSER (1.2.2-notls (i386/linux))
200 OK
Now:: Sat Nov 3 03:58:25 2007
Up since:: Sat Nov 3 03:55:41 2007
Up time:: 164 [sec]

Transaction Statistics:
200 OK
tm:UAS_transactions = 0
tm:UAC_transactions = 0
tm:inuse_transactions = 0

Stateless Server Statistics:


200 OK
sl:sent_replies = 0
sl:sent_err_replies = 0
sl:received_ACKs = 0

221 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
UsrLoc Stats:
200 OK
usrloc:registered_users = 0
usrloc:location-users = 0
usrloc:location-contacts = 0
usrloc:location-expires = 2
usrloc:aliases-users = 0
usrloc:aliases-contacts = 0

usrloc:aliases-expires = 0

Esta ferramenta imprime estatsticas dos mdulos TM, SL e USRLOC. Voc poder
apontar com este comando quantas transaes esto em uso e quantas j foram
executadas. Mensagens enviadas trazem a voc algumas informaes sobre erros e
permite verificar a sade do seu servidor. Finalmente as estatsticas de usrloc
permitem a voc verificar a sade dos processos de registro de pacotes.

Ferramentas de trace e captura de pacotes


Existem vrias ferramentas de captura de pacotes para o OpenSER. Uma das mais
simples o Ngrep usado neste livro. Tshark, o antigo Tethereal uma tima
ferramenta se voc tem um servidor sem uma interface grfica. Com o Tshark voc
pode exportar os dados capturados para analisar no Wireshark. Ferramentas de
rastreamento como o mdulo SIPTRACE so legais tambm. No entanto elas podem
impactar o desempenho de seu sistema quando habilitadas. O mdulo SIPTRACE
registra em uma base de dados todo o trfego de entrada e sada passando atravs do
Proxy para uma transao previamente marcada.

Tshark e Wireshark
O Wireshark (antigo Ethereal) o analisador de protocolos mais usado do mercado e
ele distribudo com uma licena GPL. Normalmente voc no ter uma GUI no seu
servidor, mas mesmo assim voc ainda pode capturar pacotes usando a verso texto
do Wireshark chamada Tshark. Ns freqentemente usamos o Ngrep, porque ele
simples e leve. Ensin-lo detalhadamente como usar um analisador de protocolos est
fora do escopo deste material. No entanto, ns vamos dar a voc algumas dicas de
como analisar pacotes com os protocolos SIP e RTP.
O Wireshark possui algumas estatsticas especiais para o SIP e RTP. Aps carregar os
pacotes capturados, voc pode comear a analisar as estatsticas do protocolo SIP.
Vamos tentar, no wireshark selecione:
Statistics->sip

O programa ir pedir a voc para usar um filtro, use sip

11 | Ferramentas de resoluo de problemas 222


Pressione o boto Create Stat.

um truque interessante, voc pode agora verificar as estatsticas gerais sobre as


mensagens SIP. Bem este ainda no o nosso melhor truque, mas ele pode ajud-lo a
descobrir um comportamento anormal.
Ento vamos ao segundo truque que criar um grfico com um dilogo SIP. No menu
Wireshark, selecione:
Statistics->voip calls

Voc ir receber a seguinte tela:

223 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Nesta tela voc pode selecionar a chamada que voc quer ter no grfico. Aps
selecionar a chamada pressione o boto Graph.

Voc ir receber este bonito grfico com o dilogo SIP. Agora voc pode facilmente
encontrar problemas em um dilogo especfico. Voc pode at mesmo tocar a
chamada no menu anterior se ela estiver codificada em G.711. Muito bom mesmo,
voc no acha? Ns ainda temos alguns truques na manga, ento segura um pouco e
vamos para o prximo.
Bem vamos verificar os pacotes RTP. No fim das contas os pacotes RTP determinam
a qualidade da voz. No existe uma frmula mgica, pessoalmente eu considero uma
qualidade de voz boa, quela onde a transferncia de pacotes RTP est com a latncia
est abaixo de 150ms, Jitter abaixo de 20ms e uma perda de pacotes inferior a 3%.
Voc pode at mesmo ter uma qualidade de voz boa com latncias maiores que
150ms, no entanto a interatividade da conversa comea a deteriorar. Teste para ver o
que funciona bem com voc. Use o Wireshark para medir estes parmetros. No menu
do Wireshark v para:
Statistics | RTP | Stream Analysis

11 | Ferramentas de resoluo de problemas 224


Selecione um fluxo para analisar. Use Shift-left para selecionar um fluxo reverso

Agora voc pode analisar, pacote por pacote, o Jitter, latncia(delta), banda passante e
perda de pacote dos seus fluxos. Voc pode at mesmo gerar um grfico do seu fluxo
RTP.

225 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
No nosso caso, ns podemos ver pelo grfico que nosso Jitter est abaixo de 5ms em
ambas as direes. JItter a diferena o tempo entre a chegada dos pacotes ou
variao da latncia.

O mdulo SIPTRACE
O OpenSER tem um mdulo chamado SIPTRACE. Ele permite que voc armazene as
mensagens SIP em um banco de dados. Ele gera informao para a interface grfica
do CDRTool que usada para rastrear chamadas diretamente a partir da bilhetagem.
O mdulo muito simples de se usar, simplesmente carregue o mdulo e marque as
transaes para serem rastreadas com um flag definido no parmetro do mdulo
SIPTRACE chamado trace_flag.
Voc provavelmente no ir querer registrar todas as mensagens para a base de dados
por causa da carga imposta ao servidor por este processo. O mdulo permite que voc
ligue e desligue o rastreamento usando o utilitrio openserctl. Para isto voc vai
precisar configurar o parmetro do mdulo chamado trace_on para 0 e manualmente
iniciar ou parar o rastreamento das mensagens usando openserctl fifo sip_trace on
e openserctl fifo sip_trace off. No se esquea de configurar o parmetro db_url
do mdulo. No CDRTool voc ver uma tela semelhante a mostrada abaixo.

Ferramentas para testes de Stress


Vamos apresentar agora algumas ferramentas para testar o seu servidor OpenSER
antes de coloc-lo em produo. A primeira ferramenta o sipsak (www.sipsak.org) e
a segunda o SIPp (sip.sourceforge.net).

Sipsak
O sipsak uma ferramenta usada em linha de comando por administradores SIP. Ela
usada para rodar testes simples contra um servidor SIP. uma boa ferramenta para
verificar a segurana do servidor porque voc pode criar o pedido SIP exatamente da

11 | Ferramentas de resoluo de problemas 226


maneira que quiser. Detalhes podem ser encontrados em www.sipsak.org. Vamos
mostrar um exemplo de como us-lo abaixo: Instale-o usando o comando abaixo:
apt-get install sipsak

Exemplo de uso:
sipsak U s sip:1000@192.168.1.185 a 1000 W 1 vvvvv

O comando acima envia um pacote de REGISTER para o SIP Proxy e retorna um


nmero de cdigo 1 para o Nagius. Voc pode neste caso usar o Nagius (utilitrio
bastante comum para monitoramento de servidores) para verificar se o OpenSER est
efetivamente processando as transaes de registro ao invs de simplesmente ping-
lo.

SIPp
Explicar cada detalhe do SIP est alm do escopo deste material. A idia aqui dar a
voc uma viso geral do SIPp e ensinar a voc como comear. Aloque tempo
suficiente para testar sua plataforma antes de coloc-la em produo.
O SIPp uma ferramenta de gerao de trfego e testes de stress para o SIP. uma
boa ferramenta para gerar trfego para o seu servidor SIP e test-lo antes de colocar
em produo. Ele estabelece e libera mltiplas chamadas com mtodos como o
INVITE e BYE. A taxa de chamadas pode ser ajustada dinamicamente. Mais
informaes podem ser encontradas no seu web site
http://sipp.sourceforge.net/doc/reference.html.

Vamos ver alguns exemplos em cenrios reais no qual voc poderia usar esta
ferramenta.

Instalando o SIPp
Passo 1: Instalao das dependncias:
apt-get install g++
apt-get install ncurses-dev
apt-get install openssl-devel
apt-get install libssl-dev
apt-get install libnet1-dev
apt-get install libpcap0.8-dev

Passo 2: Descarregar e descompactar o arquivo fonte:


wget http://downloads.sourceforge.net/sipp/sipp-2.0.1.src.tar.gz
tar -xzvf sipp-2.0.1.src.tar.gz

Passo 3: Compilar e rodar:


make
./sipp

Teste de stress da sinalizao SIP


Para testar o OpenSER em condies de stress, voc vai precisar usar um UAC, um
UAS e o prprio SIP Proxy. Veja o diagrama abaixo:

227 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
SIP Server
192.168.1.185:5060

User Agent Client (sipp) User Agent Server (1003)


Running sipp -sn uac Running sipp -sn uas
192.168.1.117:5062 192.168.1.116:5060

Para que o SIPp funcione, voc vai precisar registrar manualmente um usurio
adicionando um mapeamento esttico na tabela de localizao dos usurios. No
exemplo abaixo, ns estamos dizendo que o usurio 1003 est no endereo
192.168.1.117 (onde carregamos o User Agent Server).
openserctl ul add 1003 sip:1003@192.168.1.117:5060

Para iniciar um UAS use;


./sipp sn uas

Ele ir mostrar-lhe a tela abaixo:

No arquivo XML de exemplo do SIPp, o recurso de record-routing no suportado.


Por favor, altere o script de acordo se voc desejar testar com Record-Route. Eu criei
um exemplo chamado openser.chapter11 que eu usei para os testes. Voc ter de
manipular manualmente ACKs e BYEs.
Para iniciar um UAC use:
./sipp -sn uac 192.168.1.185:5060 -s 1003 -ap 1000 -p 5062 -d 1000

11 | Ferramentas de resoluo de problemas 228


Aumente a taxa de chamadas usando a tecla + at voc comear a ver retransmisses.
No caso acima,100 chamadas por segundo simultneas com suporte do mediaproxy
foi o suficiente para saturar o servidor. A tela acima referente a minha mquina
virtual que tem poucos recursos de processamento.

Tome cuidado quando testar o sistema com a contabilizao ligada. Voc pode
encher o disco rapidamente com os bilhetes do sistema.

Teste de stress da sinalizao RTP


possvel testar a sinalizao RTP usando uma combinao de um UAS e da funo
rtp_echo combinada com um UAC com a funo pcap. Veja detalhes na
documentao do SIPp

229 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Para iniciar o UAS com eco de RTP use um comando semelhante ao abaixo. Por
favor, adapte o cenrio para a sua situao antes de testar.
Exemplo:
sipp sf uas.xml rtp_echo mi 192.168.1.116 mp 1000

Veja na figura os dados relacionados aos pacotes RTP ecoados pelo sistema.
Para iniciar o UAC com a funo pcap gerando pacotes de RTP use um comando
como o abaixo:
sipp -sf uac_pcap.xml -s 1003 192.168.1.185:5060

Voc ver uma tela como a abaixo:

Testando o MediaProxy
Para testar apenas o Mediaproxy usando o RTP, voc pode usar o gerador RTP
provido pela AG-Projects. Voc pode verificar o desempenho dele usando:
./rtpgenerator --g711 count=30

Para usar vrias mquinas para o teste use os seguintes comandos em vrias mquinas
./rtpgenerator ip=ipof the mediaproxy --g711 count=50

Verifique a CPU usando a aplicao do Linux chamada top. Voc pode tambm usar
o utilitrio sessions.py para ver as sesses disponveis.

Ferramentas de monitoramento
Para monitorar o OpenSER voc pode usar um conjunto de utilitrios junto com as
ferramentas de monitoramento de redes. Voc pode usar o Nagios junto com o sipsak
para monitorar transaes reais como o REGISTER e o INVITE. A ferramenta
MONIT(www.tildeslash.com) outra que voc pode usar para monitorar o status do
sistema e o daemon do OpenSER. Um bom tutorial em como configurar o MONIT
com o OpenSER pode ser encontrado em http://www.voip-
info.org/wiki/view/OpenSER+And+Monit.

11 | Ferramentas de resoluo de problemas 230


Sumrio
Neste captulo voc aprendeu sobre as principais ferramentas para testar e monitorar o
OpenSER. prudente testar o OpenSER antes de coloc-lo em produo. Ferramentas
de captura de pacotes tais como o Wireshark e o Ngrep so muito importantes e sero
usadas diariamente, por isso esteja familiarizado com elas. Finalmente o MONIT pode
ser usado para monitorar os processos relacionados ao OpenSER e ajud-lo a mant-
los operacionais.

231 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
A
Expresses regulares

Viso geral das expresses regulares.


O OpenSER usa muito as expresses regulares para tomar decises de roteamento,
por isto resolvi incluir este breve tutotial como apndice.
Uma expresso regular permite que voc teste se uma string casa com uma forma
sinttica. Voc pode pesquisar uma string por uma substring que corresponda um
padro. Uma expresso regular descreve um conjunto de strings. O caso mais simples
o que descreve uma string em particular, por exemplo, a string foo quando no
contexto de uma expresso regular casa com foo e nada mais.
Expresses regulares no triviais usam certas construes especiais de forma que elas
podem bater com mais de uma string. Por exemplo, a expresso regular foo\|bar
corresponde ou com a string foo ou com a string bar. A expresso regular c[ad]*r
corresponde a quaisquer das strings cr, car, cdr, caar, cadddara todas as outras
strings com quaisquer nmeros de as ou ds.
Sintaxe das expresses regulares.
As expresses regulares tm uma sintaxe na qual alguns poucos caracteres so
construes especiais e o restante ordinrias. Um caractere ordinrio uma expresso
regular simples que ir bater aquele caractere e nada mais. Os caracteres especiais so
\$, ^, ., *, +, [, ] e \. Quaisquer outros caracteres aparecendo em uma
expresso regular so ordinrios a menos que um \ os preceda.
Por exemplo, f no um caractere especial e sim um ordinrio deste modo f uma
expresso regular que corresponde a string f e nenhuma outra string. (Ele no bate
com a string ff) .
Quaisquer expresses regulares A e B podem ser concatenadas. O resultado uma
expresso regular que bate com uma string se A bate com alguma parte do incio
daquela string e B bate o resto da string.
Os seguintes so caracteres e seqncias de caracteres que tem um significado

.
especial dentro de uma expresso regular. Quaisquer caracteres no mencionados aqui
no so especiais.
um caractere especial que bate com qualquer coisa exceto um caractere newline.
Usando concatenao, ns podemos criar expresses regulares como a.b que bate
quaisquer strings com trs caracteres que iniciem com a e terminem com b

*No uma construo por si s; ele um sufixo, que significa que a expresso regular
precedente pode ser repetida tantas vezes quanto possvel. Em fo*, o * se aplica ao
o, de forma que fo* bate com f seguido por quaisquer nmeros de os. O caso de
zero os permitido fo* bate com f. * sempre se aplica menor expresso
precedente possvel. Deste modo, fo* tem um o repetindo e no um fo repetindo. O
processo que faz a correspondncia processa um * batendo imediatamente tantas
repeties quantas podem ser encontradas. Ento ele continua com o restante do
padro. Por exemplo, batendo c[ad]*ar contra a string caddaar, o primeiro [ad]* bate
com addaa, mas isto no permite o prximo a no padro. a ser batido. Desta forma a
ltima das correspondncias revertida e tentada novamente e agora tem sucesso.

+ como o * exceto que pelo menos uma correspondncia do padro precedente


necessrio para o +. Deste modo, c[ad]+r no casa com cr, mas casa com qualquer
expresso onde c[ad]*r casaria .
como o * exceto que ele permite ou zero ou uma correspondncia para o padro
? precedente. Deste modo, c[ad]?r casa com cr ou car ou cdr e nada mais.

[Inicia um conjunto de caracteres, que terminada por um ]. No caso mais simples, os


caracteres entre os dois formaram o conjunto. Deste modo, [ad] bate ou com a ou
com d e [ad]* bate qualquer string de as e ds (incluindo uma string vazia). Faixas
de caracteres podem tambm ser includas em um conjunto de caracteres, escrevendo
os dois caracteres com um entre eles. Deste modo [a-z] casa com todos os caracteres
em minsculas. Faixas podem ser misturadas com caracteres individuais como em [a-
z$%.], que corresponde com qualquer caractere minsculo ou $ ou % ou ponto. Note
que caracteres especiais no so especiais dentro de um conjunto de caracteres.
Um conjunto completamente diferente de caracteres especiais existe dentro dos
conjuntos de caracteres: ],- e ^ . Para incluir ] em um conjunto de caracteres,
voc deve faz-lo o primeiro caractere. Por exemplo, []a] corresponde ao ] ou um
a. Para incluir um caractere -, voc deve us-lo em um contexto onde ele no
poderia possivelmente indicar uma faixa, em outras palavras como o primeiro
caractere, ou imediatamente aps a faixa.

[^Inicia um conjunto de caracteres complementar, que casa com qualquer caractere


exceto queles especificados. Deste modo, [^a-z0-9A-Z] casa com todos os caracteres
exceto letras e dgitos.
No um caractere especial em um conjunto a menos que ele seja o primeiro
^ caractere. O caractere seguindo o ^ tratado como se fosse o primeiro (ele pode ser
um ou um ]). ^ um caractere especial que casa com uma string vazia, mas
apenas no incio de uma linha onde o texto est sendo batido. De outra forma ele no
bate com nada. Deste modo, ^foo casa com foo que ocorre no incio de uma linha.
semelhante a ^ , mas bate apenas no fim de uma linha. Deste modo, xx*$ bate
$ com uma string de um ou mais xs no fim de uma linha.
Tem duas funes: ele precede caracteres especiais (incluindo o \), e ele introduz
\ construes especiais adicionais. Como o \ precede caracteres especiais, \$ a
expresso regular que casa apenas com $ e \] uma expresso regular que casa apenas
com [ e assim por diante. Na maioria dos casos, \ seguido por qualquer caractere bate
apenas com aquele caractere. Entretanto existem vrias excees: caracteres que
quando precedidos pelo \, so construes especiais. Tais caracteres so sempre
ordinrios quando encontrados sozinhos. Nenhum novo caractere especial ser
definido. Todas as extenses sintaxe das expresses regulares so feitas definindo
novas construes de dois caracteres que iniciam com \. \| especifica uma alternativa.
Duas expresses regulares A e B com um \| entre eles formam uma expresso que
233 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
casa com A ou B. Deste modo foo\|bar casa com foo ou bar e nada mais. \| se aplica a
maior expresso ao redor possvel. Apenas um conjunto \(....\) pode limitar o poder do
\|.

\( ...\)conjunto
uma construo de agrupamento que serve trs propsitos: Para confinar um
de alternativas \| para outras operaes. Deste modo \(foo\|bar\)x casa com
foox e barx. Para confinar uma expresso complicada para depois acrescentar um *.
Deste modo ba\(na\)* casa com bananana, etc.. com quaisquer nmeros de nas. Para
marcar uma substring casada para referncia futura. Esta ltima aplicao no uma
conseqncia da idia de agrupamento parenttico; ele um recurso separado que
designado como o segundo significado para a mesma construo \(...\) porque no
existe conflito na prtica entre os dois significados. Aqui est uma explicao deste
recurso.
aps o fim de uma construo \(...\), o processo lembra o incio e o fim do texto
\DIGITOcasado pela construo. Ento, mais tarde na expresso regular, voc pode usar o \
seguido por um digito para dizer bata com o mesmo texto casado com a ensima vez
pela construo \(...\). As construes \(...\) so numeradas na ordem inicial pela
expresso regular. As strings batendo com as primeiras nove construes aparecendo
nas expresses regulares tem designados os nmeros de 1 9. \1 at \9 podem ser
usadas para se referir ao texto casado pela construo \(...\) correspondente. Por
exemplo, \(.*\)\1 casa com qualquer string que composta por duas metades iguais. A
\(.*\) bate com a primeira metade, que pode ser qualquer coisa, mas o \1 que segue
bate apenas com o mesmo exato texto.

\bbate com uma string vazia, mas apenas se ele est no incio ou no fim de uma palavra.
Deste modo \bfoo\b bate com qualquer ocorrncia de foo como uma palavra separada.
\bball\(s\|\)\b casa com ball ou balls como uma palavra separada.
bate com uma string vazia, contanto que ela no esteja no incio ou fim de uma
\Bpalavra.
\<bate com uma string vazia, mas apenas se ela estiver no inicio de uma palavra.
bate com uma string vazia, mas apenas se ela estiver no fim de uma palavra.
\>Outras expresses ainda podem ser usadas. Uma boa referncia rpida para as
expresses regulares pode ser encontrada em http://www.regular-
expressions.info/reference.html.

A | Expresses regulares 234


B
Cdigo de Status das
Mensagens

Tabela de Cdigos de Mensagem


1XX -200 Informational
100 Trying
180 Ringing
181 Call Is Being Forwarded
182 Queued
183 Session Progress
200 OK
202 OK

3XX Redirection
300 Multiple Choices
301 Moved Permanently
303 See Other
305 Use Proxy
380 Alternative Service

4XX Client-Error
400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Timeout
409 Conflict
410 Gone
411 Length Required
413 Request Entity Too Large
414 Request-URI Too Large
415 Unsupported Media Type
420 Bad Extension
480 Temporarily not available
481 Call Leg/Transaction does not exist
482 Loop Detected
483 Too Many Hops
484 Address Incomplete
485 Ambiguous
486 Busy Here
487 Request Terminated
488 Not Acceptable Here
489 Bad Event
491 Request Pending
493 Undecipherable

5XX Server-Error
500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Time-out
505 SIP Version not supported
513 Message Too Large
580 Precondition Failure

B | Cdigo de Status das Mensagens 236


6XX Global-Failure
600 Busy Everywhere
603 Decline
604 Does Note Exist Anywhere
606 Not Acceptable

237 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
C
Definies usadas no SIP

Os seguintes termos tem significado especial para o SIP. Apresentamos aqui


principalmente a lista dos mais difceis de identificar. Para uma lista completa voc
pode consultar as RFCs 2543 e 3261.
AOR Address-of-Record (Endereo do registro):
Um endereo de registro um SIP ou SIP URI que aponta para um domnio com um
servio de localizao que pode mapear o URI para outro URI onde o usurio pode
estar disponvel. Tipicamente, o servio de localizao preenchido atravs de
registros. Um AOR possui frequentemente o endereo pblico do usurio.
Back-to-Back User Agent (agente-usurio diretamente ligado):
Um back-to-back user agent (B2BUA) uma entidade lgica que recebe um pedido e
processa-o como um user-agent-server (UAS agente-usurio servidor). De forma
a determinar como um pedido deveria ser respondido, ele age como um user-agent-
client (UAC agente-usurio cliente) e gera os pedidos. Ao contrrio de um proxy
server, ele mantm o estado do dilogo e deve participar de todos os pedidos no
dilogo que ele estabeleceu. Como ele uma soma do UAC com o UAS, nenhuma
definio explicita necessria para descrever seu comportamento.
Call (Chamada):
Uma chamada um termo informal que se refere a alguma comunicao entre pares,
geralmente configurado para propsitos de uma conversao multimdia.
Call Leg (Perna da chamada):
Outro nome para um dilogo.
Call Stateful (Chamada com manuteno do estado):
Um proxy com manuteno do estado (Call Statefull) se ele retm o estado de um
dilogo do INVITE inicial at o trmino pelo BYE. Um proxy deste tipo sempre
mantenedor do estado da transao (transaction stateful), mas o contrrio no
necessariamente verdadeiro.
Dialog (Dilogo):
Um dilogo uma relao sip entre dois UAs (agentes-usurio) que persiste por
algum tempo. Um dilogo estabelecido por mensagens SIP, tais como uma resposta
2xx para um pedido do tipo INVITE (convite). Um dilogo identificado por um
identificador de chamada, uma etiqueta local e uma etiqueta remota. Um dilogo era
conhecido como uma perna de chamada na RFC 2543.
Downstream (Fluxo baixo):
Uma direo de mensagem a frente dentro de uma transao que se refere a direo
que o os pedidos fluem do UAC (agente-usurio cliente) para o UAS (agente-
usurio servidor).
Resposta final:
Uma resposta que termina uma transao SIP, ao contrrio de uma resposta provisria
que no o faz. Todas as respostas 2xx, 3xx, 4xx, 5xx e 6xx so finais.
Header (cabealho):
Um cabealho um componente de uma mensagem SIP que leva informao sobre a
mensagem. Ele estruturado como uma seqncia de campos do cabealho.
Header Field (campo do cabealho):
Um campo de cabealho um componente de um cabealho de mensagem SIP. Um
campo de cabealho pode aparecer como uma ou mais linhas. Linhas de campo
consistem de um nome de campo de cabealho e zero ou mais valores de campo de
cabealho. Mltiplos valores de campo de cabealho em uma dada linha so
separados por vrgulas.
Header Field Value (valor do campo do cabealho):
Um valor do campo do cabealho um valor nico. Um campo de cabealho consiste
de zero ou mais valores de cabealho.
Home Domain:
O domnio fornecendo o servio para um usurio SIP. Tipicamente, este o domnio
presente no URI do registro (AOR).
Initiator, Calling Party, Caller (originador da chamada):
A parte iniciando uma sesso com um pedido INVITE (convite). Um originador retm
este papel da hora que ele envia o INVITE inicial que estabeleceu o dilogo at o
trmino do dilogo.
Invitee, Invited User, Called Party, Callee (receptor da chamada, convidado):
A parte que recebe um pedido do tipo INVITE para o propsito de estabelecer uma
nova sesso. Um usurio chamado retm o seu papel da hora que ele recebe o INVITE
at o trmino do dilogo estabelecido por aquele INVITE.
Location Service (Servio localizador):
Um servio de localizao usado por um SIP Proxy ou SIP Redirect para obter
informao sobre as possveis localizaes do destinatrio. Ele contm uma lista de
AORs (endereo IP ou nome de um host normalmente) para um ou mais endereos de
contato. Estes registros podem ser criados ou removidos de diversas formas.
Normalmente criado pelo mtodo REGISTER (Registro do cliente) ou pode ainda
ser adicionado manualmente.
Loose Routing (Roteamento solto):
Um proxy pode ser considerado do tipo loose routing se ele segue os procedimentos
definidos nesta especificao para o processamento do campo cabealho de

239 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
roteamento (Route Header). Estes procedimentos separam o destino do pedido
(presente no Request-URI) de conjunto de proxies que precisam ser visitados ao longo
do caminho (presente no campo cabealho de roteamento). Um proxy que adere a
estes mecanismos tambm conhecido como um loose router.
Outbound Proxy:
Um proxy que recebe pedidos de um cliente, embora ele normalmente ele no seja o
destino final da chamada. Tipicamente um UA (agente-usurio) configurado
manualmente com um outbound proxy ou pode aprender sobre a existncia dele
atravs dos protocolos de auto-configurao.
Paralell Search (Busca paralela):
Em uma busca paralela, um proxy ao receber um pedido dispara vrios outros pedidos
para locais possveis. Ao invs de emitir um pedido e esperar pela resposta final antes
de emitir um novo pedido, ele emite todos os pedidos sem esperar pelos resultados
dos anteriores.
Provisional Response (Resposta provisria):
Uma resposta usada por um servidor para indicar progresso da chamada, mas no
terminal a transao SIP. Respostas 1xx so provisrias, outras respostas so
consideradas finais.
Proxy, (Servidor Proxy):
Uma entidade intermediria que atua ambos como um servidor e um cliente para o
propsito de fazer pedidos em nome de outrem. O objetivo primrio de um servidor
proxy rotear o pedido para outra entidade mais prxima do usurio final. Proxies
tambm so teis para aplicar uma poltica (por exemplo, certificar-se que o usurio
tem permisso de fazer a chamada). Um proxy interpreta e se necessrio reescreve
partes de uma mensagem antes de encaminh-la.
Recursion (Recurso):
Um cliente recursa em uma resposta 3xx quando ele gera um novo pedido para uma
ou mais URIs do campo do cabealho Contact na resposta.
Redirect Server (Servidor de redirecionamento):
Um servidor de redirecionamento um UAS (agente-usurio servidor) que gera
respostas 3xx para pedidos que ele recebe, dirigindo o cliente a contatar um conjunto
alternativo de URIs.
Registrar: (Servidor de Registro):
Um servidor de registro aquele que aceita um pedido de registro e coloca as
informaes que ele recebe no servio de localizao para o domnio que ele gerncia.
Regular Transaction (Transao regular):
Uma transao regular qualquer transao com um mtodo outro que INVITE, ACK
ou CANCEL.
Ring Back (Sinal de retorno da campainha):
O Ringback o tom de sinal produzido pela aplicao de discagem indicando que a
parte chamada est sendo alertada (tocando).

C | Definies usadas no SIP 240


Route Set (Conjunto de roteamento):
Um conjunto de roteamento uma coleo de URIs que representam uma lista de
proxies que devem ser atravessados para um determinado pedido. Um conjunto de
rotas pode ser aprendido atravs de cabealhos como o route header (cabealho de
roteamento), ou ele pode ser configurado.
Sequential Search (Pesquisa seqencial):
Em uma pesquisa seqencial, um servidor proxy tenta cada contato de endereo na
seqncia, procedendo para o prximo apenas aps o prvio ter recebido uma resposta
final. Uma resposta 2xx ou 6xx sempre termina uma pesquisa seqencial.
Session (Sesso):
Da especificao SDP: Uma sesso multimdia um conjunto de fluxos, emissores e
receptores multimdia entre as partes. Uma conferncia multimdia um exemplo de
sesso multimdia. Ver RFC2327 Uma sesso definida pelo SDP pode compreender
uma ou mais sesses RTP. Como definido um destinatrio pode ser convidado vrias
vezes, por diferentes chamadas em uma mesma sesso. Se o SDP for usado, uma
sesso definida pela concatenao do nome do usurio SDP, ID da sesso, tipo de
rede, tipo de endereo, e elementos do endereo no campo origem.
SIP Transaction (Transao SIP):
Uma transao SIP ocorre entre um cliente e um servidor e compreende todas as
mensagens de primeiro pedido enviado pelo cliente at a resposta final (no 1xx). Se o
pedido um INVITE e a resposta final no uma 2xx, a transao tambm inclui uma
resposta do tipo ACK. O ACK para uma resposta 2xx a um INVITE considerada
outra transao.
Spiral (Espiral):
Uma espiral um pedido SIP que roteado para um proxy, ele encaminhado
frente e chega novamente ao proxy, mas desta vez difere de uma forma que vai
resultar em um processamento diferente do pedido original.
Stateful Proxy (Proxy que mantm estado):
Uma entidade lgica que mantm o estado de uma transao definida por esta
especificao durante o processamento de um pedido, tambm conhecido como um
transaction stateful proxy.
Stateless Proxy (Proxy sem estado):
Uma entidade lgica que no mantm o estado da transao definido nesta
especificao quando ele processa pedidos. Um proxy stateless encaminha cada
pedido que ele recebe para frente e cada resposta que ele recebe de volta.
Strict Routing (Roteamento estrito):
Um proxy considerado estrito se ele segue as regras de processamento da RFC 2543
(Antiga especificao do SIP). Esta regra causa a destruio do contedo do Request-
URI quando um cabealho de roteamento esta presente. O comportamento de
roteamento estrito no usado nesta especificao, em favor do roteamento solto
(loose routing).

241 Erro! Utilize o separador Base para aplicar Ttulo 1 ao texto que
pretende que aparea aqui.
Target Refresh Request (Pedido de atualizao do alvo):
Um pedido de atualizao do alvo enviado dentro de um dilogo definido como um
pedido que pode modificar o alvo remoto do dilogo.

C | Definies usadas no SIP 242

Vous aimerez peut-être aussi