sexta-feira, 24 de janeiro de 2014

Recebendo alertas de falhas de servidores HP ProLiant rodando Ubuntu

Apesar de não suportar o sistema operacional Ubuntu, muita gente não sabe, mas a HP disponibiliza suas ferramentas de gerenciamento de servidores ProLiant no formato .deb, tendo inclusive um repositório disponível que pode ser facilmente configurado em seu servidor.

As ferramentas disponíveis permitem verificar tempetura, velocidade dos fans, estado do disco e da controladora RAID, configurar o iLO entre outras coisas.

Mas como faço para instalar as ferramentas?

Para começar, adicione o seguinte repositório no seu servidor:

deb http://downloads.linux.hp.com/SDR/downloads/ProLiantSupportPack/ lucid current/non-free

Mesmo o repositório sendo para o Ubuntu 10.04, as ferramentas funcionam perfeitamente no 12.04  (nas versões mais novas ainda não pude testar).

Após rodar um apt-get update, ficarão disponíveis os seguintes pacotes: 
  • cpqacuxe: utilitário web de configuração dos arrays de disco (necessita controladora RAID, e não, ele não funciona com o "RAID" onboard que depende de drivers que normalmente está disponível nos servidores ML110).
  • hp-health: contém as ferramentas para monitoramento da "saúde" do sistema.
  • hpsmh: provê a página web de gerenciamento do sistema onde é possível visualizar os alarmes e a "saúde" do servidor.
  • hp-smh-templates: contém templates para a página web de gerenciamento do sistema.
  • hp-snmp-agents: contém o servidor SNMP e agentes de storage e de rede para todos os servidores ProLiant.
  • hpacucli: é a versão de linha de comando do cpqacuxe.
  • hponcfg: contém as ferramentas de linha de comando para configurar o iLO.
E depois de instaladas, o que eu posso fazer?

Dos pacotes acima, eu pude testar apenas o hp-health, hpacucli e o hpsmh, e somente as seguintes ferramentas: hplog, hpacucli e a interface web do hpshm.

hplog

O hplog, entre outras coisas, possibilita a visualização do status atual da temperatura, dos fans e da energia, permitindo que tais dados sejam utilizados em um script para geração de um alerta por e-mail, por exemplo, que é o objetivo principal deste post.

Alguns exemplos:

Temperatura atual

root@lnxsrv:~# hplog -t
ID     TYPE        LOCATION      STATUS    CURRENT  THRESHOLD
 1  Basic Sensor Ambient         Normal    66F/ 19C 104F/ 40C
 2  Basic Sensor Memory Board    Normal   132F/ 56C 230F/110C
 3  Basic Sensor CPU (1)         Normal    86F/ 30C 212F/100C
 4  Basic Sensor CPU (1)         Normal    86F/ 30C 212F/100C
 5  Basic Sensor I/O Zone        Normal    96F/ 36C 145F/ 63C
 6  Basic Sensor CPU (2)         Normal   ---F/---C 212F/100C
 7  Basic Sensor CPU (2)         Normal   ---F/---C 212F/100C
Status dos fans
root@lnxsrv:~# hplog -f
ID     TYPE        LOCATION      STATUS  REDUNDANT FAN SPEED
 1  Var. Speed   System Board    Normal     No      Low    ( 35)
 2  Basic Fan    System Board    Absent     No      Unknown
 3  Var. Speed   System Board    Normal     No      Low    ( 35)
 4  Basic Fan    System Board    Absent     No      Unknown
 5  Var. Speed   CPU (1)         Normal     N/A     Low    ( 35)
 6  Basic Fan    CPU (2)         Absent     N/A     Unknown

Status do power
root@lnxsrv1:~# hplog -p
ID     TYPE        LOCATION      STATUS  REDUNDANT
 1  Standard     Pwr. Supply Bay Normal     No
 2  Standard     Pwr. Supply Bay Absent     No

hpacucli

O hpacucli, entre outras coisas, possibilita a visualização do status atual da controladora e dos discos, permitindo que tais dados sejam utilizados em um script para geração de um alerta por e-mail, por exemplo.


Alguns exemplos:

Status da controladora
root@lnxsrv:~# hpacucli ctrl all show status
Smart Array E200i in Slot 0 (Embedded)
   Controller Status: OK
   Cache Status: OK
   Battery/Capacitor Status: OK

Status dos discos
root@lnxsrv:~# hpacucli ctrl slot=0 pd all show detail
Smart Array E200i in Slot 0 (Embedded)
   array A
      physicaldrive 2I:1:1
         Port: 2I
         Box: 1
         Bay: 1
         Status: OK
         Drive Type: Data Drive
         Interface Type: SATA
         Size: 250 GB
         Firmware Revision: HPG9
         Serial Number: Z3THAVJF
         Model: ATA     VB0250EAVER
         SATA NCQ Capable: False
         PHY Count: 1
         PHY Transfer Rate: 1.5GBPS
      physicaldrive 2I:1:2
         Port: 2I
         Box: 1
         Bay: 2
         Status: OK
         Drive Type: Data Drive
         Interface Type: SATA
         Size: 250 GB
         Firmware Revision: HPG1
         Serial Number: 9SF0527C
         Model: ATA     GB0250EAFJF
         SATA NCQ Capable: False
         PHY Count: 1
         PHY Transfer Rate: 1.5GBPS

Interface web do hpshm

Minha experiência com a interface web não foi das melhores. Usei a mesma em dois modelos diferentes, mas em nenhum deles consegui obter os dados que desejava. Por fim preferi utilizar as ferramentas de linha de comando e não dei mais atenção a este recurso, então é provável que ele tenha sido mal explorado.

E como posso tratar e receber os alertas?

Uma possibilidade (a mais óbvia delas) é tratar a saída dos comandos num script que procura por erros e, caso os mesmos sejam encontrados, enviar o status para um determinado e-mail.

Vou exemplificar abaixo, partindo do pressuposto que desejamos receber alertas em caso de falhas em algum dos HDs do servidor:

#! /bin/bash
#
# Script de envio de e-mail
# em caso de falha de disco
#
# Marcelo Terres
#

MAILTO="marcelo@meudominio.com.br"
MAILSUBJECT="Alarme de disco em $HOSTNAME"
HPACUCLI="/usr/sbin/hpacucli"
MAILEXEC="/usr/bin/mail -a \"Content-Type: text/plain;charset=UTF-8;\" -s \"$MAILSUBJECT\" \"$MAILTO\""

$HPACUCLI ctrl slot=0 pd all show detail | grep "Status: Failed" -q

if [ $? == 0 ]; then

  echo "Erro de disco encontrado"

  MAILBODY="Olá, \nexiste um erro de disco no servidor $HOSTNAME\n\nSaida da verificacao:\n`$HPACUCLI ctrl slot=0 pd all show detail`"
  echo -e "${MAILBODY}" | eval $MAILEXEC
  exit 1
fi

exit 0

O exemplo acima é bastante simplório, é claro, mas tem por objetivo somente servir de base para que você coloque sua criatividade em prática e desenvolva agora algo que atenda sua demanda da melhor forma possível.

Até mais.

quinta-feira, 23 de janeiro de 2014

Bug com smb_auth no Squid3 do Ubuntu 12.04


Há muito tempo que não instalava um Squid e eis que surgiu a necessidade de fazê-lo.

Esta instalação, diferente das anteriores que havia realizado, precisava autenticar no Windows Active Directory 2012, mas como tratava-se de uma autenticação simples, ao invés de Kerberos, Winbind e afins, optei por utilizar a autenticação básica, com os comandos squid_ldap_group e o smb_auth.

Depois da instalação e da configuração finalizadas, iniciei os testes dos mecanismos de comunicação com o AD. Primeiro o squid_ldap_group, que comportou-se como o esperado e depois o smb_auth, que acabou falhando.

Mesmo após vários testes e verificações me deparava sempre com o mesmo problema:
/usr/lib/squid3/smb_auth -d -W MEUDOMINIO -U 192.168.1.2
meu_usuario minha_senha
Domain name: MEUDOMINIO
Pass-through authentication: no
Query address options: -U 192.168.1.2 -R
Domain controller IP address: 192.168.1.2
Domain controller NETBIOS name: MEUDOMINIODC1
Contents of //MEUDOMINIODC1/NETLOGON/proxyauth:
ERR

Como eu tinha certeza de que estava tudo correto, decidi debugar os softwares. Já que o smb_auth era um binário, iniciei a investigação pelo script /usr/lib/squid3/smb_auth.sh

Aparentemente não havia nada de errado com o mesmo, mas ele também falhava nos testes. Resolvi então testar o script passo a passo e acabei  me depararando com um erro lamentável. O comando que verificava o conteúdo do arquivo proxyauth no compartilhamento netlogon não estava enviando os dados de autenticação, como podemos ver abaixo:
authinfo=`smbclient "//$dcname/$AUTHSHARE" -I $dcip -d 0 -E -W "$DOMAINNAME" -c "get $authfilebs -" 2>/dev/null`

Corrigi então o código, que ficou da seguinte maneira:
authinfo=`smbclient "//$dcname/$AUTHSHARE" -I $dcip -d 0 -E -W "$DOMAINNAME" -c "get $authfilebs -" -U $USER 2>/dev/null`
Voilà, problema resolvido:  
/usr/lib/squid3/smb_auth -d -W MEUDOMINIO -U 192.168.1.2
meu_usuario minha_senha
Domain name: MEUDOMINIO
Pass-through authentication: no
Query address options: -U 192.168.1.2 -R
Domain controller IP address: 192.168.1.2
Domain controller NETBIOS name: MEUDOMINIODC1
Contents of //MEUDOMINIODC1/NETLOGON/proxyauth: allow
OK
Espero que este post seja útil e evite que você perca tanto tempo quanto eu perdi numa tarefa tão corriqueira.

quarta-feira, 22 de janeiro de 2014

Limitação do número de ligações simultâneas via IAX


Uma situação bastante comum quando você precisa interligar duas (ou mais) filiais via IAX para que os usuários de ambos locais possam falar sem custo entre si, é a existência de uma banda limitada para o uso de voz.

Quando temos este cenário, normalmente surge um problema: como podemos garantir que não teremos mais ligações simultâneas do que permite a "banda reservada" para este recurso.

Com esta demanda nas mãos, criei um plano de discagem que permite limitar o número de ligações simultâneas quando for utilizado IAX2 (ou, com pequenas adaptações, qualquer outro tipo de canal, como, por exemplo, SIP).

Para efeito de demonstração, vamos supor que você utilize um codec que consuma 64Kbps para cada ligação (G.711 a-law). Vamos supor também que você tenha 256Kbps disponível para voz, podendo realizar então até quatro ligações simultâneas sem perda na qualidade (cortes, "voz robótica", etc...).

A configuração necessária para tal controle é feita no extensions.conf, em três contextos diferentes (não esqueça de adaptar o exemplo à sua realidade):

  • o contexto [globals] é padrão do Asterisk e nele você pode declarar variáveis para uso no plano de discagem;
  • o contexto [from-iax] é o contexto que controlará as chamadas recebidas via IAX;
  • o contexto [saidaexterna] é o contexto de saída das chamadas (exceto chamadas entre ramais locais);

Contexto globals

No contexto [globals] você irá declarar a variável que controla o número máximo de chamadas permitidas, da seguinte forma:
; Controle de chamadas
; 256Kbps  = 4 chamadas a-law de 64Kbps cada
CALL_LIMIT_IAX=4 

Contexto from-iax

No contexto [from-iax]  você irá controlar as chamadas entrantes via IAX, da seguinte forma:
exten => _XXXX.,1,NoOp(Chamada via IAX)
same => n,NoOP(Chamada de origem ${CALLERID(num)} discando para ${EXTEN})
; Adiciona chamada no grupo do IAX2
same => n,NoOP(Adicionando chamada entrante ao grupo IAX2)
same => n,Set(GROUP()="IAX2")
; verifica o número de chamadas simultâneas no grupo
same => n,Set(SIMULTCALL=${GROUP_COUNT("IAX2")})
same => n,NoOp(Ligacoes em curso IAX2: ${SIMULTCALL} de ${CALL_LIMIT_IAX})
; verifica se a chamada pode ser realizada
same => n,GotoIf($[0${SIMULTCALL} <= 0${CALL_LIMIT_IAX}]?call:nocall)
; seção utilizada quando a chamada não pode ser realizada
same => n(nocall),NoOp(Limite de chamadas IAX2 excedido - chamada entrante recusada)
same => n,Playback(canais_iax_ocupados)
same => n,Hangup()
; seção utilizada para realização da chamada para ramais (sip)
same => n(call),Goto(sip,${EXTEN},1)
same => n,Hangup()

Contexto saidaexterna

No contexto [saidaexterna] você irá controlar as chamadas saintes via IAX e outras tecnologias como DAHDI, Khomp ou DGV, da seguinte forma:
exten => _X.,1,Progress
; AGI para obter a variável de discagem ${DIAL} com base no destino da ligação
;
; As saídas possíveis são, por exemplo:
; Khomp/Gebt/${EXTEN}
; Khomp/Ggsm/${EXTEN}
; DGV/g1/${EXTEN}
; IAX2/SPO/${EXTEN}
; SIP/vono/${EXTEN}
;
; Não vou postar o AGI porque ele é muito específico para a solução
; mas você pode gerar o seu próprio AGI com base na sua estrutura
;
same => n,AGI(dialout.agi)
; Obtém o tipo de canal de saída
same => n,Set(OUTCHAN=${DIAL:0:4})
; Verifica se o canal é IAX2. Se não for IAX2 vai diretamente para a discagem
same => n,GotoIf($["${OUTCHAN}"="IAX2"]?iax:call)
; Adiciona chamada no grupo IAX2
same => n(iax),NoOP(Adicionando chamada sainte ao grupo IAX2)
same => n,Set(GROUP()="IAX2")
; verifica o número de chamadas simultâneas IAX2
same => n,Set(SIMULTCALL=${GROUP_COUNT("IAX2")})
same => n,NoOp(Ligacoes em curso IAX2: ${SIMULTCALL} de ${CALL_LIMIT_IAX})
; verifica se a chamada pode ser realizada
same => n,GotoIf($[0${SIMULTCALL} <= 0${CALL_LIMIT_IAX}]?call:nocall)
; seção usada quando a chamada não pode ser realizada
same => n(nocall),NoOp(Limite de chamadas IAX2 excedido - chamada sainte recusada)
same => n,Playback(canais_iax_ocupados)
same => n,Hangup()
; disca
same => n(call),Dial(${DIAL},60,TWXr)
same => n,Hangup()

ATENÇÃO: É importante que este plano de discagem seja implementado em ambos servidores para que possamos garantir que não sejam recebidas e nem realizadas mais ligações do que o valor limite.

Agora é com você. Adapte e estenda este plano de discagem e se quiser compartilhar suas melhorias, fique à vontade para postá-las nos comentários.


Até a próxima.




terça-feira, 21 de janeiro de 2014

Próxima versão do Openfire trará suporte ao Jitsi Videobridge

Para quem ainda não conhece, o Jitsi Videobridge é um software para conferência de vídeo multi usuário, no estilo Google Hangouts, mas com o código aberto.

Em pleno desenvolvimento (a versão "70" foi lançada na data de ontem), a boa notícia é que o Jitsi Videobridge pode ser instalado como um plugin do Openfire, e o mesmo já foi adicionado na versão 3.9.0 que ainda não tem data de lançamento prevista. 

A nova versão do Openfire, além deste novo recurso, trará como de costume uma série de correções de bugs e de melhorias (as notas de lançamento já podem ser lidas aqui).

E já que estamos falamos do Jitsi Videobridge, o mesmo já está disponível para download com versões para Linux, Windows e OSX nesta URL

Mas se você não quiser esperar o lançamento da versão 3.9.0 do Openfire para testar o novo plugin, baixe-o aqui e boa diversão. 

segunda-feira, 20 de janeiro de 2014

Problema com logs no Openfire 3.8.1 e 3.8.2

Já havia atualizado o Openfire para a última versão (3.8.2) há um bom tempo, mas até o momento não havia sido preciso fazer qualquer verificação nos logs do mesmo.

Semana passada, no entanto, fui obrigado a analisar os logs para verificar uma situação de erro de s2s e percebi que o software não estava gerando os logs a partir da versão 3.8.1 (não pude confirmar a existência do bug na versão 3.8.0).

Após muita pesquisa me deparei com um link que relatava a mesma questão e trazia a solução do problema. 

É muito simples:

  • Localize o script que inicia o Openfire (se não souber onde ele está você pode encontrar esta informação no initscript que fica no /etc/init.d/).
  • Edite este arquivo e procure pela linha que inicia com o comando nohup.
  • Mova os parâmetros -DopenfireHome e -Dopenfire.lib.dir que ficam no final da linha para antes do parâmetro -classpath.
  • Reinicie o Openfire 
Problema resolvido!