Ligações por login e senha, agora com AGI!

Repost do blog antigo.

Bom pessoal, após meu post sobre ligações login vs. senha, eu refleti e cheguei à seguinte conclusão: “Eu tenho um cantinho especial reservado no inferno!”. Quando você for utilizar uns 10 login’s e senhas, até que aquilo lá quebra um galho. Mas e se você possuir 200 login’s para cadastrar? Imagine criar 200 contextos de saída e depois disso incluir tudo no AstDB manualmente… Eu pensei em realizar um upgrade na facilidade. Muitos podem pensar: “Ah, mas tem o A2Billing que faz isso.”; Minha resposta: “Se der problema no A2Billing? Se você quiser personalizar algo para o seu sistema ou para um cliente? E se…? E se…? E se…? What the hell you do?“. Voltando ao foco do post. Vamos fazer algo profissa não é? Que tal se nós utilizarmos um AGI em PHP integrando com uma tabela em PostgreSQL? 😉

O principio segue o mesmo, digita o número desejado, pede login, pede senha, verifica e completa. Vamos começar criando a tabela no PostgreSQL com esse script.

A chave primária login_ast_pk é para prevenir a inserção de valores iguais e nulos, pois o que nós queremos e ter um controle das ligações. Se as pessoas possuírem login’s iguais tudo vai ralo abaixo e login nulo eu não preciso nem explicar… O campo login_id gera um número para identificar o registro, o campo nome é o nome do usuário, o campo login é o seu respectivo login, o campo senha você coloca a senha e o campo contexto você insere o nome do contexto de saída desta pessoa. Como eu não sou um um POGamador from hell mal programador, coloquei um comentário na tabela.

Na saída do comando \d+ você visualiza a tabela login_ast, o comentário e o campo login_id como tipo sequência. Agora iremos inserir alguns registros como exemplo, lembrando que o primeiro campo não é necessário inserir informações, pois ele gera automaticamente o valor.

# touch /var/lib/asterisk/agi-bin/login.agi
# chmod 775 /var/lib/asterisk/agi-bin/login.agi
# vim /var/lib/asterisk/agi-bin/login.agi

Copie e cole este script dentro do arquivo login.agi.

O script AGI acima irá receber do Asterisk o login (primeiro argumento) e a senha (segundo argumento). Modifique a função pg_connect() de acordo com as informações do seu sistema. Copie e cole este contexto em seu dialplan.

Após isso é só inserir no banco os registros e correr para o abraço, lembrando que na coluna contexto do banco você deverá colocar um contexto e no extensions criar o contexto com as ligações que ele deverá realizar. Acredito que esta maneira tenha ficado bem mais prática. Só tem um detalhe, neste post eu segui o principio que vocês possuem um banco do asterisk, o php5 e o postgreSQL instalados junto com seus respectivos módulos e as bibliotecas PHPAGI instaladas. Se você possuírem dúvidas ou dificuldade para realizar as configurações, deixem um comentário!

Publicado em Artigos | Marcado com | 3 Comentários

O poder da Internet das coisas

Um vídeo da IBM bem interessante sobre a internet das coisas, que é uma realidade que está em crescimento nos dias de hoje.

Eu sirvo de exemplo, trabalhei em uma empresa que desenvolvia um sistema para despacho de corridas, focado em cooperativas de táxi. Esse sistema tinha a localização do táxi e despachava a corrida para ele e no momento que o taxista aceitava a corrida o sistema enviava um sms para o cliente com informações da posição do táxi (300 metros ou 10 minutos para chegar, etc…). Tudo isso de forma automática! Esse é um exemplo do poder da internet das coisas!

Publicado em Divagações | Marcado com | Deixe um comentário

Proteja seu bolso com a aplicação Authenticate() pt. 3

Repost do blog antigo.

Nesta parte irei abordar, o que acredito ser a melhor forma de se bloquear ramais, ligações por login e senha. Nas outras formas a restrição quanto à tipos de ligação fica atrelada ao ramal físico. Na facilidade de ligações por login e senha, cada pessoa possuirá seu login e a restrição adequada para ela, sendo assim, o ramal físico ficará  bloqueado permanente e a única maneira de realizar ligação é digitando o login e senha e possuir permissão para realizar a chamada desejada. E outro detalhe importante, essa pessoa poderá utilizar seu login em qualquer ramal e a ligação será atrelada ao login no campo CDR(userfield). Será um pouco mais trabalhoso, porém é mais seguro e flexível. Irei colocar um exemplo de contextos dos logins, porém essa parte fica aberta para vocês trabalharem em cima, pois os configurações são diferentes para todo mundo.

 Ex.:

  • Fulano, login 8001, senha XXXX, realiza ligações para local fixo e móvel.
  • João, login 8002, senha XXXX, realiza ligações interurbanas e locais.

 As ligações funcionarão da seguinte forma:

  1. Solicita o login.
  2. Verifica qual a senha para o login informado.
  3. Solicita a senha.
  4. Marca no campo CDR(userfield) o valor do ${login}.
  5. Encaminha o canal para o contexto com o nome do login.
  6. Completa a chamada.

Aqui está o exemplo em extension.conf e aqui o exemplo para extensions.ael

Da mesma maneira que você criou o valor no AstDB para cadeado e ligação por senha, você faz para esta facilidade. Utilize o comando “database put Senha ${login} ${pass}”. Na variável ${pass} coloque a senha desejada, na variável ${login} insiram login e mantenha a palavra “Senha”, pois é o nome da família no AstDB.

Obs.: O login aceita quatro dígitos. Se você deseja modificar altere os dados da aplicação Read na prioridade 4 do contexto “verifica-login”.

Bom, o segredo foi desvendado, não é? Qualquer dúvida comentem abaixo.

Publicado em Artigos | Marcado com | Deixe um comentário

Proteja seu bolso com a aplicação Authenticate() pt. 2

Repost do blog antigo.

Bom, decidi fazer em três partes para as postagens não ficarem tão longas. Continuando, desta vez irei comentar e colocar um exemplo de como funciona para realizar ligações por senha. Lembro que indico que leiam o próximo post, pois irei abordar sobre realizar ligações por login e senha o qual fornece mais segurança. Ligações por senha é bastante simples de serem configuradas, pois nós temos a incrível aplicação Authenticate() do Asterisk!!! As senhas só funcionaram no ramal pré-determinado. Vamos parar de papo furado e mão na massa!

 Ligações por senha irão funcionar basicamente seguindo esses passos:

  1. Solicita a senha.
  2. Confere se é igual.
  3. Completa a chamada.

Aqui está o exemplo do extensions.conf e aqui um exemplo em extensions.ael.

Da mesma maneira que você criou o valor no AstDB para cadeado você faz para esta facilidade. Utilize o comando “database put Senha ${CALLERID(num)} ${Pass}”. Na variável ${Pass} coloque a senha desejada e mantenha a palavra “Senha”, pois é o nome da família no AstDB.

Quaisquer dúvidas postem aí!

Publicado em Artigos | Marcado com | Deixe um comentário

Proteja seu bolso com a aplicação Authenticate() pt. 1

Repost do blog antigo.

Você quer se prevenir dos seus coçadores de saco funcionários que ficam pendurados no telefone em ligações particulares? O Authenticate() do Asterisk é a solução perfeita para isso!  Com ele você protege seu bolso e também fica de olho nos funcionários que não querem trabalhar! Vamos colocar a mão na massa então. Essa semana pintou algumas discussões na lista AsteriskBrasil sobre o assunto, então neste primeiro post eu irei abordar sobre o cadeado.

O cadeado consiste em uma facilidade na qual você bloqueia seu ramal com uma senha personalizada e assim não poderá realizar nenhuma ligação externa do mesmo. Para realizar uma ligação, você terá que desbloquear o ramal. Porém, após a ligação o ramal continua desbloqueado, então você terá que bloquear novamente. Muito útil para quem possui um ramal próprio e não deseja ficar digitando vários números para completar ligações. O dialplan está neste link e também tem uma versão que fiz em AEL neste link.

O contexto “cadeado” possui três extensões, as quais irei descrever para que servem e como funcionam.

  1. *55 serve para ativar o cadeado no ramal. Digitando *55 o servidor irá verificar qual a senha para o ramal na prioridade 3. Após isso, o mesmo irá solicitar a sua senha, se você digitar sua senha corretamente ele irá ativar o cadeado setando o valor número “1” na base /Cadeado/${CALLERID(num)}.
  2. *56 serve para desativar o cadeado no ramal. Funciona igual ao código *55, mas ao invés de setar o valor “1” na base /Cadeado/${CALLERID(num)}, ele setará o valor “0”.
  3. *57 serve para modificar a senha do cadeado. É claro que terá a necessidade de saber a senha do ramal para tal façanha. Mas serve para facilitar a vida sua vida. Se o usuário perdeu a senha, você seta no AstDB com uma nova senha simples, deixando a possibilidade do próprio usuário modificar para uma nova da preferência dele.

Agora veremos como funciona a saída de ligações. Essa é a parte mais simples! Se lembra dos valores “0” e “1” inseridos no AstDB? Esse contexto irá verificar o mesmo. Se o valor for “0” ele completa a ligação, se for “1” ele desliga! Quaisquer dúvidas postem aí!

Notas:

  • A modificação de senha na extensão *57 aceita somente 4 dígitos, se deseja aumentar, mude na prioridade 6 os dados da  aplicação Read() .
  • Os sons citados nos contextos não existem no Asterisk, fica na responsabilidade de vocês criarem.
Publicado em Artigos | Marcado com | Deixe um comentário

Melhor performance com o Zabbix trapper

O problema: Em um servidor possuo uma longa lista de itens para serem pesquisados no mesmo local (no caso em um banco de dados, no exemplo tamanho dos bancos do postgreSQL), seja um banco de dados, filesystem, etc…

A solução: Criar um trapper no servidor Zabbix para receber as informações enviadas pelo zabbix_sender e um script para realizar uma única query no banco de dados tornando assim menos custoso ao servidor.

Ok, o exemplo que mostrarei não é dos melhores (são somente quatro items), mas hoje me deparei com um caso que serão 156 items atualizados. Já é uma grande diferença!

Primeiro passo é verificar quantos trappers você possui ativo no servidor. É possível verificar com o seguinte comando (altere o nome do log para o caminho e nome do log no seu servidor):

# cat zabbix_server.log | grep started

A saída deverá ser parecida com essa, que mostra 5 trappers iniciados:

Zabbix trapper 1

Caso necessário altere a opção “StartTrappers” no arquivo zabbix_server.conf para iniciar mais trappers. Após isso é só alterar no item o tipo para “Zabbix trapper” conforme a imagem:

Zabbix trapper 2

Criei este script para exemplo, mas o comando deverá ser + ou – assim:

# zabbix_sender –c /usr/local/zabbix/etc/zabbix_agentd.conf –s’Zabbix server’ –z’127.0.0.1’ –p’10051’ –k’pgsql.db.size[zabbix]’ –o $(psql –dbname postgres –Atc “select pg_database_size(‘zabbix’) as size”)

Opções:

-s: Nome do host que está sendo enviado a informação.

-z: Ip ou nome do servidor Zabbix.

-k: Chave que será populada.

-o: Valor à ser populado. Podendo, como no exemplo, ser um comando que retorna o valor.

-v: Verbose.

-c: Path para o arquivo de configuração do agente. Não é necessário, mas é bom informar.

Faça um teste! O retorno do comando deverá ser parecido com este:

Zabbix trapper 3

Após configurado é só acompanhar nos logs (com debug 4) que deverá aparecer mensagens parecidas com esta:

Zabbix trapper 4

Com isso é possível colocar um script no crontab, fazer um daemon, etc… Só usar a imaginação! Qualquer dúvida comentem aí!

Dica:

  • Mova o binário “zabbix_sender” que por default fica em “/usr/local/bin/” para “/usr/sbin”, assim será possível acessar direto do console do linux.

Nota:

  • Todos os testes foram realizados em Debian 6 e com o Zabbix versão 2.0.2. Caso necessário adapte os comandos o seu ambiente.
Publicado em Tutoriais | Marcado com | 4 Comentários

Low-level discovery com o Zabbix

Já tem algum tempo que post algo útil aqui nesse blog, ando com muitos projetos e acabei não possuindo tempo para tal.

Hoje vou falar um pouco sobre Zabbix. O Zabbix é um software open source de monitoramento de disponibilidade e performance de servidores, desktop, switchs e aplicações diversas, seja o monitoramento via SNMP ou cliente zabbix.

O assunto que irei abordar dentro do zabbix é o Low-level discovery (também conhecido como “lld” e esta será a forma que irei chamá-lo durante o post). O lld tem uma função básica, porém extremamente útil para monitoração em larga escala. Ele simplesmente executa um script no agente e irá trazer informações variáveis do servidor, por exemplo interfaces configuradas em um servidor linux. Com esse retorno, o Zabbix criará automaticamente os itens, gatilhos e gráficos de acordo com as informações recebidas.

Irei utilizar um exemplo de banco de dados. Suponha que você queira monitorar o tamanho dos bancos em que você possui no seu PostgreSQL. Se você possuir 2, 3, 4 ,5, etc bancos, criar manualmente os itens e gatilhos para monitoração do tamanho da DB não será um problema. Agora, quando você possuir um grande número, o processo será repetitivo e cansativo.

Primeiramente iremos criar o script que trará as informações necessárias. É importante saber que o retorno deve ser em JSON. Neste link é possível encontrar um código em shell script que irá pesquisar os nomes dos bancos. É necessário ter o módulo simpleJSON do python para o funcionamento. Para instalá-lo execute o comando:

# aptitude install python-simplejson

Copie o script do link para o servidor e de permissão de execução para ele (chmod +x <nome_do_script>.sh). Eu indico deixar na pasta “etc/zabbix_agentd.conf.d” do zabbix  por organização. Agora será necessário criar a chave no zabbix_agentd.conf, irei aproveitar e criar a chave que retornará o tamanho do banco de dados. Segue um exemplo:

UserParameter=pgsql.db.names,/bin/sh /usr/local/zabbix/etc/zabbix_agentd.conf.d/lld_pgsql_dbnames.sh | python -mjson.tool

UserParameter=pgsql.db.size[*],psql –dbname postgres -Atc “select pg_database_size(‘$1’) as size”

Reinicie o zabbix-agent para aplicar as novas configurações e no zabbix-server execute o comando:

# zabbix_get -s<ip_do_cliente> -p<porta_configurada> -k ”pgsql.db.names”

A saída do comando deverá ser parecida como a imagem abaixo:

zabbix_lld_0

É importante saber que o script criado mostra a saída como “{#DBNAME}”: “postgres”. O valor “{#DBNAME}” é o que será utilizado pelo zabbix para associar ao item, gatilho ou gráfico criado. Como no exemplo acima ele irá criar os itens, triggers e gráfico para dois banco de dados, o “postgres” e o “asterisk”.

Se tudo ocorrer corretamente, agora sera necessário criar a “discovery rule”. Eu indico criar dentro de um template para o PostgreSQL ao invés de criar diretamente no host, pois ficará mais organizado. Segue uma imagem de exemplo:

Zabbix lld 1

Dentro de “discovery rules” entre na aba “itens prototypes”, conforme indicado na imagem abaixo:

Zabbix lld 2

Crie um “item prototype” como o exemplo abaixo:

Zabbix lld 3

Após esses procedimentos é só aguardar o zabbix executar discovery e o intervalo de coleta e será criado os itens nos hosts conforme a imagem abaixo:

Zabbix lld 4

E em dados recentes podemos confirmar que está coletando corretamente os dados:

Zabbix lld 5

Conclusão: Sem o lld não fica legal! Esta ferramenta do zabbix ajuda a administrar muito mais facilmente qualquer host. Basta no momento de criar o host adicionar o template do PostgreSQL e criar as chaves e copiar o script no agente, e voilá! Agora criar centena de hosts ficará uma passo mais fácil!

Caso tenha dificuldades nos procedimentos, comente que eu irei responder!

Notas:

  • Todos os testes foram realizados em Debian 6 e com o Zabbix versão 2.0.2. Caso necessário adapte os comandos o seu ambiente.
  • É presumido que o usuário o qual é inicado o zabbix-agent possua acesso ao banco de dados postgresql.
  • Todos os testes foram realizados nos padrões do meu ambiente. Por exemplo, a minha instalação do zabbix-agent não fica em “/usr/local” e sim em “/usr/local/zabbix”. Portanto, adapte a sua instalação e padrões.
  • Os intervalos de atualizações do lld e do item criado é um exemplo, sugiro para o lld deixar 1 dias e para o tamanho do banco 1 hora, mas varia de acordo com a necessidade de cada ambiente.
Publicado em Artigos | Marcado com | 40 Comentários

Why not MySQL?

Seguinte, eu sei que o MySQL é ruim, mas esse vídeo me surpreendeu! Você tem um banco de dados que não garante a integridade de seus dados! E você ai achando que tudo estava funcionando certinho!!!

Publicado em Divagações | Marcado com , , | 3 Comentários

How fucked is your database?

Do meu antigo blog, só atualizando por aqui! 😉

Recebi na lista do PostgreSQL uma mensagem indicando esse site. Achei muito bom e quis compartilhar. Sempre é bom dar risada de alguns problemas, principalmente quando se trata de banco de dados!

http://howfuckedismydatabase.com/

Publicado em Divagações | Marcado com | Deixe um comentário

Desvio para o Asterisk pt.1

É… passei um bom tempo sem postar aqui, mas pretendo me empenhar novamente.

Começarei a fazer alguns posts sobre desvios no Asterisk.

As centrais convencionais possuem variados tipos de desvios. Os mais comuns são: desvio imediato, desvio condicional, desvio se ocupado e desvio se não houver resposta. Serão o total de três posts, dois descrevendo cada um dos desvios e o terceiro com um contexto para cancelar todos os desvios, verificar desvios ativos, e o plano de discagem para verificar antes de discar para o ramal . 😉

Hoje irei comentar sobre a facilidade de desvio imediato, desvio se ocupado e desvio se não houver resposta.

O desvio imediato é uma facilidade onde o usuário do ramal “A” digita um código + o número do ramal “B”. Quando este código for ativo, toda vez que alguém ligar para o ramal “A” a ligação será desviada e chamará no ramal “B”, sem ao menos tentar chamar o ramal “A”.

O desvio se ocupado funciona quase igual, a única funcionamento que muda é que o desvio só é utilizado quando o ramal está ocupado e o desvio se não houver resposta é quando o ramal chama e estoura o tempo chamando, assim é utilizado o desvio para o ramal desejado.

O contexto “desvio-imediato” servirá para ativar/desativar o mesmo. Para utilizarmos a facilidade de desvio, será usado o AstDB, pela questão de ter o acesso fácil via dialplan.

O código *50 serve para ativar o desvio. Quando o usuário discar o código para ativar, o Asterisk irá atendê-lo após 1 segundo (parâmetro 1 na app Answer()) e irá verificar na tabela do AstDB se existe a família “Desvio” com a chave “${CALLERID(num)}” (o número do ramal que está chamando a facilidade). Se houver a chave indicada, ele envia o chamador para desvio-imediato,*50,8, onde será executado um playback informando que já existe um desvio ativo e será enviado para a extensão desvio-imediato,h,1, onde será esecutado um HangUp(). Se não houver a chave indicada, será direciona para a tag continua, onde será executado um áudio solicitando para entrar com um número de ramal, será lido o número do ramal com a opção Read() e será inserido no AstDB o número do ramal. Após isso será executado um áudio informando que o desvio foi ativo e irá desligar o canal.

O código *51 serve para desativar o desvio. Quando o usuário discar o código, o Asterisk irá atender a ligação, verificar se o desvio existe no AstDB, se existir o Asterisk irá deletar e tocar um áudio informando que o desvio foi desativado, se não existir o Asterisk irá somente informar que não existe desvio imediato ativo.

Agora, o desvio se ocupado e o desvio se não houver resposta funcionam exatamente iguai a esse. Porém cada um deve possuir sua extensão para ativar/desativar e sua própria família no AstDB.

Segue aqui o exemplo do extensions.conf.

Note que o desvio se não houver resposta chama algumas aplicações à mais. Na extensão *54, prioridade 7, ele executa um áudio informando para entrar com o número de vezes que o ramal será chamado antes de desviar. Após ler o número de 1 dígito (de 1 à 9, se for zero ele irá executar um áudio informando que a opção é inválida e retornar para solicitar novamente o número), ele irá multiplar o mesmo por 4 (cada toque é quatro segundos, o Asterisk chama por segundos, portanto…) e salvar no AstDB. Na extensão *55, prioridade 5, o número de toques será deletado do AstDB.

Notas:

  • Os áudios citados são exemplos abstratos. Eles não existem no Asterisk, você terá que gravá-los e adcionar na pasta padrão de áudios (“/var/lib/asterisk/sounds/”).
  • No contextos de desvio, extensão *50, *52 e *54, prioridade 5, aplicação Read(), o valor “4” é referente ao número de dígitos dos seus ramais. Modifique conforme a necessidade.
  • Eu NÃO TESTEI, por isso verifiquem antes de utilizar, mas é para estar correto e funcionando.

Bom, esses desvios foram simples, o problema será o desvio condicional!

Até mais!

Publicado em Tutoriais | Marcado com | 3 Comentários