TCC_LuisFernandoCordeiro_final.pdf - Repositório ...
-
Upload
khangminh22 -
Category
Documents
-
view
3 -
download
0
Transcript of TCC_LuisFernandoCordeiro_final.pdf - Repositório ...
UNIVERSIDADE FEDERAL DE SANTA CATARINA
Desenvolvimento de um ambiente de gerenciamento centralizado
para autenticação, autorização e auditoria em um cenário de rede
heterogênea
Luís Fernando Cordeiro
Florianópolis – SC
2012/2
UNIVERSIDADE FEDERAL DE SANTA CATARINA
DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA
CURSO DE SISTEMAS DE INFORMAÇÃO
Desenvolvimento de um ambiente de gerenciamento centralizado
para autenticação, autorização e auditoria em um cenário de rede
heterogênea
Luís Fernando Cordeiro
07238071
Florianópolis – SC
2012/2
Trabalho de conclusão de curso apresentado como parte dos requisitos para a obtenção do grau de Bacharel em Sistemas de Informação.
Luís Fernando Cordeiro
Desenvolvimento de um ambiente de gerenciamento centralizado
para autenticação, autorização e auditoria em um cenário de rede
heterogênea
Trabalho de conclusão de curso apresentado como parte dos requisitos para
obtenção do grau de Bacharel em Sistemas de Informação.
__________________________________________________
Profa. Dra. Carla Merkle Westphall
Orientadora
__________________________________________________
Prof. Dr. Carlos Becker Westphall
__________________________________________________
Edison Tadeu Lopes Melo
Resumo
O presente trabalho de conclusão de curso possui como tema o estudo, o desenvolvimento e a implantação de um sistema de autenticação centralizado para equipamentos de rede, utilizando como base tecnologias padronizadas e livres. Ao longo do trabalho, são apresentadas as análises realizadas sobre os principais protocolos que envolvem as áreas de Autenticação, Autorização e Contabilização (AAA) (METZ,1999), como RADIUS (IETF 2865, 2000) e TACACS+ (METZ,1999). Além da parte teórica, foram desenvolvidas duas aplicações, uma para suporte e outra para a gerência do ambiente. Foram realizados ainda testes com uma aplicação já consolidada no mercado, a qual se mostrou muito completa mas pouco adaptável a ambientes de rede heterogêneas. Por fim, denota-se do estudo da nova estrutura que além de suportar uma variedade maior de equipamentos, é possível customizar ainda mais o ambiente e expandir o seu uso para computadores pessoais e servidores, sendo eles Windows ou Linux, o que será indicado como trabalhos futuros.
Palavras-chave: openLDAP, TACACS+, AAA, Gerenciamento de Identidades.
Lista de Figuras
Figura 1 - Modo de Autenticação de Três Partes. Fonte: Todorov (2007) ................ 15 Figura 2 - Troca de mensagens usando RADIUS. Fonte: CISCO (2008) ................. 18 Figura 3 - Troca de mensagens usando TACACS+. Fonte: CISCO (2008) .............. 19 Figura 4 - Comparação entre o X.500 e o LDAP ...................................................... 24 Figura 5 - Exemplo de uma árvore de diretório LDAP .............................................. 25 Figura 6 - Exemplo dos atributos de um objeto ......................................................... 26 Figura 7 - Processo de autenticação atual ................................................................ 30 Figura 8 - Arquitetura do ambiente proposto ............................................................. 32 Figura 9 - Infraestrutura de rede dos servidores ....................................................... 34 Figura 10 - Fluxo dos dados no ambiente proposto .................................................. 36 Figura 11 - Exemplo de Configuração de usuários no tac_plus ................................ 40 Figura 12 - Exemplo de uma entrada LDAP com suporte ao TAC_PLUS MAVIS .... 43 Figura 13 - Exemplo de configuração de níveis de privilégios .................................. 44 Figura 14 - Exemplo de configurações de grupos de equipamentos ........................ 45 Figura 15 - Definições de especificações de tempo e ACLs ..................................... 46 Figura 16 - Roteador Cisco 7606 .............................................................................. 49 Figura 17 - Switch 3Com 5500G ............................................................................... 49 Figura 18 - D-Link DGS 3100 PoE ............................................................................ 50 Figura 19 - Cisco WLC 5500 ..................................................................................... 51 Figura 20 - Interface de Logs - logs de comandos .................................................... 53 Figura 21 – Interface de Logs - logs de acessos ...................................................... 54 Figura 22 - Interface de Logs - logs de acessos 2 .................................................... 55 Figura 23 - Interface de gerência - visão inicial ......................................................... 56 Figura 24 - Interface de gerência - acompanhamento de comandos ........................ 57 Figura 25 - Interface de gerência - adicionar usuário ................................................ 58 Figura 26 - Funcionamento geral do ambiente ......................................................... 59
Lista de Abreviaturas
TACACS – Terminal Access Controller Access-Control System RADIUS – Remote Authentication Dial in User Service LDAP – Lightweight Directory Access Protocol IEEE – Institute of Eletrical and Eletronics Engineers AAA – Authentication, Authorization and Accounting ISP – Internet Service Provider NAS – Network Access Server PAP – Password Authentication Protocol CHAP – Challenge-Handshake Authentication Protocol
Sumário
1. Introdução ................................................................................................. 7 1.1 Objetivo .............................................................................................................. 9
1.1.1 Objetivo Geral .............................................................................................. 9 1.1.2 Objetivos Específicos ................................................................................... 9
1.2 Justificativa ..................................................................................................... 10 1.3 Organização do Trabalho ............................................................................... 10
2. Conceitos Básicos .................................................................................... 11 2.1 Autenticação, Autorização e Contabilização (AAA) .................................... 12
2.1.1 Autenticação .............................................................................................. 13 2.1.2 Autorização ................................................................................................ 15 2.1.3 Contabilização ............................................................................................ 16
2.2 Protocolos de Autenticação para equipamentos ........................................ 17 2.2.1 RADIUS ...................................................................................................... 17 2.2.2 TACACS+ .................................................................................................. 18 2.2.3 Diferenças entre RADIUS e TACACS+ ..................................................... 20
3. Tecnologias ............................................................................................... 22 3.1 openLDAP ........................................................................................................ 23 3.2 TAC_PLUS ....................................................................................................... 27 3.3 MAVIS ............................................................................................................... 27
4. Estudo de Caso – Rede UFSC ................................................................. 29 4.1 Projeto .............................................................................................................. 29
4.1.1 Cenário Atual ............................................................................................. 29 4.1.2 Cenário Proposto ....................................................................................... 31
4.2. Desenvolvimento ........................................................................................... 36 4.2.1 Cisco ACS .................................................................................................. 37 4.2.2 TAC_PLUS ................................................................................................. 39
4.3. Implantação .................................................................................................... 48 4.3.1 Estrutura Física .......................................................................................... 48 4.3.2 Implantação em Números .......................................................................... 51 4.3.3 Gerência do Ambiente ............................................................................... 52 4.3.4 Adequação com normas de segurança ..................................................... 60
5. Considerações Finais ............................................................................... 62 5.1 Trabalhos Futuros .......................................................................................... 63
Referências ................................................................................................... 65 Apêndices ...................................................................................................... 68
1. Introdução
Com o crescente número de usuários da rede UFSC, os equipamentos de
rede estão em constante mudança, seja por melhoria da infraestrutura, seja pelas
novas configurações que lhes são aplicadas.
Com esse quadro de modernização, esses equipamentos ganharam suporte a
novos protocolos, dentre os quais estão alguns que são usados para a gerência de
identidades de usuários, como o TACACS+ (METZ, 1999) e o RADIUS (IETF 2865,
2000).
Assim, é importante a utilização mais adequada das ferramentas baseadas
nos protocolos TACACS+ e RADIUS, a fim de aproveitar todas as vantagens
oferecidas, bem como permitir uma gerência mais segura dos ativos de rede.
Em um ambiente tão crítico e complexo como o de gerência da rede UFSC,
onde um comando errado pode acarretar em problemas de conectividade para
usuários e serviços, é preciso ter o maior controle possível do que é feito e por quem
é feito.
Para tanto, verifica-se a necessidade do uso de uma aplicação que realize o
gerenciamento das identidades dos usuários, para garantir que cada pessoa com
acesso ao equipamento faça apenas o que lhe é permitido e não tenha acesso total,
como acontece normalmente.
Tendo por base situações como esta, foi proposto um framework estrutural
que provê um conjunto de três funções de segurança, o AAA (Authentication,
Authorization e Accounting) (METZ, 1999). Baseado nesse framework, é possível
definir quem terá acesso (Autenticação), quais as ações que poderão ser feitas
depois de sua autenticação (Autorização), o horário que estas ações podem ser
feitas, bem como a geração de todos os logs das ações efetuadas para fins de uma
possível auditoria (Contabilização).
O presente trabalho é fundamentado nesse framework e no problema da
ausência de controle no atual ambiente de gerência da rede UFSC, que é apenas
usado nos roteadores, a fim de propor uma solução que poderá ser aproveitada para
uma variedade maior de equipamentos, desde que tenham suporte ao protocolo
TACACS+, possibilitando, assim, que o AAA seja utilizado, quando possível.
Outras questões muito importantes que envolvem a estrutura em análise diz
respeito à criticidade da aplicação, já que o acesso à gerência dos equipamentos
estará diretamente relacionada com o bom funcionamento dos servidores, à
carência de redundância dos serviços, para que, caso aconteça algum problema
com um servidor, ter um outro no mesmo estado para assumir os serviços, e à falta
de uma gerência proativa do ambiente, o que pode gerar contratempos caso
aconteçam problemas de um processo parar ou o disco encher e o administrador
não ser avisado, por exemplo.
Este trabalho tem por objeto realizar o estudo das principais tecnologias de
autenticação para equipamentos de rede, analisando seus funcionamentos e
características. Também será desenvolvida uma interface Web para a gerência do
ambiente e visualização dos logs dos usuários.
1.1 Objetivo
1.1.1 Objetivo Geral
O objetivo geral deste trabalho é projetar, desenvolver e implantar um
ambiente de autenticação centralizada para os administradores/operadores da rede
UFSC, construindo um ambiente com alta disponibilidade, diante da criticidade da
aplicação, e com segurança na troca de informações. Pretende-se utilizar apenas
implementações livres de tecnologias padrões como o OpenLDAP (BUTCHER,
2007) e o TAC_PLUS (HUBBER, 2011), que são alternativas a softwares
proprietários de empresas como Microsoft e Cisco, respectivamente.
1.1.2 Objetivos Específicos
Os objetivos específicos que podem ser citados neste trabalho são:
• Estudar o framework estrutural AAA;
• Estudar os protocolos RADIUS, TACACS+ e LDAP;
• Desenvolver uma interface web para a gerência do ambiente, cadastro de
novos usuários, grupos e equipamentos;
• Gerar alertas de status dos serviços associados com o ambiente (gerência
proativa);
• Substituir o atual sistema pelo proposto;
1.2 Justificativa
A rede UFSC está em pleno crescimento, tanto de usuários quanto de
equipamentos e serviços. Gerenciar todos esses equipamentos, sem um controle
rigoroso, tanto de acesso, quanto de modificações, pode ser um grande problema.
Um outro problema que é enfrentado pelos administradores é que são
contratados estagiários para ajudar na gerência e melhoria da infraestrutura da rede,
e estes, quando acaba o período de estágio, conhecem todas as senhas de acesso
aos equipamentos. Existem outros mecanismo de bloqueio de acesso de fora da
rede de gerência, mas mesmo assim é um ponto de falha gravíssimo alguém
externo à organização ter as credenciais para acesso aos equipamentos.
Além disso, a universidade cada vez mais é cobrada pela Controladoria Geral
da União para melhorar suas práticas de gestão de recursos de Tecnologia da
Informação baseando-se por exemplo, na ISO/IEC 27001 (ABNT, 2006).
Percebendo estas necessidades, este estudo tem como objetivos pesquisar,
desenvolver e implantar um ambiente onde problemas como os citados não
ocorram, utilizando tecnologias livres.
1.3 Organização do Trabalho
Este trabalho está dividido em cinco capítulos. O capítulo 2 se refere as
fundamentações teóricas sobre os conceitos básicos de AAA, RADIUS e TACACS+.
No capítulo 3 serão descritas as principais tecnologias utilizadas durante o estudo e
implementação do novo ambiente. O capítulo 4 confronta o cenário atual com o
proposto, justificando a implementação do novo sistema. Apresenta os resultados
obtidos com o novo ambiente, bem como as principais configurações necessárias
para o seu funcionamento. Por fim, no capítulo 5, serão apresentadas as
considerações finais e sugestões para trabalhos futuros.
2. Conceitos Básicos
Este capítulo tem o objetivo de descrever conceitos sobre os protocolos e
tecnologias referentes ao tema de autorização, autenticação e contabilização,
auxiliando no entendimento dos estudos realizados.
De acordo com TODOROV (2007), as informações são ativos importantes das
organizações e pessoas. A divulgação, modificação imprópria ou indisponibilidade
das informações podem gerar grandes prejuízos para a organização ou ao indivíduo.
Um ativo de informação é uma parte atômica que tem significado para o indivíduo ou
à organização, de modo que cada entidade, dentro de suas possibilidades, tenta
proteger essas informações.
Ambas as entidades tem tipicamente três requisitos para a proteção de ativos
de informação, que de acordo com a ISO/IEC 27001 (ABNT, 2006) são:
• Confidencialidade – Propriedade de que a informação não esteja
disponível ou revelada a indivíduos, entidades ou processos não
autorizados;
• Integridade – Propriedade de salvaguarda da exatidão e completeza de
ativos;
• Disponibilidade – Propriedade de estar acessível e utilizável sob
demanda por uma entidade autorizada.
Na linha de evolução da segurança, MATOS (1999) sugere que, à medida
que se desenvolveram as redes de computadores e as informações passaram a
trafegar livremente por elas, as preocupações acerca da segurança deixaram de
envolver apenas a parte física, ou seja, o acesso indevido ao prédio/sala onde a
máquina se encontrava, e passaram a cuidar do risco de acesso não autorizado aos
dados, criando a necessidade de proteção pela rede.
Nesse sentido, SOARES (1995) elucida que segurança na área da tecnologia
de computadores e rede
“[...] está relacionada à necessidade de proteção contra o acesso ou manipulação, intencional ou não, de informações confidenciais por elementos não autorizados, e a utilização não autorizada do computador ou de seus dispositivos periféricos. A necessidade de proteção deve ser definida em termos das possíveis ameaças e riscos dos objetivos de uma organização, formalizada nos termos de uma política de segurança.”.
Para CISCO ... (2006), o AAA é uma forma segura e eficaz de fazer o referido
controle de segurança, através do qual é possível configurar o controle de acesso
aos equipamentos de rede e servidores.
NAKHJIRI (2005) entende que o AAA são três blocos importantes usados na
construção da arquitetura de uma rede, que ajuda a proteger tanto os
administradores quanto os clientes contra fraudes, ataques, gestão de recursos
inadequados e perda de informação.
2.1 Autenticação, Autorização e Contabilização (AAA)
Segundo METZ (1999), provedores de serviços de Internet (ISPs) têm mais a
se preocupar do que somente garantir o acesso à rede aos seus clientes. É preciso
ter proteção contra ataques que possam prejudicar a disponibilidade do serviço.
Devem ser estabelecidos níveis de autorização, controle de acesso e fazer o registro
de todas as ações feitas durante a conexão.
Enfrentar esses desafios de forma simplificada e escalável é a principal tarefa
da Autenticação, Autorização e Contabilização (METZ,1999). O AAA, por sua vez,
nada mais é do que um framework estrutural para coordenar todas essa áreas sob
várias tecnologias de redes e plataformas.
Alguns dos benefícios de usar o AAA em equipamentos de rede são:
• Aumento da flexibilidade e controle do acesso a configuração;
• Escalabilidade;
• Métodos de autenticação padronizados como RADIUS, TACACS+ e
Kerberos.
2.1.1 Autenticação
Para TODOROV (2007), o processo de autenticação, geralmente, consiste
em duas fases distintas: a identificação e a autenticação.
• Identificação – provê a identificação do usuário ao sistema de
segurança. Esta identidade é geralmente fornecida através de um ID
único de usuário. O sistema de segurança normalmente procura por
todos os seus objetos abstratos que ele conhece e encontra o objeto
específico para os privilégios que o usuário atual está se submetendo;
• Autenticação – é o processo de validar a identidade do usuário. O fato
de o usuário dizer que é alguém, não necessariamente significa que
isso é verdade. Para ter certeza que o usuário é quem ele diz ser, o
usuário deve fornecer informações que comprovem sua identidade ao
sistema. As evidências fornecidas por um usuário em um processo de
autenticação são chamadas credenciais. Em sistemas computacionais,
as credenciais frequentemente tomam a forma de uma senha, a qual é
um segredo conhecido apenas pelo indivíduo e o sistema.
NAKHJIRI (2005) e TODOROV (2007) ressaltam que são tipicamente três
componentes interagindo em um processo de autenticação, como demostra a Figura
1:
• Usuário – é o usuário que tenta o acesso. É o responsável por
informar as credenciais, para provar sua identidade;
• Autenticador – é o responsável por toda interação com o usuário. Não
tem autoridade nenhuma para barrar por ele mesmo o acesso de um
suplicante ao serviço, podendo ser comparado com um guarda que
fica na porta de entrada de um prédio, verificando a identidade das
pessoas que desejam entrar. No modelo AAA é também conhecido
como NAS (Network Access Server), que, neste contexto, é
considerado um cliente;
• Servidor de Autenticação – é quem realmente tem a autoridade e
acesso à base de dados, para poder autorizar ou não o acesso do
cliente ao sistema.
Figura 1 - Modo de Autenticação de Três Partes. Fonte: Todorov (2007)
2.1.2 Autorização
Segundo CISCO ... (2006), a autorização provê o método de controle de
acesso. A autorização do AAA trabalha montando uma lista de atributos, que
descreve quais ações o usuário é autorizado a realizar.
“Autorização é definida como o ato de determinar se um privilégio especial
pode ser concedida para o apresentador de uma credencial particular.” (NAKHJIRI,
2005, p.7).
TODOROV (2007) ressalta que a autorização só entra em funcionamento
depois que o usuário estiver devidamente identificado e com as credenciais
validadas para ganhar acesso aos serviços.
2.1.3 Contabilização
A contabilização, conforme CISCO ... (2006), fornece o método de coleta e
envio de informações sobre as ações do usuário, sendo esses dados utilizados para
contabilizar, auditar e reportar. Possibilita saber os serviços que os usuários estão
acessando, como também a quantidade de recursos de rede que estão usando.
“Usuários são responsáveis pelas suas ações em um sistema. Usuários podem ser autorizados para acessar um recurso; se eles acessam, o sistema operacional ou a aplicação precisa fornecer uma trilha de auditoria que fornece dados históricos sobre quando e como um usuário acessou um recurso. Por outro lado, se um usuário tentou acessar um recurso, sem que ele tenha permissão para tal, uma trilha de auditoria ainda é necessária para determinar uma tentativa de violar o sistema de autorização e, em alguns casos, as políticas de autenticação.” (NAKHJIRI, 2005, p.8).
NAKHJIRI (2005) continua seu pensamento afirmando que as ações do
usuário devem ser registradas em caso de sucesso ou falha, bem como suas
tentativas de autenticação no sistema. Isso torna a contabilização muito útil a partir
de uma perspectiva de segurança.
Para TODOROV (2007), existe uma variedade de aplicações que são
definidas para o uso de contabilização, dentre as quais são citadas as seguintes:
• Auditoria: ato de verificar a conformidade das políticas de uso,
diretrizes de segurança e assim por diante;
• Análise de Tendências: utilizado na previsão de uso futuro para fins de
planejamento de capacidade.
2.2 Protocolos de Autenticação para equipamentos
Sistemas de autenticação, que utilizam protocolos como RADIUS e
TACACS+, estão sendo implementados com sucesso. Este capítulo descreve
algumas características de cada um desses protocolos.
2.2.1 RADIUS
RADIUS é um sistema distribuído cliente/servidor que previne as redes contra
acesso não autorizado (CISCO, 2006). Foi desenvolvido em meados de 1990 pela
Levingston Enterprise, com o fim de prover autenticação e auditoria para os
equipamentos de rede da organização (METZ, 1999).
Segundo o RFC 2865 (IETF, 2000), os seus atributos funcionais consistem
em:
• Modelo Cliente/Servidor – o equipamento de acesso à rede (NAS)
opera como um cliente do RADIUS. O cliente é o responsável por
passar as informações do usuário ao servidor RADIUS e depois agir de
acordo com a resposta retornada. O servidor RADIUS é o responsável
por receber o pedido de conexão do usuário, fazer a autenticação e
retornar todas as configurações necessárias ao cliente, para que este
consiga fornecer o serviço ao usuário, como mostra a Figura 2;
• Segurança de Rede – Transações entre o servidor RADIUS e o NAS
são autenticadas por uma chave compartilhada, que nunca é enviada
pela rede. As senhas dos usuários são enviadas cifradas entre o
cliente e o servidor para evitar o roubo em redes inseguras;
• Mecanismo de Autenticação Flexível – Um servidor RADIUS pode
suportar vários mecanismos de autenticação como PAP e CHAP;
• Protocolo Extensível – Novos valores de atributos podem ser
adicionados sem prejudicar as implementações existentes do
protocolo.
Figura 2 - Troca de mensagens usando RADIUS. Fonte: CISCO (2008)
Porém, o RADIUS deixa a desejar quando o assunto é segurança.
“Proteção de segurança no RADIUS é bastante primitivo. Duas funções principais são fornecidas, uma é esconder o atributo (principalmente senha) e o outro é autenticar certas mensagens. Ambas são realizadas usando funções de hash MD5 e um segredo é compartilhado entre o servidor RADIUS e o cliente (NAS).” (NAKHJIRI,2005, p131).
2.2.2 TACACS+
Outro protocolo que provê os serviços de AAA é o Terminal Access Controller
Access Control Protocol (TACACS). Originalmente descrito na RFC 1492 (IETF,
1993), foi reestruturado ao longo dos anos pela CISCO e é suportado por vários
servidores, roteadores e outros dispositivos encontrados nas redes empresarias de
hoje. A versão atual é chamada de TACACS+, que reflete as melhorias feitas no
protocolo original (METZ,1999).
De acordo com HARRIS (2007) o TACACS tem três gerações: TACACS;
XTACACS; TACACS+. Na verdade, o TACACS+ não é uma nova geração, é um
novo protocolo que provê funcionalidades similares. Por ser um protocolo totalmente
diferente, não é compatível com o TACACS ou XTACACS.
Para CISCO ... (2006), TACACS+ é uma aplicação de segurança que provê a
validação centralizada dos usuários que estão tentando acessar equipamentos de
rede ou servidores de acesso à rede. O Protocolo possibilita a instalação separada e
modular dos serviços de autenticação, autorização e contabilização. Outro ponto
muito importante, é que toda a troca de informações entre o equipamento de acesso
e o daemon é cifrado.
Figura 3 - Troca de mensagens usando TACACS+. Fonte: CISCO (2008)
A Figura 3 mostra todo o fluxo de comunicação entre um cliente e o servidor
TACACS+. Cada serviço, ou seja, autenticação, autorização e contabilização tem
um momento específico dentro deste fluxo. Para a autenticação, primeiro o cliente
faz uma requisição de acesso, o servidor retorna requisitando o nome de usuário e
depois a senha. Já para a autorização e a contabilização, para cada requisição
existe uma resposta. Quando o pacote inicial de verificação de acesso ao shell é
executado, é feita uma requisição de autorização, o servidor verifica se a permissão
existe e retorna o resultado. Com isso é enviado também uma requisição para início
de execução de contabilização, mesmo que o comando seja negado. Verificado se o
usuário tem permissão de acesso ao shell, inicia-se a requisição do comando e seus
parâmetros. Para cada requisição de comando é feita uma requisição de
contabilização, para gravar as ações do usuário. Ao fim desse fluxo é feita uma
requisição para parar o processo de contabilização. É importante ressaltar que esse
fluxo é feito para cada comando executado no equipamento.
2.2.3 Diferenças entre RADIUS e TACACS+
De uma forma resumida, para CISCO ... (2008), as principais diferenças entre
RADIUS e o TACACS+ são descritas na sequência:
Protocolo de Transporte:
O RADIUS utiliza UDP, ao passo que o TACACS+ usa TCP. TCP oferece
algumas vantagens em relação ao UDP, tais como:
• TCP oferece transporte orientado à conexão, enquanto o UDP oferece
o melhor esforço de entrega;
• TCP é mais escalável e adaptável para redes em crescimento ou
bastante congestionadas;
• Usando TCP é possível indicar se o servidor está com problemas ou
está desligado, já com UDP essa diferenciação não é possível.
Cifragem dos Pacotes
O RADIUS cifra apenas a senha do usuário no pacote de requisição de
acesso do cliente ao servidor. O resto do pacote é enviado sem estar cifrado. O
TACACS+, por sua vez, permite que todo o corpo do pacote seja criptografado,
sendo excluído apenas um cabeçalho, o qual possui um campo que indica se o resto
do pacote é cifrado ou não.
Autenticação e Autorização
RADIUS combina a autenticação e autorização. O pacote de acesso aceito do
servidor RADIUS para o cliente contém informações de autorização, dificultando o
desacoplamento dessas duas funções.
O TACACS utiliza a arquitetura AAA, na qual cada funcionalidade pode ser
usada independentemente. Isso possibilita o emprego de diferentes soluções de
autenticação, sendo possível ainda usar a autorização e a contabilização do
TACACS+. Um exemplo disso seria o uso da autenticação via Kerberos e o
TACACS+ para as funcionalidades de autorização e contabilização.
Suporte a Multiprotocolos
TACACS+ oferece suporte a multiprotocolos, já RADIUS não suporta:
• AppleTalk Remote Access protocol
• NetBIOS Frame Protocol Control protocol
• Novell Asynchronous Services Interface (NASI)
• X.25 Pad
Gerência de Equipamentos
A utilização do RADIUS não permite um controle mais profundo de quais
comandos podem ou não ser executados em um equipamento.
O TACACS+ oferece dois métodos de autorização de comandos. No primeiro
método, é possível definir um nível de privilégio para o usuário. Assim, o
equipamento verifica se o usuário tem nível de privilégio suficiente para executar um
comando ou não. Por padrão, os níveis de privilégio vão de 0 a 15, no qual zero
significa nenhum privilégio e quinze significa privilégio total. O outro método destina-
se a especificar os atributos dos usuários ou grupos e quais comandos eles terão
permissão de executar, deixando a verificação da permissão ou não do comando a
encargo do servidor TACACS+.
3. Tecnologias
Para o desenvolvimento do ambiente proposto, foram utilizadas apenas
tecnologias livres, que estão disponíveis livremente na Internet.
O openLDAP, que será usado para o armazenamento dos usuários, o
TAC_PLUS, que é a implementação de código aberto do protocolo TACACS+ e
interage com o openLDAP por meio do MAVIS.
Outras tecnologias foram usadas para o desenvolvimento do ambiente,
principalmente na interface administrativa do sistema, como javascript, JQuery,
AJAX, JSON, HTML, PHP e no servidor onde são armazenados todos os logs, foi
usado o MySQL como sistema gerenciador de banco de dados, mas como não
fazem parte do objetivo central, não serão explicadas.
3.1 openLDAP
O Lightweight Directory Access Protocol (LDAP) de uma forma simplificada, é
um protocolo para pesquisar e atualizar diretórios. Segundo a RFC 2251 (IETF,
1997), que define a versão três do protocolo, o LDAP segue o modelo de serviços de
diretório X.500, que é uma árvore de nós, cada um consistindo de um conjunto de
atributos com seus respectivos valores. O modelo X.500 era muito complexo para
ser suportado em desktops e através da Internet, então o LDAP foi criado para
prover este serviço.
Segundo CARTER (2003), diretórios são frequentemente confundidos com
bancos de dados. Ambos têm características em comum como rapidez em leitura e
extensibilidade de esquemas. A maior diferença é que diretórios são desenvolvidos
para terem mais operações de leitura do que escrita, já bancos de dados assumem
que essas operações ocorrem com mesma frequência. Em consequência a isto,
estruturas de diretórios não implementam transações e locks, como as bases de
dados.
Para CARTER (2003), serviços de diretórios podem assumir muitas formas,
mas cinco características, pelo menos, são verdadeiras:
• Otimizadas para leitura;
• Implementam modelos distribuídos de armazenamento de informações;
• Pode estender os tipos de informação que armazena;
• Recursos avançados de pesquisa;
• Replicação consistente entre servidores de diretórios.
O serviço de diretório X.500 ganhou o título de “pesado”. Nele, toda a
comunicação entre cliente e servidor é feita usando o a pilha do protocolo Open
System Interface (OSI), e como trabalha na camada de aplicação, o cabeçalho de
rede fica muito pesado.
Já o LDAP é considerado leve, como o próprio nome sugere, em comparação
com o X.500 pois utiliza mensagens com baixa sobrecarga, mapeadas diretamente
na camada TCP da pilha do protocolo TCP/IP.
A figura 4 ilustra essa comparação entre os dois serviços e suas respectivas
pilhas.
Figura 4 - Comparação entre o X.500 e o LDAP
Modelos LDAP representam os serviços providos pelo servidor, vistos por um
cliente. São modelos abstratos que descrevem as várias facetas de um diretório
LDAP. De acordo com a RFC 2251, um diretório LDAP é dividido em dois
componentes: modelo protocolo e modelo de dados.
O modelo de dados assume que o servidor garante acesso à árvore de
informações do diretório. A árvore é feita de várias entradas, estas, por sua vez,
possuem informações relevantes ao objeto.
Já o modelo protocolo basicamente define a forma de interação entre cliente e
servidor. O cliente faz uma requisição de uma operação sobre o diretório, o servidor
faz o processamento e retorna o resultado.
Até este momento foram apresentadas apenas algumas características dos
diretórios, em especial do LDAP. A partir de agora o foco será na estrutura da árvore
e dos objetos. Para tal considere como base as Figuras 5 e 6.
Figura 5 - Exemplo de uma árvore de diretório LDAP
O Distinguished Name (DN) é usado para identificar uma entrada de forma
não ambígua e única em um serviço de diretórios. Esse atributo é composto por uma
sequência de Relative Distinguished Name (RDN) e cada RDN corresponde a um
ramo na árvore do diretório, desde a raiz até a entrada à qual o DN faz referência.
Na árvore usada como exemplo, um DN possível é
dn:uid=luis,ou=Usuarios,dc=ufsc,dc=br e um RDN seria uid=luis.
Figura 6 - Exemplo dos atributos de um objeto
Na Figura 6, podemos visualizar os atributos e seus respectivos valores em
um objeto. Para fins de um melhor entendimento do desenvolvimento desde
trabalho, destacamos os atributos objectClass. Para a RFC 2251, um atributo
objectClass especifica as classes de um objeto, e permite determinar quais atributos
são válidos para uma entrada.
Segundo BUTCHER (2007) para utilizar um objectClass, o openLDAP utiliza
schemas, que são arquivos onde são definidos as diferentes classes dos objetos e
seus atributos que o openLDAP deve suportar, entre outras coisas. Usando estes, o
OpenLDAP pode determinar quais entradas são permitidas armazenar, se qualquer
entrada de dado é válida, e como as entradas devem ser idealmente armazenadas.
Uma outra possibilidade é a criação de schemas para uma maior customização dos
elementos de uma árvore LDAP.
Depois dessa visão geral sobre o openLDAP e seu funcionamento, que para
este projeto será usado como backend do ambiente, entraremos em detalhes das
tecnologias utilizadas para prover os serviços de AAA.
3.2 TAC_PLUS
De acordo com HUBBER (2011), principal desenvolvedor do projeto, o
tac_plus é um daemon dirigido a eventos do TACACS+, ou seja, seu funcionamento
esta extremamente relacionado ao envio e recebimento de eventos. Provê os
serviços de autenticação, autorização e contabilização para roteadores Cisco e
outros equipamentos de rede, desde que suportem o protocolo. É uma reformulação
do código-fonte original do TACACS da Cisco. Alguns dos principais recursos
incluem:
• Flexibilidade de backends externos para perfis de usuários (LDAP,
Active Directory e RADIUS);
• Multiplexação das conexões – múltiplos clientes por processo;
• Escalabilidade – sem limite de usuários, servidores ou clientes;
• Suporte aos protocolos IPv4 e IPv6;
• Compilado com a especificação mais recente do protocolo TACACS+;
Para poder oferecer a já falada flexibilidade de backend, o tac_plus usa um
outro módulo chamado MAVIS e que será explicado a seguir.
3.3 MAVIS
O Modular Attribute-Value Interchange System (MAVIS) é uma biblioteca que
provê um protocolo extensível e modular para as tarefas de autenticação e
autorização. Também funciona como um subsistema de autenticação modular,
usado pelo daemon tac_plus. Esta biblioteca contem vários módulos para o uso de
diversos backends e um deles é para serviço de diretório, seja o openLDAP ou o
Active Directory da Microsoft.
Para poder usar todas suas vantagens é só adicionar um novo arquivo de
schema no servidor LDAP e em cada objeto que poderá fazer uso das
funcionalidades do tac_plus, adicionar o objectClass “tacacsAccount“ e seus
respectivos atributos.
4. Estudo de Caso – Rede UFSC
A partir deste capítulo passa-se a discorrer sobre o ambiente proposto. Serão
abordadas três fases: Projeto, Desenvolvimento e Implantação.
No Projeto será analisado o ambiente atual e apresentado uma solução que
resolva suas limitações. No Desenvolvimento será exposto com mais detalhes as
configurações do ambiente. Já na Implantação serão apresentados os resultados de
desenvolvimento.
4.1 Projeto
Nesta seção será descrito e analisado o ambiente atual, listando as
deficiências que motivaram às modificações e melhorias que são descritas no
ambiente proposto.
4.1.1 Cenário Atual
O ambiente de autenticação atual é simples e tem problemas de segurança.
Da forma como é usado, a autenticação é bastante limitada e o uso de
contabilização e autorização é implementada apenas nos equipamentos de core
(núcleo) da rede. A Figura 7 mostra como é o fluxo da informação em um processo
de autenticação. Nos roteadores existe um agente externo, que é o servidor Cisco,
participando da autenticação e também da autorização, como indica o número 2.
Figura 7 - Processo de autenticação atual
Já para os demais equipamentos, indicados pelo número 1, não existe
nenhum sistema atuante no processo de autenticação, sendo que os usuários são
autenticados na base de dados local destes equipamentos. Pelo fato da
autenticação ser feita dessa forma, vários problemas são gerados, dentre eles:
• Se não for criada uma credencial para cada usuário, todas as pessoas
que terão acesso precisam saber a senha do usuário administrador;
• Se cada pessoa tiver sua credencial, é necessário o acesso em todos
os equipamentos e criar na base local a conta para o usuário;
• Caso seja necessário trocar alguma senha, seja de administrador ou
de um usuário, é preciso acessar cada equipamento e fazer a
mudança;
• Caso seja preciso retirar o acesso de um usuário de um equipamento,
ou de todos, é necessário remover as credenciais de cada
equipamento onde existir o registro;
• No caso de equipamentos que suportam o serviço de autorização e
não existir a política de cada usuário ter uma credencial, todo mundo
terá o mesmo nível de privilégio, desde pessoas com mais experiência
aos mais inexperientes;
• Nos equipamentos que suportam o serviço de contabilização,
principalmente os de core (núcleo), se todos usarem as credenciais de
administrador, não é possível saber quem executou determinado
comando no equipamento, pois todos usuários fazem o login com a
mesma conta.
• Faltou falar da trilha de auditoria tanto no que se refere para toda a
estrutura AAA
Assim, o principal problema do cenário atual é a gerência das identidades dos
usuários, já que para fazer qualquer alteração, tanto para mudança de senha,
quanto para permitir um novo usuário, será obrigatório o acesso em cada
equipamento para fazer essas alterações. Por outro lado este ambiente tem um
ponto muito importante que é o funcionamento independente de outros sistemas,
reduzindo assim os pontos de falha.
4.1.2 Cenário Proposto
Tentando resolver todos as deficiências expostas, foi elaborado um ambiente
com características que possibilite, além de todas as principais funcionalidades do
AAA, uma alta disponibilidade e confiabilidade, como mostra o desenho esquemático
da Figura 8.
Figura 8 - Arquitetura do ambiente proposto
Na infraestrutura proposta, existem dois servidores virtualizados, um
funcionando como master e outro como slave. Os softwares adotados utilizam
daemons, que, conforme OLIVEIRA, CARISSIMI e TOSCANI (2001), são processos
do sistema, e realizam as tarefas do próprio sistema, e não do usuário. Em cada
servidor foram instalados os daemons:
• LDAP e TACACS+ - utilizados para fazer a gerência das identidades,
todas as regras e permissões para as autorizações e interação com os
equipamentos de rede;
• MySQL – utilizado para armazenamento todos os logs gerados na
utilização do sistema, tanto na parte de contabilização quanto das
interfaces administrativas;
• Apache – servidor web para hospedar a aplicação de administração e
monitoramento do ambiente.
Os servidores são independentes entre si, ou seja, se um comutador de rede
for configurado para utilizar o servidor master, e outro equipamento for configurado
para o slave, ambos devem ter os mesmos resultados. Isso é possível pois todos os
arquivos de configurações, bases de dados do MySQL e os diretórios LDAP são
replicados bidirecionalmente entre as máquinas. Para isso, no MySQL e no LDAP
foram configurados os serviços de replicação dos próprios daemons.
Já os arquivos de configurações, principalmente os do TACACS+, são
sincronizados utilizando o softwares Unison File Synchronizer. De acordo com
PIERCE (2009), principal desenvolvedor do projeto, o Unison é uma ferramenta de
sincronização de arquivos, disponível para Unix e Windows. Permite a réplica de
arquivos e diretórios usando diferentes tipos de ferramentas como por exemplo CVS,
Coda e Rsync.
Para acesso às máquinas, foi definido que cada servidor teria configurada
uma interface de rede para acesso roteado, ou seja, quando os endereços IP de
quem está fazendo o acesso não pertencem ao mesmo segmento de rede do
servidor. Além da interface roteada, vão ser configuradas interfaces em cada rede
de gerência de equipamentos. Isso possibilita o acesso aos equipamentos mesmo
que haja problemas na rede a nível de roteamento, já que os switches, roteadores e
servidores de autenticação estarão em camada dois (enlace) no modelo TCP/IP. O
acesso ficará comprometido apenas em casos de problemas no meio físico, como
por exemplo rompimento de fibra ou cabo de rede. A Figura 9 exemplifica as
configurações de rede dos servidores.
Figura 9 - Infraestrutura de rede dos servidores
Supondo que o servidor AAA tenha as seguintes interfaces de rede
configuradas:
• rede1 – IP: 10.0.1.1
• rede2 – IP: 10.0.2.1
• Interface Roteada – IP: 10.0.5.1
Qualquer equipamento pertencente a rede 10.0.1.0/24 fará toda a
comunicação pela interface 10.0.1.1. O mesmo ocorre para equipamentos com IPs
pertencentes a rede 10.0.2.0/24, que farão acesso pela interface 10.0.2.1.
Caso um usuário ou equipamento com o IP 10.0.6.5 queira fazer acesso ao
sistema, toda a comunicação acontecerá pela interface 10.0.5.1 pois o servidor não
tem nenhuma interface configurada para a rede 10.0.6.0/24, sendo necessário o uso
de roteamento.
Além disso, será usado um outro daemon, o UCARP, que servirá para fazer
com que a disponibilidade do ambiente seja transparente ao usuário. Para DENIS
(2010), o UCARP é uma implementação portátil do protocolo CARP (Common
Address Redundancy Protocol). Com ele é possível, por exemplo, configurar uma
máquina para responder ao IP 10.0.5.1, a outra ao IP 10.0.5.2 e criar uma interface
virtual que responda no endereço 10.0.5.3. O próprio daemon, quando recebe uma
requisição no seu endereço, é o responsável por fazer o “roteamento” e enviar os
pacotes para o servidor que estiver com o melhor tempo de resposta. Isto é muito
útil, pois caso aconteça algum problema com um servidor de exemplo 192.168.1.2, e
ele estiver configurado como master, o daemon encaminha todo o tráfego para o
servidor com o IP 192.168.1.3 sem que o usuário perceba.
Uma outra mudança significativa em relação ao ambiente anterior é no que
diz respeito ao fluxo dos dados no ambiente, após o usuário informar suas
credenciais. Diferente do que era, onde para a grande maioria dos equipamentos
não havia nenhum sistema de suporte as funcionalidades de AAA, agora todas as
requisições são recebidas por um servidor, que faz todo o processamento e retorna
as informações necessárias. Esse processo pode ser melhor visualizado na Figura
10.
Figura 10 - Fluxo dos dados no ambiente proposto
Nesse caso os equipamentos acabam funcionando como suplicantes,
repassando as credenciais ou informações do usuário para o autenticador (servidor
AAA). Esse comportamento é que possibilita ao servidor AAA analisar as
informações, e de acordo com as configurações do daemon autenticar, autorizar e
gerar logs de tudo que é feito nesse processo de interação do usuário com o
equipamento.
Uma outra funcionalidade do ambiente é a possibilidade de integração da
autenticação de máquinas Windows e Linux, independente de serem estações de
trabalho ou servidores. Isso possibilita que com apenas uma credencial o usuário
possa acessar o sistema de autenticação nos comutadores de rede e também nas
suas máquinas pessoais e/ou servidores.
4.2. Desenvolvimento
Apresentados o funcionamento do ambiente, bem como o propósito que se
pretende alcançar com o presente trabalho, neste momento, passa-se a discorrer
sobre duas ferramentas que possuem mecanismos capazes de solucionar as
necessidades verificadas anteriormente. Foram analisadas duas ferramentas para
desenvolver o projeto proposto:
• Cisco Secure Access Control Server 5.1 (ACS) (CISCO, 2012);
• TAC_PLUS (HUBBER, 2011).
Como a ferramenta desenvolvida pela Cisco possui algumas limitações, que
serão explicadas no texto, foi escolhida a solução utilizando o TAC_PLUS MAVIS
para uso no projeto.
4.2.1 Cisco ACS
Segundo CISCO...(2012), o Secure Access Control Server (ACS) é um
servidor de segurança baseado em políticas que fornece os padrões de
autenticação, autorização e contabilização (AAA) para uma rede. Facilita o
gerenciamento administrativo de aplicações e dispositivos, sejam eles Cisco ou não.
Também serve de ponto de integração entre o controle de acesso à rede e o
gerenciamento de identidade.
Dentro do contexto dos dois principais protocolos do AAA – RADIUS e
TACACS+ – o ACS tem as seguintes áreas funcionais:
• No framework do protocolo RADIUS, o ACS controla o acesso cabeado
ou wireless por usuários e máquinas à rede e gerencia os recursos de
rede utilizados por meio de contabilização. Suporta múltiplos métodos
de autenticação do RADIUS incluindo PAP, CHAP, MSCHAPv1,
MSCHAPv2 e outros da família de protocolos EAP como EAP-MD5,
LEAP, PEAP, EAP-FAST e EAP-TLS;
• Já no framework do protocolo TACACS+, o ACS facilita o
gerenciamento administrativo de equipamentos como switches, pontos
de acesso wireless, roteadores e gateways, como também serviços
como acesso dial-up, VPN (Virtual Private Network) e firewall, sendo
Cisco ou não.
O ACS é o responsável por identificar usuário e dispositivos que tentam
acessar a rede. Essa identificação pode ocorrer diretamente no repositório interno
de identidades para fazer autenticação local, mas também existe a possibilidade do
uso de repositórios externos como:
• LDAP
• Active Directory
• RSA SecurID Token Server
• RADIUS Identity Server
Outro detalhe importante são os recursos necessário para a instalação da
aplicação. De acordo com CISCO...(2011), existem duas formas para a instalação
do ACS, usando uma máquina virtual no hipervisor VMWare ou em um hardware
específico da Cisco. Caso seja instalado o ACS no formato de uma máquina virtual,
o sistema operacional é um Linux Red Hat 5 e é exigido pelo menos 500 GB de
espaço de disco para funcionar nas configurações mínimas de avaliação do sistema.
Estas características do ACS acabam se transformando em problemas pois
necessitam de muitos recursos, tanto de hardware como financeiros para a compra
de software. Para a instalação do ambiente proposto, com todos os componentes já
citados, seria necessária a aquisição de duas licenças do ACS 5.1 e pelo menos 2
TB de capacidade de armazenamento, que é o recomendado pela Cisco para o uso
em ambiente de produção.
Outra limitação que acabou deixando muito a desejar diz respeito ao suporte
à equipamentos de outras empresas, já que o ACS não suporta, quando instalado
sem nenhum modificação, o uso de autorização em equipamentos que não são da
Cisco. Comparando com a realidade da rede UFSC, onde existe uma
heterogeneidade nos equipamentos, este é o principal ponto negativo, pois desta
forma a solução só funcionaria de maneira satisfatória nos equipamentos de core da
rede, da mesma forma que é feito atualmente. Para os demais equipamentos, o ACS
funcionaria apenas para suporte à autenticação.
4.2.2 TAC_PLUS
Considerando que já foi exposto o conceito do daemon TAC_PLUS na seção
3.2, foram feitos dois testes distintos:
• Compilação padrão
• Compilação TAC_PLUS MAVIS
Da forma padrão o TAC_PLUS é limitado. Uma das principais limitações é
que todos os usuários, dispositivos e demais diretivas precisam estar cadastrados
no arquivo de configurações do daemon. Isso é um grande problema já que para
adicionar cada novo usuário ao sistema é necessário que um administrador edite o
arquivo de configurações e depois reinicie o daemon. Se por acaso alguém estiver
executando algum comando no equipamento exatamente na hora em que o daemon
é reiniciado, o comando será negado, por exemplo. Caso o usuário não esteja
cadastrado no arquivo de configurações, é possível fazer login utilizando o PAM
(Pluggable Authentication Modules) do servidor linux. Desta maneira também é
necessário ter um registro no arquivo de configurações mostrando que, para aquele
usuário específico, as informações serão fornecidas pelo sistema operacional. Um
exemplo dessa configuração pode ser visto na Figura 11, onde o usuário luís é
autenticado via PAM e o usuário joão via arquivo de configuração.
Figura 11 - Exemplo de Configuração de usuários no tac_plus
Utilizando a compilação padrão, o PAM é uma peça fundamental ao sistema
pois é através dele que o TAC_PLUS tem a possibilidade do uso de recursos
externos para a autenticação, como por exemplo o LDAP. O funcionamento é bem
simples:
1. Quando o usuário está configurado para autenticar via PAM, o daemon
busca as credenciais do usuário da base local do sistema operacional.
2. É instalada uma biblioteca ao PAM que permite que ele verifique as
credenciais de um usuário em um diretório LDAP.
3. Essa biblioteca é configurada para que sempre a primeira opção de
busca seja feita na base local, e caso não seja encontrado o usuário, a
busca é feita no diretório LDAP.
Essa obrigatoriedade do uso do PAM deixa todo o sistema um tanto quanto
inflexível, pois centraliza tudo no arquivo de configurações, ao invés de ter uma
forma simples de possibilitar a gerência de todo o daemon.
Outra limitação é não possibilitar que um usuário tenha várias políticas de
acesso. Dessa forma o usuário terá o mesmo nível de privilégio para todos os
equipamentos que ele tiver acesso. Caso o usuário em questão seja um estagiário,
ou qualquer outro que deve ter níveis de acesso distintos, e precise de acesso total
a algum tipo de equipamento, seja ele de borda ou core, existem duas opções:
• Criar uma Access Control List (ACL) onde é negado o acesso a
equipamentos de maior criticidade, como por exemplo os de core, e
vinculá-la às suas definições no arquivo de configurações. Dessa
forma o usuário não terá acesso ao equipamento;
• Permitir o acesso ao equipamento com todos os privilégios garantidos
pelas configurações. A Figura 11 ilustra um caso onde os dois
usuários têm o mesmo nível de privilégio para todos os equipamentos,
já que não existe nenhuma ACL associada com nenhum deles. Os
níveis de privilégios são garantidos pela variável member. Na variável
cmd da diretiva group são listados os comandos liberados para quem
pertence a este grupo. No caso mostrado na Figura 11, os dois
usuários cadastrados pertencem ao mesmo grupo GrupoTeste,
portanto têm o privilégio de executar os mesmos comandos como por
exemplo show, traceroute, ping, logout e exit.
Usando o TAC_PLUS MAVIS (explicado na seção 3.3) algumas dessas
limitações são atendidas. Primeiramente, o daemon tem suporte nativo a agentes
externos como:
• Active Directory;
• LDAP;
• RADIUS.
Caso a autenticação esteja configurada para acontecer via Active Directory ou
LDAP, a solução torna-se ainda mais completa, pois permite que sejam definidos
atributos específicos nos registros do diretório e não somente no arquivo de
configurações. O exemplo da Figura 12 mostra a adição dos três novos atributos -
tacacsClient, tacacsMember e tacacsProfile – que são responsáveis por possibilitar
a flexibilidade necessária com o seu uso.
Figura 12 - Exemplo de uma entrada LDAP com suporte ao TAC_PLUS MAVIS
tacacsClient
Define o endereço IP ou segmento de rede de onde o daemon pode aceitar a
conexão do usuário. Funciona de forma semelhante a um firewall, analisando a
origem da requisição e permitindo, ou não, o acesso ao equipamento. Na Figura 12
o usuário tem acesso somente a partir da rede 150.162.248.0/24, ou seja, se esse
usuário específico tentar se conectar pela rede 150.162.161.0/24, mesmo não
havendo um firewall instalado no servidor, o acesso será negado. É possível
também especificar o endereço IP exato para o acesso, como por exemplo
150.162.248.43/32.
tacacsMember
Atributo responsável pela definição das políticas de acesso. As sintaxes
permitidas são as seguintes:
• nível de privilégio;
• nível de privilégio@grupo de equipamentos.
Tanto o nível de privilégio quanto o grupo de equipamentos são configurados
no arquivo de configurações do daemon. Cada nível de privilégio é composto por
uma lista de comandos possíveis de serem executados para aquele nível. A Figura
13 exemplifica a configuração dos níveis de privilégios.
Figura 13 - Exemplo de configuração de níveis de privilégios
Como mostrado na Figura 13, usuário que possuem o atributo tacacsMember
como admin_1, terão permissão de executar todos os comandos existentes no
equipamento pois o padrão da configuração é permitir tudo. Já para os casos onde o
atributo for operador_2, o padrão para esse nível é negar (default command =
deny) o comando, exceto para os casos de comandos listados pelos campos cmd,
que são usados para especificar alguns comandos com permissão.
Foram definidos 4 níveis de privilégios para atender as demandas de
autorização do ambiente:
• admin_1 – acesso total, sem restrições;
• admin_2 – pode ver todas as configurações. Alterar apenas ACLs,
Interfaces e VLAN;
• operador_1 – pode ver todas as configurações, exceto running-config.
Alterar apenas Interface;
• operador_2 – apenas ver configurações de rotas, arp, interface, log,
VLAN, processos, spanning-tree;
• Todos os níveis podem executar os comandos de ping e traceroute.
No caso dos grupos de equipamentos, podem ser definidos endereços IP de
um ou mais equipamentos, ou segmentos de rede, e a chave secreta que é usada
para autenticar o equipamento no servidor TACACS+. Um exemplo simples da
configuração de grupos pode ser visto na Figura 14.
Figura 14 - Exemplo de configurações de grupos de equipamentos
Cada escopo marcado como host define o grupo. Pode ter um ou mais
address, que são os endereços IP dos equipamentos deste grupo e uma key, que é
a chave de autenticação no daemon que deve ser configurada igual no equipamento
pertencente ao grupo.
tacacsProfile
Usado para definir mais algumas variáveis ao registro. Utilizando este atributo
é possível definir tempo de validade do registro, caso seja necessário liberar o
acesso por um tempo determinado, fazer restrições de acesso por horário e também
fazer o uso de ACLs para restringir ou permitir o acesso a outros equipamentos.
Alguns exemplos dessas definições podem ser vistas na Figura 15.
Figura 15 - Definições de especificações de tempo e ACLs
No exemplo de usuário mostrado na Figura 12, o atributo tacacsProfile possui
duas definições, uma definindo a validade das credenciais e outra uma
especificação de tempo, indicando o período do dia que o acesso será liberado. A
acl acl_horario_padrao, mostrada na Figura 15, para a qual a credencial está
configurada, restringe o acesso para apenas os dias da semana, em horário
comercial, das 8 as 18 horas.
Todas essas possibilidades acabam deixando o sistema muito mais dinâmico
e simples, pois não será mais necessário fazer acesso ao servidor e editar o arquivo
de configurações sempre que for preciso criar/editar/excluir uma credencial. Desta
forma foi criada uma nova necessidade, o desenvolvimento de uma aplicação para
fazer a gerência de todo o ambiente.
4.3. Implantação
Esta seção tem o objetivo de descrever o ambiente de implantação, bem
como a estrutura e os equipamentos suportados. Também serão apresentados os
resultados da implantação e os sistemas de gerência e acompanhamento de logs
que foram desenvolvidas.
4.3.1 Estrutura Física
No desenvolvimento deste ambiente, foi trabalhado com dois tipos de
infraestrutura:
• Servidores;
• Comutadores de rede.
Para a infraestrutura de servidores foram criadas duas máquinas virtuais,
hospedadas em um ambiente com o hipervisor VMWare. Cada uma possui dois
processadores virtuais Intel® Xeon® de 3.33GHz, capacidade de armazenamento
de 24 GB e 2GB de memória. Além destas características de hardware, cada
servidor tem associado a ele cinco interfaces de rede, para possibilitar o uso dos
recursos descritos na seção 4.2, quando é descrito a forma de acesso aos
servidores.
No caso da infraestrutura dos equipamentos de rede, a rede UFSC dispõe
principalmente dos seguintes modelos de equipamentos:
• Cisco Router 7606 (Figura 16)
Figura 16 - Roteador Cisco 7606
Uso: Core da rede.
Principais Características: Faz o roteamento de toda a rede. Possui
interfaces 1Gb e 10Gb via fibra óptica para fazer a conexão tanto ao PoP-SC,
quanto aos principais equipamentos de distribuição da UFSC, seja para rede
cabeada ou sem fio.
Suporte ao ambiente: implementa autenticação, autorização e
contabilização.
• 3Com SuperStack® 4 5500G (Figura 17)
Figura 17 - Switch 3Com 5500G
Uso: Usados principalmente para a distribuição dos centros da UFSC.
Principais Características: Interfaces 1Gb via fibra óptica ou cabo UTP.
Suporte ao ambiente: implementa autenticação, autorização e
contabilização.
• D-Link DGS 3100-24/48 PoE
Figura 18 - D-Link DGS 3100 PoE
Uso: Equipamentos usados principalmente para acesso dos usuários (borda).
Principais Características: Interfaces 1Gb via cabo UTP, sendo que as
quatro ultimas podem ser optado pelo uso de fibra óptica. São utilizados modelos de
24 e 48 portas e alguns com a opção de PoE (Power over Ethernet).
Suporte ao ambiente: implementa autenticação e autorização com apenas
dois tipo de privilégio, acesso total ou somente leitura.
• Cisco Wireless LAN Controller 5500
Figura 19 - Cisco WLC 5500
Uso: Faz o controle centralizado dos pontos de acesso sem fio Cisco.
Principais Características: Permite a gerência de múltiplos pontos de
acesso de forma centralizada.
Suporte ao ambiente: implementa autenticação, autorização e
contabilização.
Além destes equipamentos citados, alguns outros modelos também estão
operando com pelo menos a autenticação pelo ambiente. Estes equipamentos são:
• Cisco Catalyst 3560
• Cisco Catalyst 2960G
• D-Link DES 3526
• D-Link DES 3028P
• Edge-Core ES3526XA
4.3.2 Implantação em Números
A SeTIC controla por volta de 850 equipamentos de rede, dos quais, cerca de
630 são gerenciáveis, ou seja, possibilita aplicar configurações. Destes,
aproximadamente 400 já estão, ou têm suporte, pelo menos para o uso de
autenticação pelo sistema proposto. Esse número é baseado apenas em
equipamentos Cisco, 3Com e D-Link, sem contar os equipamentos de outras
fabricantes como SMC, Dell, Enterasys e HP, onde ainda não foram feitos os testes
de suporte.
De todos esses comutadores suportados pelo sistema, dois são usados como
roteadores principais, quatro são controladores da rede sem fio, cinco são switchs
de distribuição de centro e o restante é considerado de borda ou distribuição local.
4.3.3 Gerência do Ambiente
Foram desenvolvidas duas aplicações para a gerência do ambiente:
• Logs - para acompanhamento em tempo real dos comandos
executados nos equipamentos;
• Gerência – para gerenciar as identidades e permissões de acesso ao
sistema.
Para o desenvolvimento da aplicação de logs foram usadas as linguagens de
programação perl, para analisar e inserir os logs gerados pelo TAC_PLUS MAVIS
em uma base MySQL, e o PHP para a criação da interface onde os administradores
possam acompanhar/auditar as ações feitas no sistema.
Imagens da interface de logs podem ser vistas nas Figuras 20, 21 e 22.
Figura 20 - Interface de Logs - logs de comandos
A Figura 20 mostra os logs apenas de comandos executados no sistema.
Informações importantes podem ser visualizadas como a hora que o comando foi
executado, o endereço IP do equipamento onde o comando foi executado, o usuário
que executou o comando, o endereço IP do usuário e o comando executado,
indicando se foi permitido (permit) ou negado (deny).
Figura 21 – Interface de Logs - logs de acessos
Na Figura 21 mostra o acompanhamento de logs de acesso aos
equipamentos. A interface é parecida com a de acompanhamento de comandos,
sendo diferente na ultima coluna da tabela, onde é indicado o status do processo de
autenticação.
Figura 22 - Interface de Logs - logs de acessos 2
Já na Figura 22 é mostrada a mesma interface da Figura 21, só que foi
aplicado um filtro para mostrar apenas registros onde o status é “Usuário não
encontrado”. Percebe-se que na maior parte dos casos, o acesso é feito por usuário
externos à rede UFSC, indicados pelo endereço IP não pertencentes a faixa utilizada
pela universidade. Este indicador, associado com a tentativa de login utilizando o
nome de usuário como admin e root é um comportamento que pode sugerir algum
ataque de invasão por força bruta ao equipamento, por exemplo.
Além de acompanhar os logs é possível aplicar filtros para refinar os
resultados das buscas e a atualização dos dados é feita em tempo real.
No caso da interface de gerência das identidades foi usado principalmente
PHP como linguagem de programação, interagindo com o diretório LDAP, onde
ficam armazenadas as credenciais dos usuários.
As Figuras 23, 24 e 25 mostram alguns dos módulos do sistema.
Figura 23 - Interface de gerência - visão inicial
A Figura 23 mostra a visão geral do sistema, após o usuário fazer o login na
interface WEB. É possível saber se todos os processos essenciais ao ambiente
estão sendo executados, como também um monitoramento das partições do
servidor. É importante salientar que para todos esses casos, tanto dos processos,
quanto das partições, caso aconteça algum incidente, é enviado um e-mail
automaticamente aos administradores do sistema para informar do ocorrido.
Figura 24 - Interface de gerência - acompanhamento de comandos
Outro recurso é o histórico de comandos, mostrado na Figura 24. Nele é
possível que os usuários possam ter um histórico dos comandos que eles próprios
executaram nos equipamentos. Na interface de logs apresentada anteriormente,
apenas os administradores têm acesso, pois envolve ações de todos os usuário. Já
nesse caso, cada usuário pode apenas acompanhar suas ações.
Figura 25 - Interface de gerência - adicionar usuário
A Figura 25 mostra o módulo de gerência das credenciais dos usuários. É
possível definir todos os atributos requeridos pelo LDAP para o correto
funcionamento com o TAC_PLUS MAVIS. Quando a opção Tacacs+ está
selecionada nas “Opções da Conta” é exibido três novos atributos: Rede de Acesso,
Perfil e Membro. Cada um desses atributos corresponde àqueles atributos do
TAC_PLUS MAVIS mostrados na seção 4.2.2.
Apresentados as duas aplicações desenvolvidas, será mostrado uma imagem
esquemática da funcionamento geral do ambiente (Figura 26).
Figura 26 - Funcionamento geral do ambiente
Os administradores têm acesso tanto as duas aplicações, gerência do
ambiente e visualizaçãoo de logs. Essas duas aplicações ficam hospedadas no
próprio servidor, sendo que a de gerência do ambiente interage com o LDAP e a de
logs com o MySQL.
O usuário pode utilizar o sistema de gerência para alterar suas informações
pessoais, como senha, e-mail e telefone, como também visualizar seu histórico de
comandos.
Tanto os administradores quanto os usuário podem ter acesso aos
equipamentos de rede, desde que possuam permissão para tal.
Já os equipamentos de rede interagem com o daemon TAC_PLUS MAVIS
para autenticar e autorizar os acessos dos usuários.
4.3.4 Adequação com normas de segurança
Órgãos públicos estão sendo cada vez mais cobrados sobre questões de
melhores práticas de gestão dos recursos de TI e com a UFSC isso não é diferente.
A Controladoria Geral da União (CGU) em suas auditorias exige a adequação da
universidade a frameworks de gestão da segurança em TI como a ISO27001
(ABNT,2006). Em função disso, é necessário um conjunto de ações para adequar e
melhorar os sistemas utilizados.
De acordo com ABNT (2006) a ISO 27001 é dividida em 11 domínios
diferentes, sendo que cada domínio tem objetivos de controle e estes, por sua vez,
possuem controles.
No desenvolvimento do presente trabalho conseguiu-se uma adequação com
os seguintes objetivos de controle e controles:
• A.10 Gerenciamento das Operações e comunicações
o A.10.10 Monitoramento
§ A.10.10.1 Registros de auditoria
§ A.10.10.2 Monitoramento do uso do sistema
§ A.10.10.3 Proteção das informações dos registros(logs)
§ A10.10.4 Registros (log) de administrador e operador
§ A10.10.5 Registros (log) de falhas
• A.11 Controle de acessos
o A.11.1 Requisitos de negócio para controle de acesso
§ A.11.1.1 Políticas de controle de acesso
o A.11.2 Gerenciamento de acesso do usuário
§ A.11.2.1 Registro de usuário
§ A.11.2.2 Gerenciamento de privilégios
§ A.11.2.3 Gerenciamento de senha do usuário
o A.11.5 Controle de acesso ao sistema operacional
§ A.11.5.2 Identificação e autenticação do usuário
§ A.11.5.3 Sistema de gerenciamento de senha
§ A.11.5.5 Limite de tempo de sessão
§ A.11.5.6 Limite de horário de conexão
Não é garantido que todos os controles citados são realmente utilizados, mas
as aplicações desenvolvidas dão e têm suporte total a todos eles.
5. Considerações Finais
O presente trabalho de conclusão de curso teve como propósito demonstrar
todo o processo de desenvolvimento e implantação de um ambiente de
autenticação, autorização e contabilização para equipamentos de rede em um
cenário heterogêneo.
Para tanto, buscou-se estudar os principais conceitos relacionados ao
assunto, bem como as tecnologias mais utilizadas e de fácil acesso para a
realização do desenvolvimento.
Foram realizados dois ambientes de teste. No primeiro foi utilizado o software
proprietário da Cisco (ACS 5.1) que por mais robusto que seja, não supriu as
necessidades, principalmente por ser muito voltado a equipamentos e serviços da
própria CISCO. Já no outro teste, empregou-se apenas tecnologias livres como os
daemons TAC_PLUS MAVIS e openLDAP, que implementam os protocolos
TACACS+ e LDAP, respectivamente, os quais juntos possibilitaram a flexibilidade de
uso exigida para um ambiente com as características do encontrado na rede UFSC.
Depois da implantação de forma definitiva do ambiente, foi atingida a marca
de cerca de 70% dos equipamentos configurados para autenticar utilizando o
ambiente proposto, o que é um número bastante significativo até o momento, à
medida que ainda não foram realizados testes com todas as marcas e modelos de
equipamentos encontradas na rede. Registra-se, ainda, que o uso do ambiente pode
influenciar também nos processos de licitação para compra de novos equipamentos,
que pode passar a exigir que tenham suporte completo ao protocolo TACACS+,
filtrando equipamentos sem muitos recursos, e aumentando o uso do ambiente.
O desenvolvimento das interfaces também trouxe um ganho significativo,
tanto por possibilitar a gerência das credenciais do ambiente, interagindo com o
diretório LDAP, como viabilizar o acompanhamento, em tempo real, das ações e
comandos feitos pelos usuário nos equipamentos. Esse acompanhamento pode ser
utilizado para auditoria do processo de gestão de ativos de rede, ou até mesmo para
a identificação de tentativas de acesso não autorizado aos equipamentos.
Nas pesquisas realizadas, não foi encontrado nenhum trabalho acadêmico
com uma implementação parecida. Além disso, nem mesmo empresas como a RNP
e os seus principais Pontos de Presença da RNP (PoPs), geralmente, fazem o uso
de soluções semelhantes, deixando todas as credenciais usadas na base local de
cada equipamento.
Pode-se dizer que toda a implantação foi bem sucedida e os objetivos
estipulados, tanto gerais quanto específicos, foram alcançados. Por fim, registra-se
que ainda existem correções a serem feitas, principalmente na interface de
gerenciamento desenvolvida, mas o ambiente tem se mostrado bastante estável,
não tendo registrado nenhum momento de inoperância nesses mais de seis meses
de uso.
5.1 Trabalhos Futuros
Para trabalhos futuros pretende-se estender o uso do ambiente para
servidores e computadores pessoais de uma forma mais completa, já que,
atualmente, é possível apenas o uso de autenticação para estes equipamentos. É
muito importante fazer um estudo das soluções disponíveis ou até mesmo
desenvolver alternativas que possibilitem o uso de autorização e contabilização dos
servidores Linux.
Outra necessidade verificada é a melhoria da interface de gerência para
permitir a configuração de mais opções do sistema sem a necessidade de fazer o
acesso ao terminal do servidor e alterar os arquivos de configurações.
Referências
ABOBA, B; ARKKO, J; HARRINGTON, D. Introduction to Accounting
Management, IETF, RFC 2975. [Online]. Disponível em:
http://www.ietf.org/rfc/rfc2975.txt, Outubro 2000.
Associação Brasileira de Normas Técnicas. Tecnologia da Informação – Técnicas
de segurança – Sistemas de gestão de segurança da informação – Requisitos:
NBR 27001. Rio de Janeiro, 2006.
BELLOVIN, STEVEN M; CHESWICK, WILIAM R; RUBIN, AVIEL D. Firewalls e
Segurança na Internet – Repelindo o Hacker Ardiloso. Segunda Edição. Editora
Bookman, 2005. 400p.
BERNARDO, MAURO C. Avaliação do Uso de Agentes Móveis em Segurança
Computacional. 1999. Dissertação (Mestrado em Ciência da Computação). Instituto
de Ciências Matemáticas e de Computação – ICMC – USP. São Carlos, 1999.
BUTCHER, MATT. Mastering OpenLDAP: Configuration, Securing and
Integrating Directory Services. Primeira Edição. Editora Packt, 2007. 484p.
CARTER, GERALD. LDAP System Administration. Primeira Edição. Editora
O’Reilly, 2003. 294p.
CISCO SYSTEMS, INC. Cisco IOS Security Configuration Guide. Cisco Press,
2006. 586p.
CISCO SYSTEMS, INC. Installation and Upgrade Guide for the Cisco Secure
Access Control System 5.1. junho de 2011. Disponível em:
http://www.cisco.com/en/US/docs/net_mgmt/cisco_secure_access_control_system/5.
1/installation/guide/acs5_1_install_guide.html . Acesso em: 20 de outubro de 2012.
CISCO SYSTEMS, INC. TACACS+ and RADIUS Comparison. Janeiro de 2008.
Disponível em:
http://www.cisco.com/en/US/tech/tk59/technologies_tech_note09186a0080094e99.s
html. Acesso em 03/04/2012.
CISCO SYSTEMS, INC. User Guide for the Cisco Secure Access Control
System 5.1. Outubro de 2012. Disponível em:
http://www.cisco.com/en/US/docs/net_mgmt/cisco_secure_access_control_system/5.
1/user/guide/introd.html . Acesso em: 20 de outubro de 2012.
DENIS, FRANK. UCARP. 2010. Disponível em:
http://www.pureftpd.org/project/ucarp. Acesso em: 15 de outubro de 2012.
FINSETH, C. An Access Control Protocol, Sometimes Called TACACS, IETF,
RFC 1492. [Online]. Disponível em : http://www.rfc-editor.org/rfc/rfc1492.txt, Julho
1993.
HARRIS, SHON. CISSP All-in-One Exam Guide. 4. ed. Editora McGraw-Hill, 2007.
1145p.
HUBBER, MARC. MAVIS. Novembro de 2011. Disponível em: http://www.pro-bono-
publico.de/projects/mavis.html. Acesso em: 26 de junho de 2012.
HUBBER, MARC. TAC_PLUS. Dezembro de 2011. Disponível em: http://www.pro-
bono-publico.de/projects/tac_plus.html. Acesso em: 26 de junho de 2012.
MATOS, ALEXANDRE V. Gerência de Segurança em Aplicações De Bancos de
Dados na Web. 1999. Dissertação (Mestrado em Ciência da Computação) - Pós-
Graduação em Ciência da Computação, Universidade Federal de Santa Catarina,
Florianópolis, 1999.
METZ, Christopher. AAA Protocols: Authentication, Authorization and
Accounting for the Internet. IEEE, p.75-79. Dezembro 1999.
NAKAMURA, EMILIO T; GEUS, PAULO L. Segurança de redes: em ambientes
cooperativos. 2. ed. São Paulo: Futura, 2003.
NAKHJIRI, MADJID; NAKHJIRI, MAHSA. AAA and Network Security for Mobile
Access: Radius, Diameter, EAP, PKI and IP Mobility. Editora Wiley, 2005. 295p.
OLIVEIRA, Rômulo Silva de; CARISSIMI, Alexandre da Silva; TOSCANI, Simão
Sirineo. Sistemas Operacionais. Revista de Informática Teórica e Aplicada –
RITA, v. 8, n. 3, p. 1-33, dez. 2001.
PIERCE, BENJAMIN C. Unison. 2009. Disponível em:
www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html.
Acesso em: 15 de outubro de 2012.
RIGNEY, C; WILLENS, S; RUBENS, A; SIMPSON, W. Remote Authentication Dial
In User Service (RADIUS), IETF, RFC 2865. [Online]. Disponível em:
http://www.ietf.org/rfc/rfc2865.txt, Junho 2000.
SOARES, LUIZ F. Redes de Computadores: das LANs, MANs e WANs às Redes
ATM. Segunda Edição. Editora Campus, 1995.
TODOROV, DOBROMIR. Mechanics of User Identification and Authentication:
Fundamentals of Identity Management. Editora Auerbach, 2007. 760p.
WAHL, M; HOWES, T; KILLE, S. Lightweight Directory Access Protocol (v3),
IETF, RFC 2251. [Online]. Disponível em: http://www.ietf.org/rfc/rfc2251.txt,
Dezembro 1997.
Apêndices
Desenvolvimento de um ambiente de gerenciamento centralizado para autenticação, autorização e contabilização em
um cenário de rede heterogênea Luís F. Cordeiro
Departamento de Informática e Estatística Universidade Federal de Santa Catarina (USFC) – Florianópolis, SC – Brasil
Abstract. This paper has as its theme the study, development and implementation of a centralized authentication system for network equipment using standardized and free technologies as base. Throughout the work, analysis on the main protocols that involve areas of Authentication, Authorization and Accounting (AAA) [METZ 1999] are presented, such as RADIUS [IETF 2865 2000] and TACACS + [METZ 1999]. Besides the theoretical part, two applications were developed, one for support and the other to the management of the environment. Tests were also performed with an application already consolidated in the market, which was very complete but somewhat adaptable to heterogeneous network environments. Resumo. O presente artigo possui como tema o estudo, o desenvolvimento e a implantação de um sistema de autenticação centralizado para equipamentos de rede, utilizando como base tecnologias padronizadas e livres. Ao longo do trabalho, são apresentadas as análises realizadas sobre os principais protocolos que envolvem as áreas de Autenticação, Autorização e Contabilização (AAA) [METZ 1999], como RADIUS [IETF 2865 2000] e TACACS+ [METZ 1999]. Além da parte teórica, foram desenvolvidas duas aplicações, uma para suporte e outra para a gerência do ambiente. Foram realizados ainda testes com uma aplicação já consolidada no mercado, a qual se mostrou muito completa mas pouco adaptável a ambientes de rede heterogêneas.
1. Introdução Com o crescente número de usuários da rede UFSC, os equipamentos de rede estão em constante mudança, seja por melhoria da infraestrutura, seja pelas novas configurações que lhes são aplicadas. Com esse quadro de modernização, esses equipamentos ganharam suporte a novos protocolos, dentre os quais estão alguns que são usados para a gerência de identidades de usuários, como o TACACS+ [METZ 1999] e o RADIUS [IETF 2865 2000]. Assim, é importante a utilização mais adequada das ferramentas baseadas nos nesses protocolos, a fim de aproveitar todas as vantagens oferecidas, bem como permitir uma gerência mais segura dos ativos de rede.
Em um ambiente tão crítico e complexo como o de gerência da rede UFSC, onde um comando errado pode acarretar em problemas de conectividade para usuários e serviços, é preciso ter o maior controle possível do que é feito e por quem é feito.
Para tanto, verifica-se a necessidade do uso de uma aplicação que realize o gerenciamento das identidades dos usuários, para garantir que cada pessoa com acesso ao equipamento faça apenas o que lhe é permitido e não tenha acesso total, como acontece normalmente.
Tendo por base situações como esta, foi proposto um framework estrutural que provê um conjunto de três funções de segurança, o AAA (Authentication, Authorization e Accounting) [METZ 1999]. Baseado nesse framework, é possível definir quem terá acesso (Autenticação), quais as ações que poderão ser feitas depois de sua autenticação (Autorização), o horário que estas ações podem ser feitas, bem como a geração de todos os logs das ações efetuadas para fins de uma possível auditoria (Contabilização). O presente trabalho é fundamentado nesse framework e no problema da ausência de controle no atual ambiente de gerência da rede UFSC, que é apenas usado nos roteadores, a fim de propor uma solução que poderá ser aproveitada para uma variedade maior de equipamentos, desde que tenham suporte ao protocolo TACACS+, possibilitando, assim, que o AAA seja utilizado, quando possível. O restante do artigo está organizado da seguinte forma: a seção 2 se refere as fundamentações teóricas sobre os conceitos básicos de AAA, RADIUS e TACACS+; Na seção 3 serão descritas as principais tecnologias utilizadas durante o estudo e implementação do novo ambiente. A seção 4 confronta o cenário atual com o proposto, justificando a implementação do novo sistema. Apresenta os resultados obtidos com o novo ambiente, bem como as principais configurações necessárias para o seu funcionamento; Por fim, na seção 5, serão apresentadas as considerações finais e sugestões para trabalhos futuros.
2. Conceitos Básicos
2.1. Autenticação, Autorização e Contabilização (AAA) O AAA [METZ 1999], é um framework estrutural para coordenar as áreas de autenticação, autorização e contabilização sob várias tecnologias de redes e plataformas. Alguns dos benefícios de usar o AAA em equipamentos de rede são:
• Aumento da flexibilidade e controle do acesso a configuração;
• Escalabilidade;
• Métodos de autenticação padronizados como RADIUS, TACACS+ e Kerberos.
2.2. Protocolos de autenticação para equipamentos
2.2.1. Radius RADIUS é um sistema distribuído cliente/servidor que previne as redes contra acesso não autorizado [CISCO 2006]. Foi desenvolvido em meados de 1990 pela Levingston Enterprise, com o fim de prover autenticação e auditoria para os equipamentos de rede da organização [METZ 1999]. Segundo o RFC 2865 [IETF 2000], os seus atributos funcionais consistem em:
• Modelo Cliente/Servidor – o equipamento de acesso à rede (NAS) opera como um cliente do RADIUS. O cliente é o responsável por passar as informações do usuário ao servidor RADIUS e depois agir de acordo com a resposta retornada. O servidor RADIUS é o responsável por receber o pedido de conexão do usuário, fazer a
autenticação e retornar todas as configurações necessárias ao cliente, para que este consiga fornecer o serviço ao usuário;
• Segurança de Rede – Transações entre o servidor RADIUS e o NAS são autenticadas por uma chave compartilhada, que nunca é enviada pela rede. As senhas dos usuários são enviadas cifradas entre o cliente e o servidor para evitar o roubo em redes inseguras;
• Mecanismo de Autenticação Flexível – Um servidor RADIUS pode suportar vários mecanismos de autenticação como PAP e CHAP;
• Protocolo Extensível – Novos valores de atributos podem ser adicionados sem prejudicar as implementações existentes do protocolo.
3.2.2 Tacacs + Outro protocolo que provê os serviços de AAA é o Terminal Access Controller Access Control Protocol (TACACS). Originalmente descrito na RFC 1492 [IETF 1993], foi reestruturado ao longo dos anos pela CISCO e é suportado por vários servidores, roteadores e outros dispositivos encontrados nas redes empresarias de hoje. A versão atual é chamada de TACACS+, que reflete as melhorias feitas no protocolo original [METZ 1999]. De acordo com HARRIS (2007) o TACACS tem três gerações: TACACS; XTACACS; TACACS+. Na verdade, o TACACS+ não é uma nova geração, é um novo protocolo que provê funcionalidades similares. Por ser um protocolo totalmente diferente, não é compatível com o TACACS ou XTACACS. Para CISCO ... (2006), TACACS+ é uma aplicação de segurança que provê a validação centralizada dos usuários que estão tentando acessar equipamentos de rede ou servidores de acesso à rede. O Protocolo possibilita a instalação separada e modular dos serviços de autenticação, autorização e contabilização. Outro ponto muito importante, é que toda a troca de informações entre o equipamento de acesso e o daemon é cifrado.
2.3. Tecnologias
2.3.1. openLDAP O Lightweight Directory Access Protocol (LDAP) de uma forma simplificada, é um protocolo para pesquisar e atualizar diretórios. Segundo a RFC 2251 [IETF 1997], que define a versão três do protocolo, o LDAP segue o modelo de serviços de diretório X.500, que é uma árvore de nós, cada um consistindo de um conjunto de atributos com seus respectivos valores. O modelo X.500 era muito complexo para ser suportado em desktops e através da Internet, então o LDAP foi criado para prover este serviço. Para CARTER (2003), serviços de diretórios podem assumir muitas formas, mas cinco características, pelo menos, são verdadeiras:
• Otimizadas para leitura;
• Implementam modelos distribuídos de armazenamento de informações;
• Pode estender os tipos de informação que armazena;
• Recursos avançados de pesquisa;
• Replicação consistente entre servidores de diretórios.
O serviço de diretório X.500 ganhou o título de “pesado”. Nele, toda a comunicação entre cliente e servidor é feita usando o a pilha do protocolo Open System Interface (OSI), e como trabalha na camada de aplicação, o cabeçalho de rede fica muito pesado. Já o LDAP é considerado leve, como o próprio nome sugere, em comparação com o X.500 pois utiliza mensagens com baixa sobrecarga, mapeadas diretamente na camada TCP da pilha do protocolo TCP/IP.
2.3.2. TAC_PLUS De acordo com HUBBER (2011), principal desenvolvedor do projeto, o tac_plus é um daemon dirigido a eventos do TACACS+, ou seja, seu funcionamento esta extremamente relacionado ao envio e recebimento de eventos. Provê os serviços de autenticação, autorização e contabilização para roteadores Cisco e outros equipamentos de rede, desde que suportem o protocolo. É uma reformulação do código-fonte original do TACACS da Cisco. Alguns dos principais recursos incluem:
• Flexibilidade de backends externos para perfis de usuários (LDAP, Active Directory e RADIUS);
• Multiplexação das conexões – múltiplos clientes por processo;
• Escalabilidade – sem limite de usuários, servidores ou clientes;
• Suporte aos protocolos IPv4 e IPv6;
• Compilado com a especificação mais recente do protocolo TACACS+; Para poder oferecer a já falada flexibilidade de backend, o tac_plus usa um outro módulo chamado MAVIS e que será explicado a seguir.
2.3.3. MAVIS O Modular Attribute-Value Interchange System (MAVIS) é uma biblioteca que provê um protocolo extensível e modular para as tarefas de autenticação e autorização. Também funciona como um subsistema de autenticação modular, usado pelo daemon tac_plus. Esta biblioteca contem vários módulos para o uso de diversos backends e um deles é para serviço de diretório, seja o openLDAP ou o Active Directory da Microsoft. Para poder usar todas suas vantagens é só adicionar um novo arquivo de schema no servidor LDAP e em cada objeto que poderá fazer uso das funcionalidades do tac_plus, adicionar o objectClass “tacacsAccount“ e seus respectivos atributos.
4. Estudo de Caso
4.1. Projeto
4.1.1. Cenário Atual O ambiente de autenticação atual é simples e tem problemas de segurança. Da forma como é usado, a autenticação é bastante limitada e o uso de contabilização e autorização é implementada apenas nos equipamentos de core (núcleo) da rede. A Figura 1 mostra como é o fluxo da informação em um processo de autenticação. Nos roteadores existe um agente externo, que é o servidor Cisco, participando da autenticação e também da autorização, como indica o número 2.
Figura 27 - Processo de autenticação atual
Já para os demais equipamentos, indicados pelo número 1, não existe nenhum sistema atuante no processo de autenticação, sendo que os usuários são autenticados na base de dados local destes equipamentos. Pelo fato da autenticação ser feita dessa forma, vários problemas são gerados, dentre eles:
• Se não for criada uma credencial para cada usuário, todas as pessoas que terão acesso precisam saber a senha do usuário administrador;
• Se cada pessoa tiver sua credencial, é necessário o acesso em todos os equipamentos e criar na base local a conta para o usuário;
• Caso seja necessário trocar alguma senha, seja de administrador ou de um usuário, é preciso acessar cada equipamento e fazer a mudança;
• Caso seja preciso retirar o acesso de um usuário de um equipamento, ou de todos, é necessário remover as credenciais de cada equipamento onde existir o registro;
• No caso de equipamentos que suportam o serviço de autorização e não existir a política de cada usuário ter uma credencial, todo mundo terá o mesmo nível de privilégio, desde pessoas com mais experiência aos mais inexperientes;
• Nos equipamentos que suportam o serviço de contabilização, principalmente os de core (núcleo), se todos usarem as credenciais de administrador, não é possível saber quem executou determinado comando no equipamento, pois todos usuários fazem o login com a mesma conta.
• Faltou falar da trilha de auditoria tanto no que se refere para toda a estrutura AAA Assim, o principal problema do cenário atual é a gerência das identidades dos usuários, já que para fazer qualquer alteração, tanto para mudança de senha, quanto para permitir um novo usuário, será obrigatório o acesso em cada equipamento para fazer essas
alterações. Por outro lado este ambiente tem um ponto muito importante que é o funcionamento independente de outros sistemas, reduzindo assim os pontos de falha.
4.1.2. Cenário Proposto Tentando resolver todos as deficiências expostas, foi elaborado um ambiente com características que possibilite, além de todas as principais funcionalidades do AAA, uma alta disponibilidade e confiabilidade, como mostra o desenho esquemático da Figura 2.
Figura 28 - Arquitetura do ambiente proposto
Na infraestrutura proposta, existem dois servidores virtualizados, um funcionando como master e outro como slave. Os softwares adotados utilizam daemons, que, conforme OLIVEIRA, CARISSIMI e TOSCANI (2001), são processos do sistema, e realizam as tarefas do próprio sistema, e não do usuário. Em cada servidor foram instalados os daemons:
• LDAP e TACACS+ - utilizados para fazer a gerência das identidades, todas as regras e permissões para as autorizações e interação com os equipamentos de rede;
• MySQL – utilizado para armazenamento todos os logs gerados na utilização do sistema, tanto na parte de contabilização quanto das interfaces administrativas;
• Apache – servidor web para hospedar a aplicação de administração e monitoramento do ambiente.
Os servidores são independentes entre si, ou seja, se um comutador de rede for configurado para utilizar o servidor master, e outro equipamento for configurado para o slave, ambos devem ter os mesmos resultados. Isso é possível pois todos os arquivos de configurações, bases de dados do MySQL e os diretórios LDAP são replicados bidirecionalmente entre as máquinas. Para isso, no MySQL e no LDAP foram configurados os serviços de replicação dos próprios daemons. Uma outra mudança significativa em relação ao ambiente anterior é no que diz respeito ao fluxo dos dados no ambiente, após o usuário informar suas credenciais. Diferente do que era, onde para a grande maioria dos equipamentos não havia nenhum sistema de
suporte as funcionalidades de AAA, agora todas as requisições são recebidas por um servidor, que faz todo o processamento e retorna as informações necessárias. Esse processo pode ser melhor visualizado na Figura 3.
Figura 29 - Fluxo dos dados no ambiente proposto
Nesse caso os equipamentos acabam funcionando como suplicantes, repassando as credenciais ou informações do usuário para o autenticador (servidor AAA). Esse comportamento é que possibilita ao servidor AAA analisar as informações, e de acordo com as configurações do daemon autenticar, autorizar e gerar logs de tudo que é feito nesse processo de interação do usuário com o equipamento.
4.2. Desenvolvimento Apresentados o funcionamento do ambiente, bem como o propósito que se pretende alcançar com o presente trabalho, neste momento, passa-se a discorrer sobre duas ferramentas que possuem mecanismos capazes de solucionar as necessidades verificadas anteriormente. Foram analisadas duas ferramentas para desenvolver o projeto proposto:
• Cisco Secure Access Control Server 5.1 (ACS) [CISCO 2012];
• TAC_PLUS [HUBBER 2011]. Como a ferramenta desenvolvida pela Cisco possui algumas limitações, que serão explicadas no texto, foi escolhida a solução utilizando o TAC_PLUS MAVIS para uso no projeto.
4.2.1. Cisco ACS Segundo CISCO...(2012), o Secure Access Control Server (ACS) é um servidor de segurança baseado em políticas que fornece os padrões de autenticação, autorização e contabilização (AAA) para uma rede. Facilita o gerenciamento administrativo de aplicações e dispositivos, sejam eles Cisco ou não. Também serve de ponto de integração entre o controle de acesso à rede e o gerenciamento de identidade. O ACS é o responsável por identificar usuário e dispositivos que tentam acessar a rede. Essa identificação pode ocorrer diretamente no repositório interno de identidades para
fazer autenticação local, mas também existe a possibilidade do uso de repositórios externos como:
• LDAP
• Active Directory
• RSA SecurID Token Server
• RADIUS Identity Server Outro detalhe importante são os recursos necessário para a instalação da aplicação. De acordo com CISCO...(2011), existem duas formas para a instalação do ACS, usando uma máquina virtual no hipervisor VMWare ou em um hardware específico da Cisco. Caso seja instalado o ACS no formato de uma máquina virtual, o sistema operacional é um Linux Red Hat 5 e é exigido pelo menos 500 GB de espaço de disco para funcionar nas configurações mínimas de avaliação do sistema. Estas características do ACS acabam se transformando em problemas pois necessitam de muitos recursos, tanto de hardware como financeiros para a compra de software. Para a instalação do ambiente proposto, com todos os componentes já citados, seria necessária a aquisição de duas licenças do ACS 5.1 e pelo menos 2 TB de capacidade de armazenamento, que é o recomendado pela Cisco para o uso em ambiente de produção. Outra limitação que acabou deixando muito a desejar diz respeito ao suporte à equipamentos de outras empresas, já que o ACS não suporta, quando instalado sem nenhum modificação, o uso de autorização em equipamentos que não são da Cisco. Comparando com a realidade da rede UFSC, onde existe uma heterogeneidade nos equipamentos, este é o principal ponto negativo, pois desta forma a solução só funcionaria de maneira satisfatória nos equipamentos de core da rede, da mesma forma que é feito atualmente. Para os demais equipamentos, o ACS funcionaria apenas para suporte à autenticação.
4.2.2. TAC_PLUS Considerando que já foi exposto o conceito do daemon TAC_PLUS na seção 3.2, foram feitos dois testes distintos:
• Compilação padrão
• Compilação TAC_PLUS MAVIS Da forma padrão o TAC_PLUS é limitado. Uma das principais limitações é que todos os usuários, dispositivos e demais diretivas precisam estar cadastrados no arquivo de configurações do daemon. Isso é um grande problema já que para adicionar cada novo usuário ao sistema é necessário que um administrador edite o arquivo de configurações e depois reinicie o daemon. Se por acaso alguém estiver executando algum comando no equipamento exatamente na hora em que o daemon é reiniciado, o comando será negado, por exemplo. Caso o usuário não esteja cadastrado no arquivo de configurações, é possível fazer login utilizando o PAM (Pluggable Authentication Modules) do servidor linux. Desta maneira também é necessário ter um registro no arquivo de configurações mostrando que, para aquele usuário específico, as informações serão fornecidas pelo sistema operacional. Utilizando a compilação padrão, o PAM é uma peça fundamental ao sistema pois é através dele que o TAC_PLUS tem a possibilidade do uso de recursos externos para a autenticação, como por exemplo o LDAP. O funcionamento é bem simples:
1. Quando o usuário está configurado para autenticar via PAM, o daemon busca as credenciais do usuário da base local do sistema operacional.
2. É instalada uma biblioteca ao PAM que permite que ele verifique as credenciais de um usuário em um diretório LDAP.
3. Essa biblioteca é configurada para que sempre a primeira opção de busca seja feita na base local, e caso não seja encontrado o usuário, a busca é feita no diretório LDAP.
Essa obrigatoriedade do uso do PAM deixa todo o sistema um tanto quanto inflexível, pois centraliza tudo no arquivo de configurações, ao invés de ter uma forma simples de possibilitar a gerência de todo o daemon. Outra limitação é não possibilitar que um usuário tenha várias políticas de acesso. Dessa forma o usuário terá o mesmo nível de privilégio para todos os equipamentos que ele tiver acesso. Usando o TAC_PLUS MAVIS (explicado na seção 3.3) algumas dessas limitações são atendidas. Primeiramente, o daemon tem suporte nativo a agentes externos como:
• Active Directory;
• LDAP;
• RADIUS. Caso a autenticação esteja configurada para acontecer via Active Directory ou LDAP, a solução torna-se ainda mais completa, pois permite que sejam definidos atributos específicos nos registros do diretório e não somente no arquivo de configurações. São adicionados três novos atributos - tacacsClient, tacacsMember e tacacsProfile – que são responsáveis por possibilitar a flexibilidade necessária com o seu uso. tacacsClient Define o endereço IP ou segmento de rede de onde o daemon pode aceitar a conexão do usuário. Funciona de forma semelhante a um firewall, analisando a origem da requisição e permitindo, ou não, o acesso ao equipamento. tacacsMember Atributo responsável pela definição das políticas de acesso. tacacsProfile Usado para definir mais algumas variáveis ao registro. Utilizando este atributo é possível definir tempo de validade do registro, caso seja necessário liberar o acesso por um tempo determinado, fazer restrições de acesso por horário e também fazer o uso de ACLs para restringir ou permitir o acesso a outros equipamentos.
4.3. Implantação
4.3.1. Estrutura Física No desenvolvimento deste ambiente, foi trabalhado com dois tipos de infraestrutura:
• Servidores;
• Comutadores de rede. Para a infraestrutura de servidores foram criadas duas máquinas virtuais, hospedadas em um ambiente com o hipervisor VMWare. Cada uma possui dois processadores virtuais
Intel® Xeon® de 3.33GHz, capacidade de armazenamento de 24 GB e 2GB de memória. Além destas características de hardware, cada servidor tem associado a ele cinco interfaces de rede, para possibilitar o uso dos recursos descritos na seção 4.2, quando é descrito a forma de acesso aos servidores. No caso da infraestrutura dos equipamentos de rede, a rede UFSC dispõe principalmente dos seguintes modelos de equipamentos:
• Cisco Router 7606
• 3Com SuperStack® 4 5500G
• D-Link DGS 3100-24/48 PoE
• Cisco Wireless LAN Controller 5500 Além destes equipamentos citados, alguns outros modelos também estão operando com pelo menos a autenticação pelo ambiente. Estes equipamentos são:
• Cisco Catalyst 3560
• Cisco Catalyst 2960G
• D-Link DES 3526
• D-Link DES 3028P
• Edge-Core ES3526XA
4.3.2. Implantação em números A SeTIC controla por volta de 850 equipamentos de rede, dos quais, cerca de 630 são gerenciáveis, ou seja, possibilita aplicar configurações. Destes, aproximadamente 400 já estão, ou têm suporte, pelo menos para o uso de autenticação pelo sistema proposto. Esse número é baseado apenas em equipamentos Cisco, 3Com e D-Link, sem contar os equipamentos de outras fabricantes como SMC, Dell, Enterasys e HP, onde ainda não foram feitos os testes de suporte. De todos esses comutadores suportados pelo sistema, dois são usados como roteadores principais, quatro são controladores da rede sem fio, cinco são switchs de distribuição de centro e o restante é considerado de borda ou distribuição local.
4.3.3. Gerência do ambiente Foram desenvolvidas duas aplicações para a gerência do ambiente:
• Logs - para acompanhamento em tempo real dos comandos executados nos equipamentos;
• Gerência – para gerenciar as identidades e permissões de acesso ao sistema. Para o desenvolvimento da aplicação de logs foram usadas as linguagens de programação perl, para analisar e inserir os logs gerados pelo TAC_PLUS MAVIS em uma base MySQL, e o PHP para a criação da interface onde os administradores possam acompanhar/auditar as ações feitas no sistema. Imagens da interface de logs podem ser vistas nas Figuras 4, 5 e 6.
Figura 30 - Interface de Logs - logs de comandos
A Figura 4 mostra os logs apenas de comandos executados no sistema. Informações importantes podem ser visualizadas como a hora que o comando foi executado, o endereço IP do equipamento onde o comando foi executado, o usuário que executou o comando, o endereço IP do usuário e o comando executado, indicando se foi permitido (permit) ou negado (deny).
Figura 31 – Interface de Logs - logs de acessos
Na Figura 5 mostra o acompanhamento de logs de acesso aos equipamentos. A interface é parecida com a de acompanhamento de comandos, sendo diferente na ultima coluna da tabela, onde é indicado o status do processo de autenticação.
Figura 32 - Interface de Logs - logs de acessos 2
Já na Figura 6 é mostrada a mesma interface da Figura 5, só que foi aplicado um filtro para mostrar apenas registros onde o status é “Usuário não encontrado”. Percebe-se que na maior parte dos casos, o acesso é feito por usuário externos à rede UFSC, indicados pelo endereço IP não pertencentes a faixa utilizada pela universidade. Este indicador, associado com a tentativa de login utilizando o nome de usuário como admin e root é um comportamento que pode sugerir algum ataque de invasão por força bruta ao equipamento, por exemplo. Além de acompanhar os logs é possível aplicar filtros para refinar os resultados das buscas e a atualização dos dados é feita em tempo real. No caso da interface de gerência das identidades foi usado principalmente PHP como linguagem de programação, interagindo com o diretório LDAP, onde ficam armazenadas as credenciais dos usuários. As Figuras 7, 8 e 9 mostram alguns dos módulos do sistema.
Figura 33 - Interface de gerência - visão inicial
A Figura 7 mostra a visão geral do sistema, após o usuário fazer o login na interface WEB. É possível saber se todos os processos essenciais ao ambiente estão sendo executados, como também um monitoramento das partições do servidor. É importante salientar que para todos esses casos, tanto dos processos, quanto das partições, caso aconteça algum incidente, é enviado um e-mail automaticamente aos administradores do sistema para informar do ocorrido.
Figura 34 - Interface de gerência - acompanhamento de comandos
Outro recurso é o histórico de comandos, mostrado na Figura 8. Nele é possível que os usuários possam ter um histórico dos comandos que eles próprios executaram nos equipamentos. Na interface de logs apresentada anteriormente, apenas os administradores têm acesso, pois envolve ações de todos os usuário. Já nesse caso, cada usuário pode apenas acompanhar suas ações.
Figura 35 - Interface de gerência - adicionar usuário
A Figura 9 mostra o módulo de gerência das credenciais dos usuários. É possível definir todos os atributos requeridos pelo LDAP para o correto funcionamento com o TAC_PLUS MAVIS. Quando a opção Tacacs+ está selecionada nas “Opções da Conta” é exibido três novos atributos: Rede de Acesso, Perfil e Membro. Cada um desses atributos corresponde àqueles atributos do TAC_PLUS MAVIS mostrados na seção 4.2.2. Apresentados as duas aplicações desenvolvidas, será mostrado uma imagem esquemática da funcionamento geral do ambiente (Figura 10).
Figura 36 - Funcionamento geral do ambiente
Os administradores têm acesso tanto as duas aplicações, gerência do ambiente e visualizaçãoo de logs. Essas duas aplicações ficam hospedadas no próprio servidor, sendo que a de gerência do ambiente interage com o LDAP e a de logs com o MySQL. O usuário pode utilizar o sistema de gerência para alterar suas informações pessoais, como senha, e-mail e telefone, como também visualizar seu histórico de comandos. Tanto os administradores quanto os usuário podem ter acesso aos equipamentos de rede, desde que possuam permissão para tal. Já os equipamentos de rede interagem com o daemon TAC_PLUS MAVIS para autenticar e autorizar os acessos dos usuários.
4.3.4. Adequação com normas de segurança Órgãos públicos estão sendo cada vez mais cobrados sobre questões de melhores práticas de gestão dos recursos de TI e com a UFSC isso não é diferente. A Controladoria Geral da União (CGU) em suas auditorias exige a adequação da universidade a frameworks de gestão da segurança em TI como a ISO27001 [ABNT 2006]. Em função disso, é necessário um conjunto de ações para adequar e melhorar os sistemas utilizados. De acordo com ABNT (2006) a ISO 27001 é dividida em 11 domínios diferentes, sendo que cada domínio tem objetivos de controle e estes, por sua vez, possuem controles. No desenvolvimento do presente trabalho conseguiu-se uma adequação com os seguintes objetivos de controle e controles:
• A.10 Gerenciamento das Operações e comunicações o A.10.10 Monitoramento
§ A.10.10.1 Registros de auditoria § A.10.10.2 Monitoramento do uso do sistema § A.10.10.3 Proteção das informações dos registros(logs) § A10.10.4 Registros (log) de administrador e operador § A10.10.5 Registros (log) de falhas
• A.11 Controle de acessos o A.11.1 Requisitos de negócio para controle de acesso
§ A.11.1.1 Políticas de controle de acesso o A.11.2 Gerenciamento de acesso do usuário
§ A.11.2.1 Registro de usuário § A.11.2.2 Gerenciamento de privilégios § A.11.2.3 Gerenciamento de senha do usuário
o A.11.5 Controle de acesso ao sistema operacional § A.11.5.2 Identificação e autenticação do usuário § A.11.5.3 Sistema de gerenciamento de senha § A.11.5.5 Limite de tempo de sessão § A.11.5.6 Limite de horário de conexão
Não é garantido que todos os controles citados são realmente utilizados, mas as aplicações desenvolvidas dão e têm suporte total a todos eles.
5. Considerações Finais O presente trabalho de conclusão de curso teve como propósito demonstrar todo o processo de desenvolvimento e implantação de um ambiente de autenticação, autorização e contabilização para equipamentos de rede em um cenário heterogêneo. Para tanto, buscou-se estudar os principais conceitos relacionados ao assunto, bem como as tecnologias mais utilizadas e de fácil acesso para a realização do desenvolvimento. Foram realizados dois ambientes de teste. No primeiro foi utilizado o software proprietário da Cisco (ACS 5.1) que por mais robusto que seja, não supriu as necessidades, principalmente por ser muito voltado a equipamentos e serviços da própria CISCO. Já no outro teste, empregou-se apenas tecnologias livres como os daemons TAC_PLUS MAVIS e openLDAP, que implementam os protocolos TACACS+ e LDAP, respectivamente, os quais juntos possibilitaram a flexibilidade de uso exigida para um ambiente com as características do encontrado na rede UFSC. Depois da implantação de forma definitiva do ambiente, foi atingida a marca de cerca de 70% dos equipamentos configurados para autenticar utilizando o ambiente proposto, o que é um número bastante significativo até o momento, à medida que ainda não foram realizados testes com todas as marcas e modelos de equipamentos encontradas na rede. Registra-se, ainda, que o uso do ambiente pode influenciar também nos processos de licitação para compra de novos equipamentos, que pode passar a exigir que tenham suporte completo ao protocolo TACACS+, filtrando equipamentos sem muitos recursos, e aumentando o uso do ambiente.
O desenvolvimento das interfaces também trouxe um ganho significativo, tanto por possibilitar a gerência das credenciais do ambiente, interagindo com o diretório LDAP, como viabilizar o acompanhamento, em tempo real, das ações e comandos feitos pelos usuário nos equipamentos. Esse acompanhamento pode ser utilizado para auditoria do processo de gestão de ativos de rede, ou até mesmo para a identificação de tentativas de acesso não autorizado aos equipamentos. Nas pesquisas realizadas, não foi encontrado nenhum trabalho acadêmico com uma implementação parecida. Além disso, nem mesmo empresas como a RNP e os seus principais Pontos de Presença da RNP (PoPs), geralmente, fazem o uso de soluções semelhantes, deixando todas as credenciais usadas na base local de cada equipamento. Pode-se dizer que toda a implantação foi bem sucedida e os objetivos estipulados, tanto gerais quanto específicos, foram alcançados. Por fim, registra-se que ainda existem correções a serem feitas, principalmente na interface de gerenciamento desenvolvida, mas o ambiente tem se mostrado bastante estável, não tendo registrado nenhum momento de inoperância nesses mais de seis meses de uso.
5.1. Trabalhos Futuros Para trabalhos futuros pretende-se estender o uso do ambiente para servidores e computadores pessoais de uma forma mais completa, já que, atualmente, é possível apenas o uso de autenticação para estes equipamentos. É muito importante fazer um estudo das soluções disponíveis ou até mesmo desenvolver alternativas que possibilitem o uso de autorização e contabilização dos servidores Linux. Outra necessidade verificada é a melhoria da interface de gerência para permitir a configuração de mais opções do sistema sem a necessidade de fazer o acesso ao terminal do servidor e alterar os arquivos de configurações.
Referência Bibliográficas Associação Brasileira de Normas Técnicas. Tecnologia da Informação – Técnicas de
segurança – Sistemas de gestão de segurança da informação – Requisitos: NBR 27001. Rio de Janeiro, 2006.
CARTER, GERALD. LDAP System Administration. Primeira Edição. Editora O’Reilly, 2003. 294p.
METZ, Christopher. AAA Protocols: Authentication, Authorization and Accounting for the
Internet. IEEE, p.75-79. Dezembro 1999. RIGNEY, C; WILLENS, S; RUBENS, A; SIMPSON, W. Remote Authentication Dial In
User Service (RADIUS), IETF, RFC 2865. [Online]. Disponível em: http://www.ietf.org/rfc/rfc2865.txt, Junho 2000.
CISCO SYSTEMS, INC. Cisco IOS Security Configuration Guide. Cisco Press, 2006. 586p. CISCO SYSTEMS, INC. Installation and Upgrade Guide for the Cisco Secure Access Control
System 5.1. junho de 2011. Disponível em: http://www.cisco.com/en/US/docs/net_mgmt/cisco_secure_access_control_system/5.1/installation/guide/acs5_1_install_guide.html . Acesso em: 20 de outubro de 2012.
CISCO SYSTEMS, INC. User Guide for the Cisco Secure Access Control System 5.1. Outubro de 2012. Disponível em: http://www.cisco.com/en/US/docs/net_mgmt/cisco_secure_access_control_system/5.1/user/guide/introd.html . Acesso em: 20 de outubro de 2012.
FINSETH, C. An Access Control Protocol, Sometimes Called TACACS, IETF, RFC 1492. [Online]. Disponível em : http://www.rfc-editor.org/rfc/rfc1492.txt, Julho 1993.
HUBBER, MARC. MAVIS. Novembro de 2011. Disponível em: http://www.pro-bono-publico.de/projects/mavis.html. Acesso em: 26 de junho de 2012.
HUBBER, MARC. TAC_PLUS. Dezembro de 2011. Disponível em: http://www.pro-bono-publico.de/projects/tac_plus.html. Acesso em: 26 de junho de 2012.
HARRIS, SHON. CISSP All-in-One Exam Guide. 4. ed. Editora McGraw-Hill, 2007. 1145p. OLIVEIRA, Rômulo Silva de; CARISSIMI, Alexandre da Silva; TOSCANI, Simão Sirineo.
Sistemas Operacionais. Revista de Informática Teórica e Aplicada – RITA, v. 8, n. 3, p. 1-33, dez. 2001.
WAHL, M; HOWES, T; KILLE, S. Lightweight Directory Access Protocol (v3), IETF, RFC 2251. [Online]. Disponível em: http://www.ietf.org/rfc/rfc2251.txt, Dezembro 1997.
Código fonte da aplicação desenvolvida
Aplicação de Gerência das Credenciais
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_INCLUDES . 'LDAP.php'; require_once PATH_INCLUDES . 'config.php'; /* * To change this template, choose Tools | Templates * and open the template in the editor. */ /** * Description of LDAPController * * @author luis */ class LDAPController { protected $ldap; protected static $instance; public static function getInstance() { if (!self::$instance) { self::$instance = new LDAPController(); } return self::$instance; } public function __construct() { $this->ldap = LDAP::getInstance(); } /* * getValidUsers : função que retorna todos os usuários válidos da base LDAP. Verifica no arquivo de configuração se * existe algum usuário que não deve ser mostrado e retorna o array com os usuários válidos * * @return array usuários válidos */ public function getValidUsers($filter = null) { try { $result = $this->ldap->getAllUsers($filter); global $Config; $users = array();
for ($i = 0; $i < $result["count"]; $i++) { if (isset($Config['user_filter']) && !empty($Config['user_filter'])) { if (!in_array($result[$i]["uid"][0], $Config['user_filter'])) { $users[] = array( 'uid' => $result[$i]["uid"][0], 'nome' => $result[$i]['givenname'][0] ); } } else { $users[] = array( 'uid' => $result[$i]["uid"][0], 'nome' => $result[$i]['givenname'][0] ); } } $this->ldap->unbind(); return $users; } catch (Exception $e) { //echo $e->getMessage(); return false; } } /* * getValidGroups : retorna todos os grupos válidos, verificando se existe alguma restrição no arquivo de configuração * fazendo o filtro quando necessário * * @return array grupos válidos */ public function getValidGroups() { global $Config; try { $result = $this->ldap->getAllGroups(); $groups = array(); for ($i = 0; $i < $result["count"]; $i++) { if (isset($Config['group_filter']) && !empty($Config['group_filter'])) { if (!in_array($result[$i]["cn"][0], $Config['group_filter'])) { $groups[] = array( 'gid' => $result[$i]["gidnumber"][0], 'cn' => $result[$i]['cn'][0] ); } } else { $groups[] = array( 'gid' => $result[$i]["gidnumber"][0],
'cn' => $result[$i]['cn'][0] ); } } $this->ldap->unbind(); return $groups; } catch (Exception $e) { //echo $e->getMessage(); return false; } } /* * createSHA : função para cria a senha do usuário de acordo com o padrão usado pelo LDAP * * @param string $senha string que será criptografada * @return string senha criptografada em SHA1 */ public function createSHA($senha) { return '{SHA}' . base64_encode(sha1($senha, true)); } /* * autentica : função que verifica os dados fornecidos pelo usuário com os da base LDAP, liberando acesso caso os * dados são iguais * * @param string $usuario usuário que esta tentando se autenticar * @param string $senha senha não criptografada do usuário * * @return caso as informações fornecidas são compatíveis com as da base retorna o usuário LDAP, caso contrário FALSE */ public function autentica($usuario, $senha) { $temp = $this->ldap->ldapGetUser($usuario); $senha = $this->createSHA($senha); if ($temp['count'] == 1) { if ($senha == $temp[0]["userpassword"][0]) { $permissao = $this->ldap->isGroupMember("(&(cn=web-admin)(memberuid=$usuario))"); if ($permissao['count'] != 0) { $temp['admin'] = true; } return $temp; } else { return null; }
} else { return null; } } /* * modificarDN : função para modificar os atributos de alguma entrada da base LDAP, pode ser grupo ou usuário * * @param string $dn deve ser a DN da entrada ldap. EXEMPLO: 'uid=teste,dc=dominio,dc=br' * @param array $novo array com os atributos a serem alterados * * @return boolean */ public function modificarDN($dn, $novo) { try { if ($this->ldap->modifyDN($dn, $novo)) { return true; } else { return false; } } catch (Exception $e) { //echo $e->getMessage(); return false; } } /* * modificarDN : função para deletar os atributos de alguma entrada da base LDAP, pode ser grupo ou usuário * * @param string $dn deve ser a DN da entrada ldap. EXEMPLO: 'uid=teste,dc=dominio,dc=br' * @param array $var array com os atributos a serem deletados * * @return boolean */ public function deleteAttrDN($dn, $var) { try { if ($this->ldap->deleteAttr($dn, $var)) { return true; } else { return false; } } catch (Exception $e) { //echo $e->getMessage(); return false; } }
/* * addAttrDN : função para adicionar os atributos de alguma entrada da base LDAP, pode ser grupo ou usuário * * @param string $dn deve ser a DN da entrada ldap. EXEMPLO: 'uid=teste,dc=dominio,dc=br' * @param array $var array com os atributos a serem adicionados * * @return boolean */ public function addAttrDN($dn, $var) { try { if ($this->ldap->addAttr($dn, $var)) { return true; } else { return false; } } catch (Exception $e) { //echo $e->getMessage(); return false; } } /* * deleteDN : Função para deletar uma entrada da base LDAP * * @param string $dn deve ser a DN da entrada ldap. EXEMPLO: 'uid=teste,dc=dominio,dc=br' * @param string $flag idica qual o tipo de entrada que será deletada: usuário ou grupo * * @return boolean */ public function deleteDN($dn, $flag) { try { if ($flag == 'usuario') { $temp = $this->ldap->ldapGetUser($dn); $usuario = $temp[0]['uid'][0]; $grupos = $this->verificaGruposUsuario($usuario); if ($grupos) { for ($i = 0; $i < sizeof($grupos); $i++) { $this->atualizaUsuariosGrupo('del', $grupos[$i], $usuario); } } } elseif ($flag == 'grupo') { $temp = $this->ldap->ldapGetGroup($dn);
} if ($this->ldap->deleteDN($temp[0]['dn'])) { return true; } return false; } catch (Exception $e) { //echo $e->getMessage(); return false; } } /* * getDN : Função que retorna uma entrada da base LDAP * * @param string $filter UID do usuário ou CN do grupo * @param string $flag idica qual o tipo de entrada que será retornada: usuário ou grupo * * @return entrada LDAP */ public function getDN($filter, $flag) { try { if ($flag == 'usuario') { return $this->ldap->ldapGetUser($filter); } else { return $this->ldap->ldapGetGroup($filter); } } catch (Exception $e) { //echo $e->getMessage(); return false; } } /* * addDN : Função para adicionar uma entrada na base LDAP * * @param string $var array com os atributos do usuário * @param string $flag idica qual o tipo de entrada que será adicionada: usuário ou grupo * * @return boolean */ public function addDN($var, $flag) { try { if ($flag == 'usuario') { $dn = 'uid=' . $var['uid'] . ',' . $this->ldap->getUserDN(); } elseif ($flag == 'grupo') { $dn = 'cn=' . $var['cn'] . ',' . $this->ldap->getGroupDN(); }
return $this->ldap->addDN($dn, $var); } catch (Exception $e) { //echo $e->getMessage(); return false; } } /* * atualizaGrupo: Função para adicionar ou deletar do grupo um usuário no atributo memberUid * * @param string $action valor que indica se é para adicionar ao grupo ou deletar * @param string $filter pode ser o gidNumber ou o CN do grupo * @param string $uid nome do usuário a ser adicionado no grupo * * @return boolean */ public function atualizaUsuariosGrupo($action, $filter, $uid) { try { $grupo = $this->ldap->ldapGetGroup($filter); $var['memberUid'] = $grupo[0]['memberuid']; array_shift($var['memberUid']); if ($action == 'add') { if (!in_array($uid, $var['memberUid'])) { $var['memberUid'][] = $uid; } } elseif ($action == 'del') { $key = array_search($uid, $var['memberUid']); if ($key !== false) { unset($var['memberUid'][$key]); } } if ($this->ldap->modifyDN($grupo[0]['dn'], $var)) { return true; } return false; } catch (Exception $e) { //echo $e->getMessage(); return false; } } /* * verificaGruposUsuario : verifica dos grupos de um usuário dado o nome de usuário * * @param string $uid Usuário que será feita a busca
* @return array array com os nomes dos grupos do usuário */ public function verificaGruposUsuario($uid) { try { $grupos = $this->ldap->isGroupMember("(&(objectClass=posixGroup)(memberUid=$uid))"); if ($grupos['count'] != 0) { for ($i = 0; $i < $grupos['count']; $i++) { $member[] = $grupos[$i]['cn'][0]; } return $member; } else { return false; } } catch (Exception $e) { //echo $e->getMessage(); return false; } } /* * isMember : verifica dos grupos de um usuário dado o nome de usuário * * @param string $grupo nome do grupo que pretende verificar se é membro * @param string $uid Usuário que será feita a busca * @return boolean */ public function isMember($grupo, $uid) { try { $grupos = $this->ldap->isGroupMember("(&(|(cn=$grupo)(gidNumber=$grupo))(memberUid=$uid))"); if ($grupos['count'] != 0) { return true; } else { return false; } } catch (Exception $e) { //echo $e->getMessage(); return false; } } /* * getValidID : retorna um valor válido de id para grupo ou usuário * @param string $filter variavel pode ter 2 valores: usuario e grupo * @return int */
public function getValidID($filter) { try { global $Config; $ids = array(); $min = 0; if ($filter == 'usuario') { $min = $Config['uidnumber_start']; $retorno = $this->ldap->getAllUsers(); for ($i = 0; $i < $retorno['count']; $i++) { $ids[] = $retorno[$i]['uidnumber'][0]; } } elseif ($filter == 'grupo') { $min = $Config['gidnumber_start']; $retorno = $this->ldap->getAllGroups(); for ($i = 0; $i < $retorno['count']; $i++) { $ids[] = $retorno[$i]['gidnumber'][0]; } } for ($i = $min; $i <= max($ids); $i++) { if (!in_array($i, $ids)) { $id = intval($i); break; } } if (!isset($id)) { $id = intval(max($ids)) + 1; } return $id; } catch (Exception $e) { //echo $e->getMessage(); return false; } } } ?> <?php require_once dirname(__FILE__) . '/../includes/DB.php'; require_once dirname(__FILE__) . '/../includes/functions.php'; /** * Description of LogController * */ class LogController { protected $db;
protected static $instance; public static function getInstance() { if (!self::$instance) { self::$instance = new LogController(); } return self::$instance; } function __construct() { $this->db = DB::getInstance(); } function consulta($query) { if ($query) { try { $result = $this->db->query($query); $this->db->disconnect(); return $result; } catch (Exception $e) { echo($e->getMessage()); } } } function insert($query) { if ($query) { try { if (!$this->db->query($query)) { return false; } $this->db->disconnect(); return true; } catch (Exception $e) { echo $e->getMessage(); } } } function registraLogin($usuario, $flag) { $user = anti_injection($usuario); if ($flag == 'ok') { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$user','login','Logado com sucesso')"; } else { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$user','login','Falha ao realizar o login')"; } try { $this->insert($query); } catch (Exception $e) { echo $e->getMessage();
} } function registraLogout($usuario) { $user = anti_injection($usuario); $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$user','logout','Logout efetuado com sucesso')"; try { $this->insert($query); } catch (Exception $e) { echo $e->getMessage(); } } /* * registra todos os tipos de ação com feitas em um usuário * * @param string $usuarioLogado usuário que esta logado no sistema e fez a ação * @param string $acao ações suportadas: add, del, edit * @param string $flag pode ser sucesso e erro * @param string $usuario usuário que sofreu a ação */ function registraEventoUsuario($usuarioLogado, $acao, $flag, $usuario) { $usuarioLogado = anti_injection($usuarioLogado); $acao = anti_injection($acao); $usuario = anti_injection($usuario); if ($acao == 'add') { if ($flag == 'ok') { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','adicionar','Usuário $usuario adicionado com sucesso')"; } else { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','adicionar','Falha ao adicionar o usuário $usuario')"; } } elseif ($acao == 'del') { if ($flag == 'ok') { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','deletar','Usuário $usuario deletado com sucesso')"; } else { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','deletar','Falha ao deletar o usuário $usuario')"; } } elseif ($acao == 'edit') { if ($flag == 'ok') { $query = "INSERT INTO logs (usuario_logado,acao,descricao)
VALUES ('$usuarioLogado','editar','Usuário $usuario editado com sucesso')"; } else { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','editar','Falha ao editar o usuário $usuario')"; } } try { $this->insert(utf8_decode($query)); } catch (Exception $e) { echo $e->getMessage(); } } function registraEventoGrupo($usuarioLogado, $acao, $flag, $grupo) { $usuarioLogado = anti_injection($usuarioLogado); $acao = anti_injection($acao); $grupo = anti_injection($grupo); if ($acao == 'add') { if ($flag == 'ok') { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','adicionar','Grupo $grupo adicionado com sucesso')"; } else { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','adicionar','Falha ao adicionar o grupo $grupo')"; } } elseif ($acao == 'del') { if ($flag == 'ok') { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','deletar','Grupo $grupo deletado com sucesso')"; } else { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','deletar','Falha ao deletar o grupo $grupo')"; } } elseif ($acao == 'edit') { if ($flag == 'ok') { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','editar','Grupo $grupo editado com sucesso')"; } else { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','editar','Falha ao editar o grupo $grupo')"; } } try { $this->insert(utf8_decode($query)); } catch (Exception $e) { echo $e->getMessage(); } }
function registraEventoTacacs($usuarioLogado, $acao, $flag, $ip=null,$msg=null) { $usuarioLogado = anti_injection($usuarioLogado); $acao = anti_injection($acao); $ip = isset($ip)?anti_injection($ip):null; $msg = isset($msg)?anti_injection($msg):null; if ($acao == 'add') { if ($flag == 'ok') { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','tacacs_adicionar','Equipamento com o ip $ip adicionado ao arquivo temporario')"; } else { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','tacacs_adicionar','Falha ao adicionar o ip $ip adicionado ao arquivo temporario')"; } } elseif ($acao == 'del') { if ($flag == 'ok') { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','tacacs_deletar','Equipamento com o ip $ip deletado do arquivo temporario')"; } else { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','tacacs_deletar','Falha ao deletar o ip $ip adicionado ao arquivo temporario')"; } } elseif ($acao == 'aplicar') { if ($flag == 'ok') { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','tacacs_aplicar','$msg')"; } else { $query = "INSERT INTO logs (usuario_logado,acao,descricao) VALUES ('$usuarioLogado','tacacs_aplicar','$msg')"; } } try { $this->insert(utf8_decode($query)); } catch (Exception $e) { echo $e->getMessage(); } } function consultaLogs($query) { $db_log = new DB('logs'); try { $result = $db_log->query($query); $db_log->disconnect(); return $result; } catch (Exception $e) {
return $e->getMessage(); } } } ?> <?php $Config['mysql_ip'] = "localhost"; $Config['mysql_usuario'] = "xxx"; $Config['mysql_senha'] = "######"; $Config['mysql_base'] = "xxx"; $Config['mysql_base_logs'] = "xxx"; $Config['ldap_ip'] = 'ldaps://localhost'; $Config['ldap_basedn'] = 'dc=xxx,dc=xxx,dc=xx'; $Config['ldap_binddn'] = 'cn=admin,dc=xxx,dc=xxx,dc=xx'; $Config['ldap_usersdn'] = 'ou=usuarios,dc=xxx,dc=xxx,dc=xx'; $Config['ldap_groupsdn'] = 'ou=grupos,dc=xxx,dc=xxx,dc=xx'; $Config['ldap_bindpass'] = '#########'; $Config['ldap_port'] = '636'; $Config['particoes'] = array ('/','ldap','mysql','log','www'); $Config['processos'] = array('ucarp','logs_auth.pl','logs_access.pl','mavis_tacplus_ldap.pl','apache2','slapd','mysqld','tacacs'); //$Config['particoes'] = array ('/','home','lock'); $Config['user_filter'] = array('acl-ufsc','acl-ufsc-virus','rancid'); //DESCOMENTE PARA ATIVAR A VARIAVEL PARA PODER FILTRAR OS GRUPOS QUE SERAO MOSTRADOS $Config['group_filter'] = array('web-admin'); $Config['uidnumber_start'] = 1200; $Config['gidnumber_start'] = 500; //PATH do arquivo de configuracao do tacacs // LEMBRAR DE CRIAR OS DIRETORIOS/ARQUIVOS E MUDAR A PERMISSAO // PARA O APACHE (WWW-DATA) ESCREVER $Config['path_tacacs'] = '/usr/local/etc/tac_plus.cfg'; $Config['path_tacacs_temp'] = '/usr/local/etc/tacacs/temp/tac_plus_temp.cfg'; $Config['path_tacacs_backup'] = '/usr/local/etc/tacacs/backup/'; $Config['daemon'] = array( 'tacacs' => '/etc/init.d/tac_plus' ); ?> <?php define('URL_RAIZ', 'https://' . $_SERVER['SERVER_NAME'].'/ldap/');
define('URL_PUBLICO', URL_RAIZ); define('URL_ADMIN', URL_PUBLICO.'admin/'); define('RAIZ_CSS', URL_PUBLICO.'css/'); define('RAIZ_JS', URL_PUBLICO.'js/'); define('RAIZ_FORMS', URL_PUBLICO.'forms/'); define('VERSAO','Beta'); define('APP_PATH', realpath(dirname(__FILE__) . '/../')); define('PATH_INCLUDES', APP_PATH.'/includes/'); define('PATH_TEMPLATE', APP_PATH.'/template/'); define('PATH_CONTROLLERS', APP_PATH.'/controllers/'); define('PATH_PUBLICO', realpath(dirname(__FILE__) . '/../../publico/')); ?> <?php require_once(dirname(__FILE__) . '/config.php'); class DB { private $connection; private $host; private $user; private $password; private $database; private static $instance; public static function getInstance() { if (!self::$instance) { self::$instance = new DB(); } return self::$instance; } public function __construct($tipo = null) { global $Config; if (is_null($tipo)) { $this->host = $Config['mysql_ip']; $this->user = $Config['mysql_usuario']; $this->password = $Config['mysql_senha']; $this->database = $Config['mysql_base']; } else { $this->host = $Config['mysql_ip']; $this->user = $Config['mysql_usuario']; $this->password = $Config['mysql_senha']; $this->database = $Config['mysql_base_logs']; } } public function __destruct() { $this->disconnect(); }
public function connect() { if (!$this->connection = new mysqli($this->host, $this->user, $this->password, $this->database)) { throw new Exception("MySQL Connect: " . mysqli_error($this->connection)); } } public function disconnect() { if (is_resource($this->connection)) { $this->connection->close(); } } public function query($query) { if (!is_resource($this->connection)) $this->connect(); if (!$result = $this->connection->query($query)) { throw new Exception("MySQL Query: " . mysqli_error($this->connection)); } return $result; } } ?> <?php require_once realpath(dirname(__FILE__) . '/constants.php'); require_once PATH_INCLUDES . 'config.php'; require_once PATH_INCLUDES . 'firephp/fb.php'; function dataValida($data) { if (preg_match("/^(\d{2})\/(\d{2})\/(\d{4})$/", $data, $matches)) { if (checkdate($matches[2], $matches[1], $matches[3])) { return true; } } return false; } function IPValido($ip) { if (preg_match('/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}(\/[0-3][0-9])?$/', $ip)) { return true; } return false; }
function anti_injection($dado) { //Remove palavras que contenham sintaxe SQL: $dado = preg_replace("/(from|select|update|insert|delete|where|union|drop table|show tables|--|\\\\)/i", "", $dado); $dado = trim($dado); //Limpa espaços vazio no início e fim da string $dado = strip_tags($dado); //Remove tags HTML e PHP $dado = addslashes($dado); //Adiciona barras invertidas a uma string return $dado; } function array_membro() { global $Config; $exec = shell_exec("cat $Config[path_tacacs_temp] | egrep '(host|group|acl) ='"); preg_match_all('/\s*(.*[^\s])\s*=\s*(.*[^\s])\s*{/', $exec, $matches); $temp = array(); for ($i = 0; $i < sizeof($matches[1]); $i++) { $temp[$matches[1][$i]][] = $matches[2][$i]; } $array = array(); for ($i = 0; $i < sizeof($temp['group']); $i++) { for ($j = 0; $j < sizeof($temp['host']); $j++) { if (!isset($array[$temp['group'][$i]])) { $array[$temp['group'][$i]][] = $temp['group'][$i]; } $array[$temp['group'][$i]][] = $temp['group'][$i] . '@' . $temp['host'][$j]; } } return $array; } function array_equipamentos() { global $Config; $temp = "egrep '(host|address) = *' $Config[path_tacacs_temp] | awk '{for(i=3;i<=NF;i++){printf \"%s \" ,\$i}; print \"\"}'"; $exec = shell_exec($temp); if ($exec) { $exec = preg_replace(array('/\s*address/', '/\s*host/'), array('address', 'host'), $exec); $explode = explode("\n", $exec); $key = ""; for ($i = 0; $i < sizeof($explode); $i++) { if (preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}.*$/', $explode[$i])) { $array[$key][] = trim($explode[$i]);
} else { $value = str_replace(array('{', '/', '}'), '', $explode[$i]); $key = trim($value); if ($key != "") { $array[$key] = null; } } } return $array; } else { return false; } } function add_equipamento($grupo, $ip, $desc) { global $Config; //NAO ESQUECER DE MEXER NA PERMISSAO DO ARQUIVO /ETC/TACACS/TAC_PLUS.CFG //PARA CHOWN :WWW-DATA TER PERMISSAO 770 $host = '##HOST_' . strtoupper($grupo) . '##'; $address = preg_replace(array('/\//', '/\./'), array('\/', '\.'), $ip); $string = "address = $address #$desc\\n\\t\\t$host"; $sed = "/bin/sed -i 's/$host/$string/g' $Config[path_tacacs_temp] 2>&1"; return shell_exec($sed); } function get_equipamento($ip) { global $Config; $address = preg_replace(array('/\//', '/\./'), array('\/', '\.'), $ip); $comando = "/bin/egrep 'address\s*=\s*$address.*' $Config[path_tacacs_temp] 2>&1"; return shell_exec($comando); } function delete_equipamento($ip) { global $Config; $address = preg_replace(array('/\//', '/\./'), array('\/', '\.'), $ip); $comando = "/bin/sed -i '/address\s*=\s*$address.*/d' $Config[path_tacacs_temp] 2>&1"; return shell_exec($comando); } function altera_arquivo($tipo, $daemon) { global $Config;
if ($tipo == 'backup') { if ($daemon == 'tacacs') { return copy($Config['path_tacacs'], $Config['path_tacacs_backup'] . 'tac_plus_' . date('YmdHis') . '.cfg'); } }elseif($tipo == 'copiar'){ if ($daemon == 'tacacs') { return copy($Config['path_tacacs_temp'], $Config['path_tacacs']); } } } //VARIAVEL DAEMON TEM QUE ESTAR TBM NO ARQUIVO DE CONF NO ARRAY!!! function reinicia_daemon($daemon){ global $Config; return shell_exec($Config['daemon'][$daemon].' restart 2>&1'); } ?> <?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_INCLUDES . 'config.php'; /** * Description of LDAP * * Classe responsável por fazer toda a interação com o LDAP * * @author luis */ class LDAP { /* * @var string base da árvore LDAP */ private $baseDN; /* * @var string base de usuários da árvore LDAP */ private $usersDN; /* * @var string base de grupos da árvore LDAP */ private $groupsDN; /* * @var string usuário que fará a conexão com o servidor LDAP */
private $bindDN; /* * @var string senha do usuário da conexão */ private $bindPW; /* * @var string ip/nome do servidor LDAP */ private $host; /* * @var int porta de conexão com o servidor LDAP */ private $port; /* * @var ldap-link variável com as propriedades da conexão com o servidor LDAP */ private $connection; /* * @var LDAP instância da classe */ private static $instance; /* * getInstance(): função que substitui a instanciação de um novo objeto. * verifica se já foi instanciado, se sim retorna o objeto, caso contrário, cria um novo objeto * * @return LDAP objeto LDAP */ public static function getInstance() { if (!self::$instance) { self::$instance = new LDAP(); } return self::$instance; } /* * __construct(): função de instanciação do objeto. Apenas carrega os valores do arquivo de configurações */ public function __construct() { global $Config; $this->host = $Config['ldap_ip'];
$this->port = $Config['ldap_port']; $this->baseDN = $Config['ldap_basedn']; $this->bindDN = $Config['ldap_binddn']; $this->bindPW = $Config['ldap_bindpass']; $this->usersDN = $Config['ldap_usersdn']; $this->groupsDN = $Config['ldap_groupsdn']; } /* * getUserDN: função que retorna o atributo usersDN, que é a base da árvore de usuários do LDAP * * @return string base de usuários da árvore LDAP */ public function getUserDN() { return $this->usersDN; } /* * getGroupDN: função que retorna o atributo groupsDN, que é a base da árvode de grupos do LDAP * * @return string base de grupos da árvore LDAP */ public function getGroupDN() { return $this->groupsDN; } /* * connect: função para fazer a conexão com o LDAP. * */ public function connect() { $ldapConn = ldap_connect($this->host, $this->port); if (!$ldapConn) { die('O servidor LDAP não esta respondendo !'); } ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($ldapConn, LDAP_OPT_REFERRALS, 0); $ldapBind = ldap_bind($ldapConn, $this->bindDN, $this->bindPW); if (!$ldapBind) { die('Não foi possivel se vincular ao Servidor LDAP'); } $this->connection = $ldapConn; }
/* * unbind: fecha a conexão com o servidor LDAP */ public function unbind() { if (is_resource($this->connection)) { //ldap_unbind($this->connection); ldap_close($this->connection); } } /* * getAllUsers: função que busca na árvore LDAP todos os usuários * * @return array array com os usuários da base LDAP */ public function getAllUsers($filter=null) { if (!is_resource($this->connection)) { $this->connect(); } if(!$filter){ $filter = "(uid=*)"; } if (!$ldap_search = ldap_search($this->connection, $this->usersDN, $filter)) { throw new Exception("LDAP ERROR: " . ldap_err2str(ldap_errno($this->connection))); } else { return ldap_get_entries($this->connection, $ldap_search); } } public function getAllGroups() { if (!is_resource($this->connection)) { $this->connect(); } if (!$ldap_search = ldap_search($this->connection, $this->groupsDN, "(objectclass=posixGroup)")) { throw new Exception("LDAP ERROR: " . ldap_err2str(ldap_errno($this->connection))); } else { return ldap_get_entries($this->connection, $ldap_search); } } public function ldapGetUser($user) { if (!is_resource($this->connection)) { $this->connect(); }
if (!$ldapSearch = @ldap_search($this->connection, $this->usersDN, "(uid=$user)")) { throw new Exception("LDAP ERROR: " . ldap_err2str(ldap_errno($this->connection))); } else { $ldapResults = ldap_get_entries($this->connection, $ldapSearch); } $this->unbind(); return $ldapResults; } public function ldapGetGroup($filter) { if (!is_resource($this->connection)) { $this->connect(); } if (!$ldapSearch = @ldap_search($this->connection, $this->groupsDN, "(|(gidNumber=$filter)(cn=$filter))")) { throw new Exception("LDAP ERROR: " . ldap_err2str(ldap_errno($this->connection))); } else { $ldapResults = ldap_get_entries($this->connection, $ldapSearch); } $this->unbind(); return $ldapResults; } public function deleteAttr($dn, $var) { if (!is_resource($this->connection)) { $this->connect(); } if (!@ldap_mod_del($this->connection, $dn, $var)) { throw new Exception("LDAP ERROR: " . ldap_err2str(ldap_errno($this->connection))); } $this->unbind(); return true; } public function addAttr($dn, $var) { if (!is_resource($this->connection)) { $this->connect(); } if (!@ldap_mod_add($this->connection, $dn, $var)) { throw new Exception("LDAP ERROR: " . ldap_err2str(ldap_errno($this->connection))); }
$this->unbind(); return true; } public function modifyDN($dn, $var) { if (!is_resource($this->connection)) { $this->connect(); } if (!@ldap_modify($this->connection, $dn, $var)) { throw new Exception("LDAP ERROR: " . ldap_err2str(ldap_errno($this->connection))); } $this->unbind(); return true; } public function deleteDN($dn) { if (!is_resource($this->connection)) { $this->connect(); } $temp = @ldap_delete($this->connection, $dn); $this->unbind(); return $temp; } public function addDN($dn, $var) { if (!is_resource($this->connection)) { $this->connect(); } if (!@ldap_add($this->connection, $dn, $var)) { throw new Exception("LDAP ERROR: " . ldap_err2str(ldap_errno($this->connection))); } $this->unbind(); return true; } public function isGroupMember($filter) { if (!is_resource($this->connection)) { $this->connect(); } if (!$ldapSearch = @ldap_search($this->connection, $this->groupsDN, $filter)) { throw new Exception("LDAP ERROR: " . ldap_err2str(ldap_errno($this->connection))); } else { $ldapResults = ldap_get_entries($this->connection, $ldapSearch); } $this->unbind();
return $ldapResults; } } ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>Administração de Usuários</title> <link rel="icon" type="image/png" href="<?php echo RAIZ_CSS; ?>imgs/ldap.png"/> <link rel="stylesheet" type="text/css" href="<?php echo RAIZ_CSS; ?>style.css" /> <link rel="stylesheet" type="text/css" href="<?php echo RAIZ_CSS; ?>custom-theme/jquery-ui-custom.css" /> <link rel="stylesheet" type="text/css" href="<?php echo RAIZ_CSS; ?>ui.jqgrid.css" /> <link rel="stylesheet" type="text/css" href="<?php echo RAIZ_CSS; ?>colorbox.css" /> <script type="text/javascript" src="<?php echo RAIZ_JS; ?>jquery-latest.js"></script> <script type="text/javascript" src="<?php echo RAIZ_JS; ?>jquery-ui-custom.min.js"></script> </head> <body> <div id="header"> <div style="width: 980px; margin: 0 auto;"> <h3>Administração de Usuários</h3><span style="margin-left: 15px;font-size: 14px; float: left"><?php echo VERSAO ?></span> <?php echo (isset($_SESSION['logado'])) ? '<span style="float:right">Olá, <strong>' . $_SESSION['user']['nome'] . '</strong></span>' : ''; ?> </div> </div> <hr></hr> <?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); ?> <div class="menu_box"> <h4 class="menu_header">Usuário</h4> <ul class="menu_options"> <li <?php if ($page == 'editar') echo 'class ="active"'; ?>><a href="<?php echo URL_PUBLICO; ?>usuario/<?php echo $_SESSION['user']['uid']; ?>/editar">Editar</a></li> <li <?php if ($page == 'permissoes') echo 'class ="active"'; ?>><a href="<?php echo
URL_PUBLICO; ?>usuario/<?php echo $_SESSION['user']['uid']; ?>/permissoes">Permissões</a></li> <li <?php if ($page == 'logs') echo 'class ="active"'; ?>><a href="<?php echo URL_PUBLICO; ?>usuario/<?php echo $_SESSION['user']['uid']; ?>/logs">Histórico de comandos</a></li> <li><a href="<?php echo URL_PUBLICO; ?>logout">Sair</a></li> </ul> </div> <?php if (isset($_SESSION['user']['admin']) && $_SESSION['user']['admin'] == true): ?> <div class="menu_box"> <h4 class="menu_header">Sistema</h4> <ul class="menu_options"> <li <?php if ($page == 'visao-geral') echo 'class ="active"'; ?>><a href="<?php echo URL_PUBLICO; ?>sistema/visao/">Visão Geral</a></li> </ul> </div> <div class="menu_box"> <h4 class="menu_header">Gerenciar LDAP</h4> <ul class="menu_options"> <li <?php if ($page == 'adicionar-usuarios') echo 'class ="active"'; ?>><a href="<?php echo URL_PUBLICO; ?>ldap/usuarios/adicionar">Adicionar Usuário</a></li> <li <?php if ($page == 'editar-usuarios') echo 'class ="active"'; ?>><a href="<?php echo URL_PUBLICO; ?>ldap/usuarios/listar">Editar Usuários</a></li> <li <?php if ($page == 'adicionar-grupo') echo 'class ="active"'; ?>><a href="<?php echo URL_PUBLICO; ?>ldap/grupo/adicionar">Adicionar Grupo</a></li> <li <?php if ($page == 'editar-grupo') echo 'class ="active"'; ?>><a href="<?php echo URL_PUBLICO; ?>ldap/grupo/listar">Editar Grupos</a></li> </ul> </div> <div class="menu_box"> <h4 class="menu_header">Gerenciar TACACS+</h4> <ul class="menu_options"> <li <?php if ($page == 'adicionar-equipamento') echo 'class ="active"'; ?>><a href="<?php echo URL_PUBLICO; ?>tacacs/adicionar">Adicionar Equipamento</a></li> <li <?php if ($page == 'listar-equipamento') echo 'class ="active"'; ?>><a href="<?php echo URL_PUBLICO; ?>tacacs/listar">Listar Equipamentos</a></li> <li><a <?php echo (isset($_SESSION['tacacs']['modificado']) ? 'class="aplicar_tacacs warning"' : 'class="aplicar_tacacs"'); ?> href="#">Aplicar Configurações</a></li> <li><a id="ajuda" href="<?php echo URL_PUBLICO; ?>tacacs/ajuda">Ajuda de Configuração</a></li> </ul> </div>
<?php if (isset($_SESSION['tacacs']['modificado'])): ?> <p id="msg" class="warning_box warning"> <?php echo $_SESSION['tacacs']['msg']; ?> </p> <?php else: ?> <p id="msg" class="warning_box hidden"> </p> <?php endif; ?> <script type="text/javascript"> $('#ajuda').click(function(e){ e.preventDefault(); window.open($('#ajuda').attr('href'),"ajuda","location=1,status=1,scrollbars=1, width=500,height=400"); }); $('.aplicar_tacacs').click(function(e){ $.getJSON('../forms/aplicar?d=tac', function(response) { if(response.status == 'ok'){ $('.aplicar_tacacs').removeClass('warning'); var msg = $('#msg'); msg.removeClass('hidden'); msg.removeClass('warning'); msg.addClass('success_box'); msg.html(response.msg).fadeOut(5000,function(){ $(this).html(''); $(this).removeClass('success_box'); }); }else{ var msg = $('#msg'); msg.removeClass('hidden'); msg.removeClass('warning_box'); msg.addClass('error_box'); msg.html(response.msg); } }); e.preventDefault(); }); </script> <?php endif; ?>
<div id="footer"> <div id="logos"> <img src="<?php echo RAIZ_CSS;?>imgs/setic.png" align="middle" alt="SeTIC"/> <img src="<?php echo RAIZ_CSS;?>imgs/ufsc.png" align="middle" alt="UFSC" style="margin-left: 30px;"/> <img src="<?php echo RAIZ_CSS;?>imgs/pop.png" align="middle" alt="PoP-SC" style="margin-left: 30px"/> </div>
</div> </body> </html> <?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LogController.php'; require_once PATH_INCLUDES . 'functions.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { $grupo = isset($_POST['grupo']) ? $_POST['grupo'] : null; $ip = isset($_POST['ip']) ? $_POST['ip'] : null; $desc = isset($_POST['descricao']) ? $_POST['descricao'] : null; if (!isset($grupo) || $grupo == 'false') { $resposta['error']['grupo'] = "Grupo é OBRIGATÓRIO"; } if (!isset($ip) || empty($ip)) { $resposta['error']['ip'] = "IP é OBRIGATÓRIO"; } else { if (!preg_match('/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}(\/[0-3][0-9])?$/', $ip)) { $resposta['error']['ip'] = "IP é INVÁLIDO"; } } if (!isset($desc) || empty($desc)) { $resposta['error']['descricao'] = "Descrição é OBRIGATÓRIA"; } if (!isset($resposta)) { if (!get_equipamento($ip)) { $temp = add_equipamento($grupo, $ip, $desc); $db = LogController::getInstance(); if (is_null($temp)) { $resposta['status'] = "ok"; $resposta['msg'] = "IP cadastrado com Sucesso"; $_SESSION['tacacs']['modificado'] = true; $_SESSION['tacacs']['msg'] = 'Configurações foram modificadas, mas ainda não foram aplicadas. Clique em <strong>Aplicar Configurações</strong> para não perder suas modificações.';
$db->registraEventoTacacs($_SESSION['user']['uid'], 'add', 'ok', $ip); } else { $resposta['status'] = "error"; $resposta['msg'] = "Ocorreu algum ERRO: $temp"; $db->registraEventoTacacs($_SESSION['user']['uid'], 'add', 'erro', $ip); } } else { $resposta['error']['ip'] = "IP já CADASTRADO"; } } exit(json_encode($resposta)); } ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; require_once PATH_CONTROLLERS . 'LogController.php'; require_once PATH_INCLUDES . 'functions.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { if (isset($_POST['cn']) && !empty($_POST['cn'])) { $var['cn'] = strtolower($_POST['cn']); } else { $resposta['error']['cn'] = "Nome é OBRIGATÓRIO"; } if (isset($_POST['descricao']) && !empty($_POST['descricao'])) { $var['description'] = $_POST['descricao']; } else { $resposta['error']['descricao'] = "Descrição é OBRIGATÓRIA"; } if (isset($_POST['usuarios'])){ for($i=0;$i<sizeof($_POST['usuarios']);$i++){ $var['memberUid'][$i] = $_POST['usuarios'][$i]; } }
if(!$resposta){ $ldap = LDAPController::getInstance(); $var['objectclass'][0]= 'top'; $var['objectclass'][1]= 'posixGroup'; $var['gidnumber'] = $ldap->getValidID('grupo'); $add = $ldap->addDN($var, 'grupo'); $db = LogController::getInstance(); if ($add) { $db->registraEventoGrupo($_SESSION['user']['uid'],'add','ok',$var['cn']); $resposta['status'] = "ok"; $resposta['msg'] = "Grupo Cadastrado com Sucesso"; }else{ $db->registraEventoGrupo($_SESSION['user']['uid'],'add','erro',$var['cn']); $resposta['status'] = "error"; $resposta['msg'] = "Ocorreu algum ERRO"; } } exit(json_encode($resposta)); } ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; require_once PATH_CONTROLLERS . 'LogController.php'; require_once PATH_INCLUDES . 'functions.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { $var['objectClass'][] = 'top'; $var['objectClass'][] = 'person'; $var['objectClass'][] = 'inetOrgPerson'; $var['objectClass'][] = 'posixAccount'; if (isset($_POST['nome']) && !empty($_POST['nome'])) { $var['givenName'] = $_POST['nome']; } else {
$resposta['error']['nome'] = "Nome é OBRIGATÓRIO"; } if (isset($_POST['uid']) && !empty($_POST['uid'])) { $var['uid'] = strtolower($_POST['uid']); $var['cn'] = strtolower($_POST['uid']); $var['sn'] = strtolower($_POST['uid']); } else { $resposta['error']['uid'] = "Usuário é OBRIGATÓRIO"; } if (isset($_POST['email']) && !empty($_POST['email'])) { $pattern = '/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])' . '(([a-z0-9-])*([a-z0-9]))+' . '(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i'; if (preg_match($pattern, $_POST['email'])) { $var['mail'] = $_POST['email']; } else { $resposta['error']['email'] = "E-mail Inválido"; } } else { $resposta['error']['email'] = "E-mail é OBRIGATÓRIO"; } if (isset($_POST['expira'])) { if (isset($_POST['data_expira']) && !empty($_POST['data_expira'])) { if (dataValida($_POST['data_expira'])) { $dataAtual = date('d-m-Y'); $var['objectClass'][] = "shadowAccount"; $data = str_replace('/', '-', $_POST['data_expira']); $var['shadowMax'] = (strtotime($data) - strtotime($dataAtual)) / 86400; $var['shadowMin'] = 0; $var['shadowInactive'] = 0; $var['shadowExpire'] = 0; $var['shadowWarning'] = 1; $var['shadowLastChange'] = intval(strtotime($dataAtual) / (86400)); } else { $resposta['error']['data_expira'] = "DATA em formato inválido"; } } else { $resposta['error']['data_expira'] = "DATA não pode ser vazia"; } } $ldap = LDAPController::getInstance(); if (isset($_POST['senha']) && !empty($_POST['senha'])) { if (sizeof($_POST['senha']) < 6) { if (!preg_match('/^[a-z0-9]+$/i', $_POST['senha'])) {
if (isset($_POST['confirma']) && !empty($_POST['confirma'])) { if ($_POST['senha'] === $_POST['confirma']) { $var['userPassword'] = $ldap->createSHA($_POST['senha']); } else { $resposta['error']['confirma'] = "Senhas digitadas são diferentes"; } } else { $resposta['error']['confirma'] = "Senha de confirmação é OBRIGATÓRIA"; } } else { $resposta['error']['senha'] = "Senha deve ter no mínimo 1 (um) caracter especial"; } } else { $resposta['error']['senha'] = "Senha deve ter no minimo 6 caracteres"; } } else { $resposta['error']['senha'] = "Senha é OBRIGATÓRIA"; } $var['gidNumber'] = $_POST['grupo']; $ldap->atualizaUsuariosGrupo('add', $var['gidNumber'], strtolower($_POST['uid'])); $var['uidNumber'] = $ldap->getValidID('usuario'); if (isset($_POST['kvm'])) { $var['objectClass'][] = 'kn4140User'; $var['iKVM4140-userProfile'] = 'su/administrator'; } if (isset($_POST['tacacs'])) { $var['objectClass'][] = 'tacacsAccount'; if (isset($_POST['rede']) && !empty($_POST['rede'][0])) { $var['tacacsClient'] = $_POST['rede']; } else { $var['tacacsClient'] = '150.162.248.0/24'; } if (isset($_POST['perfil']) && !empty($_POST['perfil'][0])) { if (preg_match('/^\{.*\}$/', $_POST['perfil'][0])) { $var['tacacsProfile'] = $_POST['perfil'][0]; } else { $resposta['error']['perfil'] = "Perfil inválido"; } } else { $var['tacacsProfile'] = '{ }';
} if (isset($_POST['membro']) && !empty($_POST['membro'][0])) { for($i=0;$i<sizeof($_POST['membro']);$i++){ if($_POST['membro'][$i]){ $var['tacacsMember'][]=$_POST['membro'][$i]; }else{ $resposta['error']['membro'] = "Membro com algum valor INVÁLIDO"; } } } else { $resposta['error']['membro'] = "OBRIGATÓRIO pelo menos um grupo"; } } $var['loginShell'] = '/bin/bash'; $var['homeDirectory'] = '/home/' . strtolower($_POST['uid']); $db = LogController::getInstance(); if (!$resposta) { $add = $ldap->addDN($var, 'usuario'); if ($add) { if (isset($_POST['servidores'])) { //$ldap->atualizaUsuariosGrupo('add','NOME DO GRUPO OU gid',$var['uid']); } if (isset($_POST['web_admin'])) { $ldap->atualizaUsuariosGrupo('add', 'web-admin', strtolower($_POST['uid'])); } $db->registraEventoUsuario($_SESSION['user']['uid'], 'add', 'ok', $var['uid']); $resposta['status'] = "ok"; $resposta['msg'] = "Usuário Cadastrado com Sucesso"; } else { $db->registraEventoUsuario($_SESSION['user']['uid'], 'add', 'erro', $var['uid']); $resposta['status'] = "error"; $resposta['msg'] = "Ocorreu algum ERRO"; } } echo json_encode($resposta); } ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LogController.php';
require_once PATH_INCLUDES . 'functions.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { $daemon = isset($_GET['d']) ? $_GET['d'] : null; if ($daemon == 'tac') { $db = LogController::getInstance(); if (altera_arquivo('backup', 'tacacs')) { if (altera_arquivo('copiar', 'tacacs')) { $reinicia = reinicia_daemon('tacacs'); if (preg_match('/(initiated)/i',$reinicia)) { $resposta['status'] = "ok"; $resposta['msg'] = "Configurações aplicadas com sucesso!"; $_SESSION['tacacs']['modificado'] = null; $_SESSION['tacacs']['msg'] = null; $db->registraEventoTacacs($_SESSION['user']['uid'], 'aplicar', 'ok', null,$resposta['msg']); } else { $resposta['status'] = "error"; $resposta['msg'] = "Falha ao reiniciar o serviço!"; $db->registraEventoTacacs($_SESSION['user']['uid'], 'aplicar', 'erro', null,$resposta['msg']); } } else { $resposta['status'] = "error"; $resposta['msg'] = "Erro ao copiar o arquivo!"; $db->registraEventoTacacs($_SESSION['user']['uid'], 'aplicar', 'erro', null,$resposta['msg']); } } else { $resposta['status'] = "error"; $resposta['msg'] = "Erro ao fazer o backup do arquivo!"; $db->registraEventoTacacs($_SESSION['user']['uid'], 'aplicar', 'erro', null,$resposta['msg']); } } exit(json_encode($resposta)); } ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LogController.php'; require_once PATH_INCLUDES . 'functions.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { if (isset($_GET['e']) && !empty($_GET['e'])) { $ip = isset($_GET['e']) ? $_GET['e'] : null; $db = LogController::getInstance(); if (IPValido($ip)) { if (get_equipamento($ip)) { if (is_null(delete_equipamento($_GET['e']))) { $resposta = array('error' => null, 'msg' => 'IP deletado com sucesso!'); $_SESSION['tacacs']['modificado'] = true; $_SESSION['tacacs']['msg'] = 'Configurações foram modificadas, mas ainda não foram aplicadas. Clique em <strong>Aplicar Configurações</strong> para não perder suas modificações.'; $db->registraEventoTacacs($_SESSION['user']['uid'], 'del', 'ok', $ip); } } else { $resposta = array('error' => 'erro', 'msg' => 'IP não cadastrado!'); $db->registraEventoTacacs($_SESSION['user']['uid'], 'del', 'erro', $ip); } } else { $resposta = array('error' => 'erro', 'msg' => 'Ocorreu algum problema ao tentar deletar o IP!'); $db->registraEventoTacacs($_SESSION['user']['uid'], 'del', 'erro', $ip); } echo json_encode($resposta); exit(); } } ?>
<?php require_once realpath(dirname(__FILE__) .
'/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; require_once PATH_CONTROLLERS . 'LogController.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { if(isset ($_GET['g']) && !empty ($_GET['g'])){ $ldap = LDAPController::getInstance(); $db = LogController::getInstance(); if($ldap->deleteDN($_GET['g'],'grupo')){ $db->registraEventoGrupo($_SESSION['user']['uid'],'del','ok',$_GET['g']); $resposta = array('error' => null,'msg'=>'Usuário deletado com sucesso!'); }else{ $db->registraEventoGrupo($_SESSION['user']['uid'],'del','ok',$_GET['g']); $resposta = array('error' => 'erro','msg'=>'Ocorreu algum problema ao tentar deletar o usuário!'); } echo json_encode($resposta); exit(); } } ?> <?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; require_once PATH_CONTROLLERS . 'LogController.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { if(isset ($_GET['u']) && !empty ($_GET['u'])){ $ldap = LDAPController::getInstance(); $db = LogController::getInstance(); if($ldap->deleteDN($_GET['u'],'usuario')){ $db->registraEventoUsuario($_SESSION['user']['uid'],'del','ok',$_GET['u']);
$resposta = array('error' => null,'msg'=>'Usuário deletado com sucesso!'); }else{ $db->registraEventoUsuario($_SESSION['user']['uid'],'del','erro',$_GET['u']); $resposta = array('error' => 'erro','msg'=>'Ocorreu algum problema ao tentar deletar o usuário!'); } echo json_encode($resposta); exit(); } } ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; session_start(); if ($_SESSION['logado']) { if (isset($_POST['nome']) && !empty($_POST['nome'])) { $var['givenName'] = $_POST['nome']; } else { $resposta['error']['nome'] = "Nome é OBRIGATÓRIO"; } if (isset($_POST['email']) && !empty($_POST['email'])) { $pattern = '/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])' . '(([a-z0-9-])*([a-z0-9]))+' . '(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i'; if (preg_match($pattern, $_POST['email'])) { $var['mail'] = $_POST['email']; } else { $resposta['error']['email'] = "E-mail Inválido"; } } else { $resposta['error']['email'] = "E-mail é OBRIGATÓRIO"; } $ldap = LDAPController::getInstance(); if (isset($_POST['mudar_senha'])) { if (isset($_POST['senha']) && !empty($_POST['senha'])) { if (sizeof($_POST['senha']) < 6) { if (!preg_match('/^[a-z0-9]+$/i', $_POST['senha'])) { if (isset($_POST['confirma']) && !empty($_POST['confirma'])) { if ($_POST['senha'] === $_POST['confirma']) { $var['userPassword'] = $ldap->createSHA($_POST['senha']);
} else { $resposta['error']['confirma'] = "Senhas digitadas são diferentes"; } } else { $resposta['error']['confirma'] = "Senha de confirmação é OBRIGATÓRIA"; } } else { $resposta['error']['senha'] = "Senha deve ter no mínimo 1 (um) caracter especial"; } } else { $resposta['error']['senha'] = "Senha deve ter no minimo 6 caracteres"; } } else { $resposta['error']['senha'] = "Senha é OBRIGATÓRIA"; } } if (!isset($resposta)) { $temp = $ldap->modificarDN($_SESSION['user']['dn'], $var); //die(var_dump($temp)); $resposta = array("status" => "indefinido"); if ($temp) { $_SESSION['user']['nome'] = $var['givenName']; $_SESSION['user']['mail'] = $var['mail']; $resposta['status'] = "ok"; $resposta['msg'] = "Dados Atualizados com Sucesso"; } else { $resposta['status'] = "error"; $resposta['msg'] = "Ocorreu algum ERRO"; } } echo json_encode($resposta); } else { header('Location:' . URL_PUBLICO); } ?> <?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; require_once PATH_CONTROLLERS . 'LogController.php'; require_once PATH_INCLUDES . 'functions.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300);
if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { $ldap = LDAPController::getInstance(); $antigo = $ldap->getDN($_POST['antigo_cn'], 'grupo'); if ($antigo) { if (isset($_POST['cn']) && !empty($_POST['cn'])) { if ($_POST['cn'] != $antigo[0]['cn'][0]) { $var['cn'] = strtolower($_POST['cn']); $mudou_dn = true; } } else { $resposta['error']['cn'] = "Nome é OBRIGATÓRIO"; } if (isset($_POST['descricao']) && !empty($_POST['descricao'])) { if ($_POST['descricao'] != $antigo[0]['description'][0]) { $var['description'] = $_POST['descricao']; } } else { $resposta['error']['descricao'] = "Descricao é OBRIGATÓRIA"; } if (isset($_POST['usuarios'])) { for ($i = 0; $i < sizeof($_POST['usuarios']); $i++) { $var['memberUid'][$i] = $_POST['usuarios'][$i]; } } else { $var['memberUid'][0] = ''; } if (!$resposta) { if ($mudou_dn) { array_shift($antigo[0]['objectclass']); $var['objectClass'] = $antigo[0]['objectclass']; $var['gidNumber'] = $antigo[0]['gidnumber'][0]; $db = LogController::getInstance(); if ($ldap->deleteDN($antigo[0]['cn'][0], 'grupo')) { if ($ldap->addDN($var, 'grupo')) { $db->registraEventoGrupo($_SESSION['user']['uid'], 'edit', 'ok', $var['cn']); $resposta['status'] = "ok"; $resposta['msg'] = "Grupo alterado com Sucesso"; } else {
$db->registraEventoGrupo($_SESSION['user']['uid'], 'edit', 'erro', $var['cn']); $resposta['status'] = "error"; $resposta['msg'] = "Ocorreu algum ERRO"; } } else { $db->registraEventoGrupo($_SESSION['user']['uid'], 'edit', 'erro', $var['cn']); $resposta['status'] = "error"; $resposta['msg'] = "Ocorreu algum ERRO"; } } else { $db = LogController::getInstance(); if ($ldap->modificarDN($antigo[0]['dn'], $var)) { $db->registraEventoGrupo($_SESSION['user']['uid'], 'edit', 'ok', $var['cn']); $resposta['status'] = "ok"; $resposta['msg'] = "Grupo alterado com Sucesso"; } else { $db->registraEventoGrupo($_SESSION['user']['uid'], 'edit', 'erro', $var['cn']); $resposta['status'] = "error"; $resposta['msg'] = "Ocorreu algum ERRO"; } } } echo json_encode($resposta); } else { exit(json_encode(array('status' => 'error', 'msg' => 'Ocorreu algum ERRO'))); } } ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; require_once PATH_CONTROLLERS . 'LogController.php'; require_once PATH_INCLUDES . 'functions.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit();
} else { $ldap = LDAPController::getInstance(); $usuario = $_POST; unset($_POST); $antigo = $ldap->getDN($usuario['uid_antigo'], 'usuario'); $antigo_web = $ldap->isMember('web-admin', $antigo[0]['uid'][0]); for ($i = 0; $i < $antigo[0]['objectclass']['count']; $i++) { if ($antigo[0]['objectclass'][$i] == 'kn4140User') { $antigo_kvm = true; } if ($antigo[0]['objectclass'][$i] == 'tacacsAccount') { $antigo_tacacs = true; } if ($antigo[0]['objectclass'][$i] == 'shadowAccount') { $antigo_shadow = true; } $var['objectClass'][] = $antigo[0]['objectclass'][$i]; } if ($antigo) { /* * VERIFICACAO DE USUARIO */ if (isset($usuario['uid']) && !empty($usuario['uid'])) { if ($usuario['uid'] != $antigo[0]['uid'][0]) { $alterado = true; $var['uid'] = $usuario['uid']; $var['cn'] = $usuario['uid']; $var['sn'] = $usuario['uid']; $var['uidNumber'] = $antigo[0]['uidnumber'][0]; $var['loginShell'] = $antigo[0]['loginshell'][0]; $var['homeDirectory'] = '/home/' . $usuario['uid']; } else { $var['uid'] = $antigo[0]['uid'][0]; $var['cn'] = $antigo[0]['cn'][0]; $var['sn'] = $antigo[0]['sn'][0]; $var['uidNumber'] = $antigo[0]['uidnumber'][0]; $var['loginShell'] = $antigo[0]['loginshell'][0]; $var['homeDirectory'] = $antigo[0]['homedirectory'][0]; } } else { $resposta['error']['uid'] = "Usuário é OBRIGATÓRIO"; } /* * VERIFICACAO DO NOME DO USUARIO */
if (isset($usuario['nome']) && !empty($usuario['nome'])) { if ($usuario['nome'] != $antigo[0]['givenname'][0]) { $var['givenName'] = $usuario['nome']; } else { $var['givenName'] = $antigo[0]['givenname'][0]; } } else { $resposta['error']['nome'] = "Usuário é OBRIGATÓRIO"; } /* * VERIFICACAO DE EMAIL DO USUARIO */ if (isset($usuario['email']) && !empty($usuario['email'])) { $pattern = '/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])' . '(([a-z0-9-])*([a-z0-9]))+' . '(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i'; if (preg_match($pattern, $usuario['email'])) { if ($usuario['email'] != $antigo[0]['mail'][0]) { $var['mail'] = $usuario['email']; } else { $var['mail'] = $antigo[0]['mail'][0]; } } else { $resposta['error']['email'] = "E-mail Inválido"; } } else { $resposta['error']['email'] = "E-mail é OBRIGATÓRIO"; } /* * VERIFICACAO DE EXPIRACAO DA CONTA */ if (isset($usuario['expira'])) { if (isset($usuario['data_expira']) && !empty($usuario['data_expira'])) { if (dataValida($usuario['data_expira'])) { if ($antigo_shadow) { $validade_antiga = ($antigo[0]['shadowlastchange'][0] * 86400) + ($antigo[0]['shadowmax'][0] * 86400); /* * verificar se a data nova e a antiga são diferentes caso positivo, atualizar o registro * * FEITO */ if (date('d/m/Y', $validade_antiga) != $usuario['data_expira']) { $dataAtual = date('d-m-Y'); $data = str_replace('/', '-', $usuario['data_expira']);
$var['shadowMax'] = (strtotime($data) - strtotime($dataAtual)) / 86400; $var['shadowMin'] = 0; $var['shadowInactive'] = 0; $var['shadowExpire'] = 0; $var['shadowWarning'] = 1; $var['shadowLastChange'] = intval(strtotime($dataAtual) / (86400)); } else { $var['shadowMax'] = $antigo[0]['shadowmax'][0]; $var['shadowMin'] = $antigo[0]['shadowmin'][0]; $var['shadowInactive'] = $antigo[0]['shadowinactive'][0]; $var['shadowExpire'] = $antigo[0]['shadowexpire'][0]; $var['shadowWarning'] = $antigo[0]['shadowwarning'][0]; $var['shadowLastChange'] = $antigo[0]['shadowlastchange'][0]; } } else { $alterado = true; /* * CRIAR O OBJECTCLASS E OS RESPECTIVOS ATRIBUTOS * * FEITO!! */ $var['objectClass'][] = "shadowAccount"; $dataAtual = date('d-m-Y'); $data = str_replace('/', '-', $usuario['data_expira']); $var['shadowMax'] = (strtotime($data) - strtotime($dataAtual)) / 86400; $var['shadowMin'] = 0; $var['shadowInactive'] = 0; $var['shadowExpire'] = 0; $var['shadowWarning'] = 1; $var['shadowLastChange'] = intval(strtotime($dataAtual) / (86400)); } } else { $resposta['error']['data_expira'] = "DATA em formato inválido"; } } else { $resposta['error']['data_expira'] = "DATA não pode ser vazia"; } } else { if ($antigo_shadow) { $alterado = true; $remove[] = 'shadowAccount';
/* $delete['shadowMax'] = $antigo[0]['shadowmax'][0]; $delete['shadowMin'] = $antigo[0]['shadowmin'][0]; $delete['shadowInactive'] = $antigo[0]['shadowinactive'][0]; $delete['shadowExpire'] = $antigo[0]['shadowexpire'][0]; $delete['shadowWarning'] = $antigo[0]['shadowwarning'][0]; $delete['shadowLastChange'] = $antigo[0]['shadowlastchange'][0]; $delete['objectClass'] = 'shadowAccount'; FB::log('NOVO NAO É SHADOW E ANTIGO ERA - CRIOU ARRAY DE ATRIBUTOS PARA DELETAR'); */ } } /* * MUDANCA DE SENHA DO USUARIO */ if (isset($usuario['mudar_senha'])) { if (isset($usuario['senha']) && !empty($usuario['senha'])) { if (sizeof($usuario['senha']) < 6) { if (!preg_match('/^[a-z0-9]+$/i', $usuario['senha'])) { if (isset($usuario['confirma']) && !empty($usuario['confirma'])) { if ($usuario['senha'] === $usuario['confirma']) { $var['userPassword'] = $ldap->createSHA($usuario['senha']); } else { $resposta['error']['confirma'] = "Senhas digitadas são diferentes"; } } else { $resposta['error']['confirma'] = "Senha de confirmação é OBRIGATÓRIA"; } } else { $resposta['error']['senha'] = "Senha deve ter no mínimo 1 (um) caracter especial"; } } else { $resposta['error']['senha'] = "Senha deve ter no minimo 6 caracteres"; } } else { $resposta['error']['senha'] = "Senha é OBRIGATÓRIA"; } } else { $var['userPassword'] = $antigo[0]['userpassword'][0]; }
/* * ALTERACAO DE GRUPO */ /* * VALIDACAO PARA SABER SE O USUARIO TEM ACESSO AO KVM-IP */ if (isset($usuario['kvm'])) { if (!$antigo_kvm) { $alterado = true; $var['objectClass'][] = 'kn4140User'; $var['iKVM4140-userProfile'] = 'su/administrator'; } else { $var['iKVM4140-userProfile'] = 'su/administrator'; } } elseif (!isset($usuario['kvm']) && $antigo_kvm) { $alterado = true; $remove[] = 'kn4140User'; /* $delete['ikvm4140-userprofile'] = 'su/administrator'; $delete['objectclass'] = 'kn4140User'; FB::log('DELETOU O KVM DO USUARIO'); */ } /* * VERIFICACAO DE TACACS */ if (isset($usuario['tacacs'])) { if ($antigo_tacacs) { if (isset($usuario['rede']) && !empty($usuario['rede'][0])) { $var['tacacsClient'] = $usuario['rede']; } else { $var['tacacsClient'] = '150.162.248.0/24'; } if (isset($usuario['perfil']) && !empty($usuario['perfil'][0])) { if (preg_match('/^\{.*\}$/', $usuario['perfil'][0])) { $var['tacacsProfile'] = $usuario['perfil'][0]; } else { $resposta['error']['perfil'] = "Perfil inválido"; } } else { $var['tacacsProfile'] = '{ }'; } if (isset($usuario['membro']) &&
!empty($usuario['membro'][0])) { for ($i = 0; $i < sizeof($usuario['membro']); $i++) { if ($usuario['membro'][$i]) { $var['tacacsMember'][] = $usuario['membro'][$i]; } else { $resposta['error']['membro'] = "Membro com algum valor INVÁLIDO"; } } } else { $resposta['error']['membro'] = "OBRIGATÓRIO pelo menos um grupo"; } } else { $alterado = true; $var['objectClass'][] = 'tacacsAccount'; if (isset($usuario['rede']) && !empty($usuario['rede'][0])) { $var['tacacsClient'] = $usuario['rede']; } else { $var['tacacsClient'] = '150.162.248.0/24'; } if (isset($usuario['perfil']) && !empty($usuario['perfil'][0])) { if (preg_match('/^\{.*\}$/', $usuario['perfil'][0])) { $var['tacacsProfile'] = $usuario['perfil'][0]; } else { $resposta['error']['perfil'] = "Perfil inválido"; } } else { $var['tacacsProfile'] = '{ }'; } if (isset($usuario['membro']) && !empty($usuario['membro'][0])) { for ($i = 0; $i < sizeof($usuario['membro']); $i++) { if ($usuario['membro'][$i]) { $var['tacacsMember'][] = $usuario['membro'][$i]; } else { $resposta['error']['membro'] = "Membro com algum valor INVÁLIDO"; } } } else { $resposta['error']['membro'] = "OBRIGATÓRIO pelo menos um grupo"; } } } else {
if ($antigo_tacacs) { $alterado = true; $remove[] = 'tacacsAccount'; /* $rede = $antigo[0]['tacacsclient']; array_shift($rede); $membro = $antigo[0]['tacacsmember']; array_shift($membro); $delete['tacacsClient'] = $rede; $delete['tacacsMember'] = $membro; $delete['tacacsProfile'] = $antigo[0]['tacacsprofile'][0]; $delete['objectclass'] = 'tacacsAccount'; */ } } if (!isset($resposta)) { if ($usuario['grupo'] != $antigo[0]['gidnumber'][0]) { $var['gidNumber'] = $usuario['grupo']; $ldap->atualizaUsuariosGrupo('add', $var['gidNumber'], $usuario['uid']); $ldap->atualizaUsuariosGrupo('del', $antigo[0]['gidnumber'][0], $usuario['uid']); } else { $var['gidNumber'] = $antigo[0]['gidnumber'][0]; } /* * ATUALIZACAO DO GRUPO DE ACESSO AOS SERVIDORES */ if (isset($usuario['servidores'])) { //PENDENTE!!!! // //CRIAR O GRUPO QUE VAI PERMITIR O ACESSO NOS SERVIDORES E ATUALIZAR O memberUid DO GRUPO //COM O NOME DO USUARIO QUE ESTA SENDO ADICIONADO } if (isset($usuario['web_admin'])) { if (!$antigo_web) { $ldap->atualizaUsuariosGrupo('add', 'web-admin', $var['uid']); } } else { if ($antigo_web) { $ldap->atualizaUsuariosGrupo('del', 'web-admin', $antigo[0]['uid'][0]); } }
if (isset($alterado)) { for ($i = 0; $i < sizeof($var['objectClass']); $i++) { if (in_array($var['objectClass'][$i], $remove)) { unset($var['objectClass'][$i]); } } $var['objectClass'] = array_values($var['objectClass']); $db = LogController::getInstance(); if ($ldap->deleteDN($antigo[0]['cn'][0], 'usuario')) { if ($ldap->addDN($var, 'usuario')) { $db->registraEventoUsuario($_SESSION['user']['uid'], 'edit', 'ok', $var['uid']); $resposta['status'] = "ok"; $resposta['msg'] = "Usuário alterado com Sucesso"; } else { $db->registraEventoUsuario($_SESSION['user']['uid'], 'edit', 'erro', $var['uid']); $resposta['status'] = "error"; $resposta['msg'] = "Ocorreu algum ERRO"; } } else { $db->registraEventoUsuario($_SESSION['user']['uid'], 'edit', 'erro', $var['uid']); $resposta['status'] = "error"; $resposta['msg'] = "Ocorreu algum ERRO"; } } else { $db = LogController::getInstance(); if ($ldap->modificarDN($antigo[0]['dn'], $var)) { $db->registraEventoUsuario($_SESSION['user']['uid'], 'edit', 'ok', $var['uid']); $resposta['status'] = "ok"; $resposta['msg'] = "Usuário alterado com Sucesso"; } else { $db->registraEventoUsuario($_SESSION['user']['uid'], 'edit', 'erro', $var['uid']); $resposta['status'] = "error"; $resposta['msg'] = "Ocorreu algum ERRO"; } } } echo json_encode($resposta);
} else { exit(json_encode(array('status' => 'error', 'msg' => 'Não foi possível se conectar com o servidor'))); } } ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; require_once PATH_CONTROLLERS . 'LogController.php'; $erro = false; if (!empty($_REQUEST['usuario'])) { $usuario = $_REQUEST['usuario']; } else { $erro = true; $resposta['error']['usuario'] = "Usuário é OBRIGATÓRIO"; } if (empty($_POST['senha'])) { $erro = true; $resposta['error']['senha'] = "Senha é OBRIGATÓRIO"; } if (!$erro) { $ldap = LDAPController::getInstance(); $retorno = $ldap->autentica($usuario, $_POST['senha']); $resposta['status'] = "indefinido"; $db = LogController::getInstance(); if ($retorno) { $resposta['status'] = 'ok'; session_start(); $_SESSION['logado'] = true; $_SESSION['user']['uid'] = $retorno[0]['uid'][0]; $_SESSION['user']['nome'] = $retorno[0]['givenname'][0]; $_SESSION['user']['mail'] = $retorno[0]['mail'][0]; //$_SESSION['user']['pass'] = $retorno[0]['userpassword'][0]; $_SESSION['user']['dn'] = $retorno[0]['dn']; $_SESSION['user']['admin'] = isset($retorno['admin']) ? true : false; if ($_SESSION['user']['admin'] == true) { $resposta['url'] = "sistema/visao/"; } else { $resposta['url'] = "usuario/" . $retorno[0]['uid'][0] . "/editar"; }
for ($i = 0; $i < $retorno[0]['objectclass']['count']; $i++) { if ($retorno[0]['objectclass'][$i] == 'tacacsAccount') { $_SESSION['user']['tacacs']['profile'] = $retorno[0]['tacacsprofile'][0]; for ($k = 0; $k < $retorno[0]['tacacsclient']['count']; $k++) { $_SESSION['user']['tacacs']['client'][] = $retorno[0]['tacacsclient'][$k]; } for ($j = 0; $j < $retorno[0]['tacacsmember']['count']; $j++) { $_SESSION['user']['tacacs']['member'][] = $retorno[0]['tacacsmember'][$j]; } break; } } $db->registraLogin($_SESSION['user']['uid'], 'ok'); } else { $_SESSION['logado'] = false; $resposta['status'] = "error"; $resposta['msg'] = "Usuario ou Senha Inválido"; $db->registraLogin($_SESSION['user']['uid'], 'erro'); } } echo json_encode($resposta); ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; require_once PATH_CONTROLLERS . 'LogController.php'; $erro = false; if (!empty($_REQUEST['usuario'])) { $usuario = $_REQUEST['usuario']; } else { $erro = true; $resposta['error']['usuario'] = "Usuário é OBRIGATÓRIO"; } if (empty($_POST['senha'])) { $erro = true; $resposta['error']['senha'] = "Senha é OBRIGATÓRIO"; } if (!$erro) {
$ldap = LDAPController::getInstance(); $retorno = $ldap->autentica($usuario, $_POST['senha']); $resposta['status'] = "indefinido"; $db = LogController::getInstance(); if ($retorno) { $resposta['status'] = 'ok'; session_start(); $_SESSION['logado'] = true; $_SESSION['user']['uid'] = $retorno[0]['uid'][0]; $_SESSION['user']['nome'] = $retorno[0]['givenname'][0]; $_SESSION['user']['mail'] = $retorno[0]['mail'][0]; //$_SESSION['user']['pass'] = $retorno[0]['userpassword'][0]; $_SESSION['user']['dn'] = $retorno[0]['dn']; $_SESSION['user']['admin'] = isset($retorno['admin']) ? true : false; if ($_SESSION['user']['admin'] == true) { $resposta['url'] = "sistema/visao/"; } else { $resposta['url'] = "usuario/" . $retorno[0]['uid'][0] . "/editar"; } for ($i = 0; $i < $retorno[0]['objectclass']['count']; $i++) { if ($retorno[0]['objectclass'][$i] == 'tacacsAccount') { $_SESSION['user']['tacacs']['profile'] = $retorno[0]['tacacsprofile'][0]; for ($k = 0; $k < $retorno[0]['tacacsclient']['count']; $k++) { $_SESSION['user']['tacacs']['client'][] = $retorno[0]['tacacsclient'][$k]; } for ($j = 0; $j < $retorno[0]['tacacsmember']['count']; $j++) { $_SESSION['user']['tacacs']['member'][] = $retorno[0]['tacacsmember'][$j]; } break; } } $db->registraLogin($_SESSION['user']['uid'], 'ok'); } else { $_SESSION['logado'] = false; $resposta['status'] = "error"; $resposta['msg'] = "Usuario ou Senha Inválido"; $db->registraLogin($_SESSION['user']['uid'], 'erro'); } }
echo json_encode($resposta); ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; require_once PATH_CONTROLLERS . 'LogController.php'; $erro = false; if (!empty($_REQUEST['usuario'])) { $usuario = $_REQUEST['usuario']; } else { $erro = true; $resposta['error']['usuario'] = "Usuário é OBRIGATÓRIO"; } if (empty($_POST['senha'])) { $erro = true; $resposta['error']['senha'] = "Senha é OBRIGATÓRIO"; } if (!$erro) { $ldap = LDAPController::getInstance(); $retorno = $ldap->autentica($usuario, $_POST['senha']); $resposta['status'] = "indefinido"; $db = LogController::getInstance(); if ($retorno) { $resposta['status'] = 'ok'; session_start(); $_SESSION['logado'] = true; $_SESSION['user']['uid'] = $retorno[0]['uid'][0]; $_SESSION['user']['nome'] = $retorno[0]['givenname'][0]; $_SESSION['user']['mail'] = $retorno[0]['mail'][0]; //$_SESSION['user']['pass'] = $retorno[0]['userpassword'][0]; $_SESSION['user']['dn'] = $retorno[0]['dn']; $_SESSION['user']['admin'] = isset($retorno['admin']) ? true : false; if ($_SESSION['user']['admin'] == true) { $resposta['url'] = "sistema/visao/"; } else { $resposta['url'] = "usuario/" . $retorno[0]['uid'][0] . "/editar"; } for ($i = 0; $i < $retorno[0]['objectclass']['count']; $i++) { if ($retorno[0]['objectclass'][$i] == 'tacacsAccount') { $_SESSION['user']['tacacs']['profile'] =
$retorno[0]['tacacsprofile'][0]; for ($k = 0; $k < $retorno[0]['tacacsclient']['count']; $k++) { $_SESSION['user']['tacacs']['client'][] = $retorno[0]['tacacsclient'][$k]; } for ($j = 0; $j < $retorno[0]['tacacsmember']['count']; $j++) { $_SESSION['user']['tacacs']['member'][] = $retorno[0]['tacacsmember'][$j]; } break; } } $db->registraLogin($_SESSION['user']['uid'], 'ok'); } else { $_SESSION['logado'] = false; $resposta['status'] = "error"; $resposta['msg'] = "Usuario ou Senha Inválido"; $db->registraLogin($_SESSION['user']['uid'], 'erro'); } } echo json_encode($resposta); ?>
<?php require_once realpath(dirname(__FILE__) . '/../../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { //$filtro = isset($_GET['search']) ? $_GET['search'] : null; $page = isset($_GET['page']) ? $_GET['page'] : null; $limit = isset($_GET['rows']) ? $_GET['rows'] : null; $ldap = LDAPController::getInstance(); $grupos = $ldap->getValidGroups(); $count = sizeof($grupos); if ($count > 0) { $total_pages = ceil($count / $limit); } else { $total_pages = 0;
} if ($page > $total_pages) $page = $total_pages; if ($limit < 0) $limit = 0; $start = $limit * $page - $limit; if ($start < 0) $start = 0; $response = new stdClass(); $limite_tabela = $page * $limit; if ($count <= $limite_tabela) { $fim = $count; } else { $fim = $limite_tabela; } for ($i = $start; $i < $fim; $i++) { $response->rows[$i-$start]['id'] = $grupos[$i]['gid']; $response->rows[$i-$start]['cell'] = array( $grupos[$i]['cn'], '<a class="imagem editar" href="editar?g=' . $grupos[$i]['gid'] . '"></a>', '<a class="imagem excluir_generico" href="' . RAIZ_FORMS . 'delete_group?g=' . $grupos[$i]['gid'] . '"></a>' ); } echo json_encode($response); } ?> <?php require_once realpath(dirname(__FILE__) . '/../../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { //$filtro = isset($_GET['search']) ? $_GET['search'] : null; $page = isset($_GET['page']) ? $_GET['page'] : null; $limit = isset($_GET['rows']) ? $_GET['rows'] : null; $ldap = LDAPController::getInstance();
$grupos = $ldap->getValidGroups(); $count = sizeof($grupos); if ($count > 0) { $total_pages = ceil($count / $limit); } else { $total_pages = 0; } if ($page > $total_pages) $page = $total_pages; if ($limit < 0) $limit = 0; $start = $limit * $page - $limit; if ($start < 0) $start = 0; $response = new stdClass(); $limite_tabela = $page * $limit; if ($count <= $limite_tabela) { $fim = $count; } else { $fim = $limite_tabela; } for ($i = $start; $i < $fim; $i++) { $response->rows[$i-$start]['id'] = $grupos[$i]['gid']; $response->rows[$i-$start]['cell'] = array( $grupos[$i]['cn'], '<a class="imagem editar" href="editar?g=' . $grupos[$i]['gid'] . '"></a>', '<a class="imagem excluir_generico" href="' . RAIZ_FORMS . 'delete_group?g=' . $grupos[$i]['gid'] . '"></a>' ); } echo json_encode($response); } ?> <?php require_once realpath(dirname(__FILE__) . '/../../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO);
exit(); } else { //$filtro = isset($_GET['search']) ? $_GET['search'] : null; $page = isset($_GET['page']) ? $_GET['page'] : null; $limit = isset($_GET['rows']) ? $_GET['rows'] : null; $ldap = LDAPController::getInstance(); $grupos = $ldap->getValidGroups(); $count = sizeof($grupos); if ($count > 0) { $total_pages = ceil($count / $limit); } else { $total_pages = 0; } if ($page > $total_pages) $page = $total_pages; if ($limit < 0) $limit = 0; $start = $limit * $page - $limit; if ($start < 0) $start = 0; $response = new stdClass(); $limite_tabela = $page * $limit; if ($count <= $limite_tabela) { $fim = $count; } else { $fim = $limite_tabela; } for ($i = $start; $i < $fim; $i++) { $response->rows[$i-$start]['id'] = $grupos[$i]['gid']; $response->rows[$i-$start]['cell'] = array( $grupos[$i]['cn'], '<a class="imagem editar" href="editar?g=' . $grupos[$i]['gid'] . '"></a>', '<a class="imagem excluir_generico" href="' . RAIZ_FORMS . 'delete_group?g=' . $grupos[$i]['gid'] . '"></a>' ); } echo json_encode($response); } ?> <?php require_once realpath(dirname(__FILE__) . '/../../../application/includes/constants.php');
require_once PATH_CONTROLLERS . 'LDAPController.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { //$filtro = isset($_GET['search']) ? $_GET['search'] : null; $page = isset($_GET['page']) ? $_GET['page'] : null; $limit = isset($_GET['rows']) ? $_GET['rows'] : null; $ldap = LDAPController::getInstance(); $grupos = $ldap->getValidGroups(); $count = sizeof($grupos); if ($count > 0) { $total_pages = ceil($count / $limit); } else { $total_pages = 0; } if ($page > $total_pages) $page = $total_pages; if ($limit < 0) $limit = 0; $start = $limit * $page - $limit; if ($start < 0) $start = 0; $response = new stdClass(); $limite_tabela = $page * $limit; if ($count <= $limite_tabela) { $fim = $count; } else { $fim = $limite_tabela; } for ($i = $start; $i < $fim; $i++) { $response->rows[$i-$start]['id'] = $grupos[$i]['gid']; $response->rows[$i-$start]['cell'] = array( $grupos[$i]['cn'], '<a class="imagem editar" href="editar?g=' . $grupos[$i]['gid'] . '"></a>', '<a class="imagem excluir_generico" href="' . RAIZ_FORMS . 'delete_group?g=' . $grupos[$i]['gid'] . '"></a>' ); }
echo json_encode($response); } ?> <?php require_once realpath(dirname(__FILE__) . '/../../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; require_once PATH_INCLUDES . 'firephp/fb.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { $filtro = isset($_GET['search']) ? $_GET['search'] : null; $page = isset($_GET['page']) ? $_GET['page'] : null; $limit = isset($_GET['rows']) ? $_GET['rows'] : null; $ldap = LDAPController::getInstance(); if ($filtro) { $filtro = "(|(uid=*$filtro*)(mail=*$filtro*)(givenName=*$filtro*))"; } $users = $ldap->getValidUsers($filtro); $response = new stdClass(); $count = sizeof($users); if ($count > 0) { $total_pages = ceil($count / $limit); } else { $total_pages = 0; } if ($page > $total_pages) $page = $total_pages; if ($limit < 0) $limit = 0; $start = $limit * $page - $limit; if ($start < 0) $start = 0; $limite_tabela = $page * $limit; if ($count <= $limite_tabela) { $fim = $count; } else { $fim = $limite_tabela;
} for ($i = $start; $i < $fim; $i++) { $response->rows[$i-$start]['id'] = $users[$i]['uid']; $response->rows[$i-$start]['cell'] = array( $users[$i]['nome'], '<a class="imagem editar" href="editar?u=' . $users[$i]['uid'] . '"></a>', '<a class="imagem excluir_usuario" href="' . RAIZ_FORMS . 'delete_user?u=' . $users[$i]['uid'] . '"></a>' ); } $response->page = $page; $response->total = $total_pages; $response->records = $count; echo json_encode($response); } ?> <?php require_once realpath(dirname(__FILE__) . '/../../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LDAPController.php'; require_once PATH_INCLUDES . 'firephp/fb.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { $filtro = isset($_GET['search']) ? $_GET['search'] : null; $page = isset($_GET['page']) ? $_GET['page'] : null; $limit = isset($_GET['rows']) ? $_GET['rows'] : null; $ldap = LDAPController::getInstance(); if ($filtro) { $filtro = "(|(uid=*$filtro*)(mail=*$filtro*)(givenName=*$filtro*))"; } $users = $ldap->getValidUsers($filtro); $response = new stdClass(); $count = sizeof($users); if ($count > 0) { $total_pages = ceil($count / $limit); } else {
$total_pages = 0; } if ($page > $total_pages) $page = $total_pages; if ($limit < 0) $limit = 0; $start = $limit * $page - $limit; if ($start < 0) $start = 0; $limite_tabela = $page * $limit; if ($count <= $limite_tabela) { $fim = $count; } else { $fim = $limite_tabela; } for ($i = $start; $i < $fim; $i++) { $response->rows[$i-$start]['id'] = $users[$i]['uid']; $response->rows[$i-$start]['cell'] = array( $users[$i]['nome'], '<a class="imagem editar" href="editar?u=' . $users[$i]['uid'] . '"></a>', '<a class="imagem excluir_usuario" href="' . RAIZ_FORMS . 'delete_user?u=' . $users[$i]['uid'] . '"></a>' ); } $response->page = $page; $response->total = $total_pages; $response->records = $count; echo json_encode($response); } ?> <?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_INCLUDES . 'config.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { global $Config;
$retorno = shell_exec("df -h | awk '{if ($5 ~ /^\/.*/) print $4\" \"$5; else if($4 ~ /./) print $5\" \"$6;}'| grep -v \"Mounted\""); $retorno = explode("\n", $retorno); $particoes = array(); foreach ($Config['particoes'] as $particao) { foreach ($retorno as $row) { if ($particao == '/') { if (preg_match('/^.*\/$/i', $row)) { $temp = explode(' ', $row); $particoes[] = array('nome' => 'barra', 'particao' => $temp[1], 'usado' => $temp[0]); } } else { if (preg_match('/^.*' . $particao . '.*$/i', $row)) { $temp = explode(' ', $row); $particoes[] = array('nome' => $particao, 'particao' => $temp[1], 'usado' => $temp[0]); } } } } $resposta['status'] = 'ok'; $resposta['particoes'] = $particoes; $processos = array(); foreach ($Config['processos'] as $processo) { if ($processo == 'tacacs') { $pid = shell_exec('cat /var/run/tac_plus.pid'); $retorno = shell_exec('ps ax | grep -v grep | grep ' . $pid); } else { $retorno = shell_exec('ps ax | grep -v grep | grep ' . $processo); } if ($retorno) { $processos[] = array('processo' => $processo, 'status' => 'ok'); } else { $processos[] = array('processo' => $processo, 'status' => 'erro'); } } $resposta['processos'] = $processos; $retorno = shell_exec('echo "show slave status\G" | mysql -u mon --password=m0nr3plica'); preg_match('/Slave_IO_Running: +(\w+)/i', $retorno, $matches); $io_run = $matches[1];
preg_match('/Slave_SQL_Running: +(\w+)/i', $retorno, $matches); $sql_run = $matches[1]; if (strtolower($io_run) === "yes" && strtolower($sql_run) === "yes") { $replicacao = array('status' => 'ok'); } else { $replicacao = array('status' => 'erro'); } $resposta['replicacao'] = $replicacao; echo json_encode($resposta); } ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); $page = 'visao-geral'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } //else { //} include PATH_TEMPLATE . 'header.php'; ?> <div id="content"> <div id="main"> <div id="main-left"> <?php include PATH_TEMPLATE . 'menu.php'; ?> </div> <div id="main-right"> <div id="visao-left"> <fieldset id="particoes" class="rounded"> <legend>Partições</legend> </fieldset> </div> <div id="visao-right"> <fieldset id="processos" class="rounded"> <legend>Processos</legend> </fieldset> <fieldset id="replicacao" class="rounded"> <legend>Replicação MySQL</legend> </fieldset> </div>
<div class="clear"></div> </div> <div class="clear"></div> </div> </div> <script type="text/javascript"> $(document).ready(function(){ $.ajax({ url:'../getData', type: 'GET', dataType: 'json', beforeSend: function() { $('#particoes').addClass("loading_buttom"); $('#processos').addClass("loading_buttom"); $('#replicacao').addClass("loading_buttom"); }, success: function(data){ $('#particoes').removeClass('loading_buttom'); $('#processos').removeClass('loading_buttom'); $('#replicacao').removeClass('loading_buttom'); if(data.status=='ok'){ $.each(data.particoes,function(i,val){ $('#particoes').append('<div class="wrapper"><div class="label">'+val.particao+'</div><div id="'+val.nome+'" class="progressbar"><span>'+val.usado+'</span></div><div class="clear"></div>'); var valor = parseInt(val.usado.replace('\%','')); if(valor >= 60){ $('#'+val.nome+' span').addClass('font'); } $('#'+val.nome).progressbar({value:valor}); }); $.each(data.processos,function(i,val){ if(val.status == 'ok'){ $('#processos').append('<div class="wrapper"><div class="label" style="width:70px;"><img alt="OK" src="../../css/imgs/success.png" align="center"/></div><div class="processo">'+val.processo+'</div><div class="clear"></div></div>'); }else{ $('#processos').append('<div class="wrapper"><div class="label" style="width:70px;"><img alt="Falha" src="../../css/imgs/error.png" align="center"/></div><div class="processo">'+val.processo+'</div><div class="clear"></div></div>'); } }); if(data.replicacao.status == 'ok'){ $('#replicacao').append('<div class="wrapper"><div class="label" style="width:70px;"><img alt="OK" src="../../css/imgs/success.png" align="center"/></div><div
class="processo">Status da Replicação</div><div class="clear"></div></div>'); }else{ $('#replicacao').append('<div class="wrapper"><div class="label" style="width:70px;"><img alt="OK" src="../../css/imgs/error.png" align="center"/></div><div class="processo">Status da Replicação</div><div class="clear"></div></div>'); } } } }); }) </script> <?php include PATH_TEMPLATE . 'footer.php'; ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); $page = 'adicionar-equipamento'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } //else { //} include PATH_TEMPLATE . 'header.php'; ?> <div id="content"> <div id="main"> <div id="main-left"> <?php include PATH_TEMPLATE . 'menu.php'; ?> </div> <div id="main-right"> <fieldset id="adiciona-equipamento" class="rounded"> <legend>Adicionar Equipamento</legend> <form id="adicionar" action="<?php echo RAIZ_FORMS; ?>add_equipamento" method="POST"> <p> <label for="grupo">Grupo</label> <select name="grupo" id="grupo"> <option value="0">Selecione...</option> </select> </p> <p> <label for="ip">IP</label> <input type="text" name="ip" id="ip"/> </p>
<p> <label for="descricao">Descrição</label> <input type="text" name="descricao" id="descricao"/> </p> <div class="clear"></div> <p> <input type="submit" id="botao_add" value="Adicionar"/> <input type="reset" value="Limpar" id="login-limpar" style="margin-left: 20px"/> </p> </form> </fieldset> <div id="resposta"></div> </div> <div class="clear"></div> </div> </div> <script type="text/javascript" src="<?php echo URL_PUBLICO; ?>js/jquery.form.js"></script> <script type="text/javascript"> $.ajax({ url: 'getData?a=combo', type: 'GET', dataType: 'json', beforeSend: function() { },success: function(data){ if(!data.error){ var options = ''; for(var i=0;i<data.length;i++){ options += '<option value="'+data[i]+'">'+data[i]+'</option>'; } $('select#grupo').html(options); } } }); $('#ip').focusout(function(){ var pattern = /^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}(\/[0-3][0-9])?$/; if(pattern.test($(this).val())){ if($(this).next().hasClass('error_box')){ $(this).next().remove(); } }else{ if(!$(this).next().hasClass('error_box')){ $(this).after('<div class="error_box">IP inválido</div>'); }
} }); $('#descricao').focusout(function(){ var pattern = /^.{4,}$/; if(pattern.test($(this).val())){ if($(this).next().hasClass('error_box')){ $(this).next().remove(); } }else{ if(!$(this).next().hasClass('error_box')){ $(this).after('<div class="error_box">Descrição mínima de 4 letras</div>'); } } }); var options = { dataType: 'json', beforeSubmit: function() { $('.error_box').css('visibility', 'hidden'); $('#resposta').removeClass(); $('#resposta').removeAttr("style"); $('#resposta').html(""); $('#botao_add').val(""); //$('#botao_add').attr('disabled','disabled'); $('#botao_add').addClass("loading_buttom"); }, success: function(response) { $('#botao_add').val("Adicionar"); $('#botao_add').removeClass("loading_buttom"); //$('#botao_add').removeAttr('disabled'); $('.error_box').remove(); if (response.error == null) { if(response.status == 'ok') { $('#resposta').addClass("success_box"); $('#resposta').html(response.msg); $('#resposta').delay(5000).fadeOut(); $('.aplicar_tacacs').addClass('warning'); }else{ $('#resposta').addClass("errors"); $('#resposta').html(response.msg); } }else{ if (typeof(response.error.length) == 'undefined') { $('#resposta').addClass("errors"); $('#resposta').html('<span class="error">Verifique o(s) campo(s) com problema(s)</span>'); $.each(response.error, function(i, val) { if(i == 'membro'){ $('#' + i).next().after('<div class="error_box" style="width: 240px;">'+val+'</div>');
}else{ $('#' + i).after('<div class="error_box">'+val+'</div>'); } }); } else { $('#resposta').html('<span class="error">'+response.error+'</span>'); } } }, error: function(XMLHttpRequest, textStatus, errorThrown) { $('#botao_add').val("Adicionar"); $('#botao_add').removeClass("loading_buttom"); $('#resposta').addClass("errors"); //Print the error message if the request fails (possible reasons: "timeout", "error", "notmodified" and "parsererror") $('#resposta').html('<span class="error">'+XMLHttpRequest.responseText+'</span>'); } }; $("#adicionar").ajaxForm(options); </script> <?php include PATH_TEMPLATE . 'footer.php'; ?> <?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_INCLUDES . 'functions.php'; require_once PATH_INCLUDES . 'firephp/fb.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { global $Config; $action = isset($_GET['a']) ? $_GET['a'] : null; if ($action == 'combo') { $temp = array_equipamentos(); if ($temp) { foreach ($temp as $key => $value) { $var[] = $key; } } else { $var['error'] = true; } exit(json_encode($var));
} elseif ($action == 'lista') { $page = isset($_GET['page']) ? $_GET['page'] : null; $limit = isset($_GET['rows']) ? $_GET['rows'] : null; $temp = array_equipamentos(); if ($temp) { $var = new stdClass(); $count = count($temp, COUNT_RECURSIVE) - count($temp); if ($count > 0) { $total_pages = ceil($count / $limit); } else { $total_pages = 0; } if ($page > $total_pages) $page = $total_pages; if ($limit < 0) $limit = 0; $start = $limit * $page - $limit; if ($start < 0) $start = 0; $i=0; foreach ($temp as $key => $value) { for ($j = 0; $j < sizeof($value); $j++) { if ($i >= $start && $i < ($page * $limit)) { $explode = explode('#', $value[$j]); $var->rows[]['cell'] = array( $key, $explode[0], isset($explode[1]) ? $explode[1] : "", '<a class="imagem excluir_generico" href="' . RAIZ_FORMS . 'delete_equipamento?e=' . $explode[0] . '"></a>'); } $i++; if(!isset($value[$j])){ break; } } } $var->page = $page; $var->total = $total_pages; $var->records = $count; exit(json_encode($var)); } } } ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_INCLUDES . 'functions.php'; require_once PATH_INCLUDES . 'firephp/fb.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado'] && !$_SESSION['user']['admin']) { header('Location:' . URL_PUBLICO); exit(); } else { global $Config; $action = isset($_GET['a']) ? $_GET['a'] : null; if ($action == 'combo') { $temp = array_equipamentos(); if ($temp) { foreach ($temp as $key => $value) { $var[] = $key; } } else { $var['error'] = true; } exit(json_encode($var)); } elseif ($action == 'lista') { $page = isset($_GET['page']) ? $_GET['page'] : null; $limit = isset($_GET['rows']) ? $_GET['rows'] : null; $temp = array_equipamentos(); if ($temp) { $var = new stdClass(); $count = count($temp, COUNT_RECURSIVE) - count($temp); if ($count > 0) { $total_pages = ceil($count / $limit); } else { $total_pages = 0; } if ($page > $total_pages) $page = $total_pages; if ($limit < 0) $limit = 0; $start = $limit * $page - $limit; if ($start < 0) $start = 0;
$i=0; foreach ($temp as $key => $value) { for ($j = 0; $j < sizeof($value); $j++) { if ($i >= $start && $i < ($page * $limit)) { $explode = explode('#', $value[$j]); $var->rows[]['cell'] = array( $key, $explode[0], isset($explode[1]) ? $explode[1] : "", '<a class="imagem excluir_generico" href="' . RAIZ_FORMS . 'delete_equipamento?e=' . $explode[0] . '"></a>'); } $i++; if(!isset($value[$j])){ break; } } } $var->page = $page; $var->total = $total_pages; $var->records = $count; exit(json_encode($var)); } } } ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LogController.php'; require_once PATH_INCLUDES . 'firephp/fb.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado']) { header('Location:' . URL_PUBLICO); exit(); } elseif ($_SESSION['user']['uid'] != $_GET['u']) { $response = new stdClass(); $response->error = 'Dados inválidos'; exit(json_encode($response)); } else { $filtro = isset($_GET['search']) ? $_GET['search'] : null; $nas = isset($_GET['nas']) ? $_GET['nas'] : null; //usuário vem do campo hidden $usuario = isset($_GET['u']) ? $_GET['u'] : null;
$data_inicio = isset($_REQUEST['data_inicio']) ? $_REQUEST['data_inicio'] : null; $data_fim = isset($_REQUEST['data_fim']) ? $_REQUEST['data_fim'] : null; $page = isset($_GET['page']) ? $_GET['page'] : null; $limit = isset($_GET['rows']) ? $_GET['rows'] : null; $whereclause = ""; if ($data_inicio) { if (dataValida($data_inicio)) { $temp = explode("/", $data_inicio); $data_inicio = $temp[2] . "-" . $temp[1] . "-" . $temp[0]; if (strlen($whereclause) == 0) { $whereclause.=sprintf(" data >= '%s'", $data_inicio); } else { $whereclause.=sprintf(" AND data >= '%s'", $data_inicio); } } else { $fields["data_inicio"] = "Início inválido"; } } if ($data_fim) { if (dataValida($data_fim)) { $temp = explode("/", $data_fim); $data_fim = $temp[2] . "-" . $temp[1] . "-" . $temp[0]; if (strlen($whereclause) == 0) { $whereclause.=sprintf(" data <= '%s'", $data_fim); } else { $whereclause.=sprintf(" AND data <= '%s 23:59:59'", $data_fim); } } else { $fields["data_fim"] = "Final inválido"; } } if ($filtro && !preg_match('/^\s*$/', $filtro)) { if (strlen($whereclause) == 0) { $whereclause.= " command LIKE '%$filtro%'"; } else { $whereclause.=" AND command LIKE '%$filtro%'"; } } if ($nas) { if (preg_match('/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/', $nas)) { if (strlen($whereclause) == 0) {
$whereclause.= " NAS = '$nas'"; } else { $whereclause.=" AND NAS = '$nas'"; } } else { $fields["nas"] = "IP inválido"; } } if ($usuario) { if (strlen($whereclause) == 0) { $whereclause.= " user = '$usuario'"; } else { $whereclause.=" AND user = '$usuario'"; } } $query = "SELECT COUNT(id) AS count FROM authorization " . ((strlen($whereclause) == 0) ? "" : "WHERE ") . $whereclause . ";"; $db = LogController::getInstance(); $result = $db->consultaLogs($query); unset($query); $row = $result->fetch_array(MYSQLI_ASSOC); $count = $row['count']; if ($count > 0) { $total_pages = ceil($count / $limit); } else { $total_pages = 0; } if ($page > $total_pages) $page = $total_pages; if ($limit < 0) $limit = 0; $start = $limit * $page - $limit; if ($start < 0) $start = 0; $query = "SELECT data,NAS,command FROM authorization " . ((strlen($whereclause) == 0) ? "" : "WHERE ") . $whereclause . " ORDER BY data DESC LIMIT " . $start . ", " . $limit; $result = $db->consultaLogs($query); $response = new stdClass(); $response->page = $page; $response->total = $total_pages; $response->records = $count;
$response->fields = $fields; $i = 0; while ($row = $result->fetch_array(MYSQLI_ASSOC)) { $data = $row['data']; $data = strtotime($data); $data = date('d/m/Y H:i:s', $data); $dado = trim($row['command']); if (preg_match('/^permit/i', $dado)) { $dado = preg_replace('/^permit/i', '<strong><span style="color:green">permit</span></strong>', $dado); } else { $dado = preg_replace('/^deny/i', '<strong><span style="color:red">deny</span></strong>', $dado); } if (preg_match('/Group-Async/', $dado)) { $dado = preg_replace('/Group-Async /', '', $dado); } $response->rows[$i]['cell'] = array("<strong>" . $data . "</strong>", $row['NAS'], $dado); $i++; } exit(json_encode($response)); } ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); require_once PATH_CONTROLLERS . 'LogController.php'; require_once PATH_INCLUDES . 'firephp/fb.php'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado']) { header('Location:' . URL_PUBLICO); exit(); } elseif ($_SESSION['user']['uid'] != $_GET['u']) { $response = new stdClass(); $response->error = 'Dados inválidos'; exit(json_encode($response)); } else { $filtro = isset($_GET['search']) ? $_GET['search'] : null; $nas = isset($_GET['nas']) ? $_GET['nas'] : null; //usuário vem do campo hidden $usuario = isset($_GET['u']) ? $_GET['u'] : null; $data_inicio = isset($_REQUEST['data_inicio']) ? $_REQUEST['data_inicio'] : null;
$data_fim = isset($_REQUEST['data_fim']) ? $_REQUEST['data_fim'] : null; $page = isset($_GET['page']) ? $_GET['page'] : null; $limit = isset($_GET['rows']) ? $_GET['rows'] : null; $whereclause = ""; if ($data_inicio) { if (dataValida($data_inicio)) { $temp = explode("/", $data_inicio); $data_inicio = $temp[2] . "-" . $temp[1] . "-" . $temp[0]; if (strlen($whereclause) == 0) { $whereclause.=sprintf(" data >= '%s'", $data_inicio); } else { $whereclause.=sprintf(" AND data >= '%s'", $data_inicio); } } else { $fields["data_inicio"] = "Início inválido"; } } if ($data_fim) { if (dataValida($data_fim)) { $temp = explode("/", $data_fim); $data_fim = $temp[2] . "-" . $temp[1] . "-" . $temp[0]; if (strlen($whereclause) == 0) { $whereclause.=sprintf(" data <= '%s'", $data_fim); } else { $whereclause.=sprintf(" AND data <= '%s 23:59:59'", $data_fim); } } else { $fields["data_fim"] = "Final inválido"; } } if ($filtro && !preg_match('/^\s*$/', $filtro)) { if (strlen($whereclause) == 0) { $whereclause.= " command LIKE '%$filtro%'"; } else { $whereclause.=" AND command LIKE '%$filtro%'"; } } if ($nas) { if (preg_match('/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/', $nas)) { if (strlen($whereclause) == 0) { $whereclause.= " NAS = '$nas'"; } else { $whereclause.=" AND NAS = '$nas'";
} } else { $fields["nas"] = "IP inválido"; } } if ($usuario) { if (strlen($whereclause) == 0) { $whereclause.= " user = '$usuario'"; } else { $whereclause.=" AND user = '$usuario'"; } } $query = "SELECT COUNT(id) AS count FROM authorization " . ((strlen($whereclause) == 0) ? "" : "WHERE ") . $whereclause . ";"; $db = LogController::getInstance(); $result = $db->consultaLogs($query); unset($query); $row = $result->fetch_array(MYSQLI_ASSOC); $count = $row['count']; if ($count > 0) { $total_pages = ceil($count / $limit); } else { $total_pages = 0; } if ($page > $total_pages) $page = $total_pages; if ($limit < 0) $limit = 0; $start = $limit * $page - $limit; if ($start < 0) $start = 0; $query = "SELECT data,NAS,command FROM authorization " . ((strlen($whereclause) == 0) ? "" : "WHERE ") . $whereclause . " ORDER BY data DESC LIMIT " . $start . ", " . $limit; $result = $db->consultaLogs($query); $response = new stdClass(); $response->page = $page; $response->total = $total_pages; $response->records = $count; $response->fields = $fields; $i = 0; while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
$data = $row['data']; $data = strtotime($data); $data = date('d/m/Y H:i:s', $data); $dado = trim($row['command']); if (preg_match('/^permit/i', $dado)) { $dado = preg_replace('/^permit/i', '<strong><span style="color:green">permit</span></strong>', $dado); } else { $dado = preg_replace('/^deny/i', '<strong><span style="color:red">deny</span></strong>', $dado); } if (preg_match('/Group-Async/', $dado)) { $dado = preg_replace('/Group-Async /', '', $dado); } $response->rows[$i]['cell'] = array("<strong>" . $data . "</strong>", $row['NAS'], $dado); $i++; } exit(json_encode($response)); } ?>
<?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); $page = 'permissoes'; session_start(); setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado']) { header('Location:' . URL_PUBLICO); exit(); } //else { //die(var_dump($_SESSION['user']['tacacs'])); //} include PATH_TEMPLATE . 'header.php'; ?> <div id="content"> <div id="main"> <div id="main-left"> <?php include PATH_TEMPLATE . 'menu.php'; ?> </div> <div id="main-right"> <?php if (isset($_SESSION['user']['tacacs'])): ?> <fieldset id="permissoes" class="rounded">
<legend>Tacacs +</legend> <?php if (isset($_SESSION['user']['tacacs']['client'])): ?> <p> <label for="acesso">Rede de acesso: </label><br/> <?php for ($i = 0; $i < sizeof($_SESSION['user']['tacacs']['client']); $i++): ?> <span><?php echo $_SESSION['user']['tacacs']['client'][$i] ?></span><br/> <?php endfor; ?> </p><br/> <?php endif; if (isset($_SESSION['user']['tacacs']['profile']) && !preg_match("/^\{ *\}/", $_SESSION['user']['tacacs']['profile'])): ?> <p> <label for="perfil">Perfil: </label><br/> <span id="perfil" name="perl"><?php echo $_SESSION['user']['tacacs']['profile']; ?></span> </p><br/> <?php endif; if (isset($_SESSION['user']['tacacs']['member'])): ?> <p> <label>Membro: </label><br/> <?php for ($i = 0; $i < sizeof($_SESSION['user']['tacacs']['member']); $i++): ?> <span><?php echo $_SESSION['user']['tacacs']['member'][$i] ?></span><br/> <?php endfor; ?> </p> <?php endif; ?> </fieldset> <?php endif; ?> </div> <div class="clear"></div> </div> </div> <script type="text/javascript"> $(document).ready(function(){ }) </script> <?php include PATH_TEMPLATE . 'footer.php'; ?> <?php require_once realpath(dirname(__FILE__) . '/../../application/includes/constants.php'); $page = 'permissoes'; session_start();
setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], time() + 300); if (!$_SESSION['logado']) { header('Location:' . URL_PUBLICO); exit(); } //else { //die(var_dump($_SESSION['user']['tacacs'])); //} include PATH_TEMPLATE . 'header.php'; ?> <div id="content"> <div id="main"> <div id="main-left"> <?php include PATH_TEMPLATE . 'menu.php'; ?> </div> <div id="main-right"> <?php if (isset($_SESSION['user']['tacacs'])): ?> <fieldset id="permissoes" class="rounded"> <legend>Tacacs +</legend> <?php if (isset($_SESSION['user']['tacacs']['client'])): ?> <p> <label for="acesso">Rede de acesso: </label><br/> <?php for ($i = 0; $i < sizeof($_SESSION['user']['tacacs']['client']); $i++): ?> <span><?php echo $_SESSION['user']['tacacs']['client'][$i] ?></span><br/> <?php endfor; ?> </p><br/> <?php endif; if (isset($_SESSION['user']['tacacs']['profile']) && !preg_match("/^\{ *\}/", $_SESSION['user']['tacacs']['profile'])): ?> <p> <label for="perfil">Perfil: </label><br/> <span id="perfil" name="perl"><?php echo $_SESSION['user']['tacacs']['profile']; ?></span> </p><br/> <?php endif; if (isset($_SESSION['user']['tacacs']['member'])): ?> <p> <label>Membro: </label><br/> <?php for ($i = 0; $i < sizeof($_SESSION['user']['tacacs']['member']); $i++): ?> <span><?php echo $_SESSION['user']['tacacs']['member'][$i] ?></span><br/> <?php endfor; ?>
</p> <?php endif; ?> </fieldset> <?php endif; ?> </div> <div class="clear"></div> </div> </div> <script type="text/javascript"> $(document).ready(function(){ }) </script> <?php include PATH_TEMPLATE . 'footer.php'; ?> <?php require_once realpath(dirname(__FILE__) . '/../application/includes/constants.php'); include PATH_TEMPLATE . 'header.php'; ?> <div id="content"> <div id="main"> <div id="login-wrapper"> <form id="login" action="forms/login" method="POST"> <p> <label for="usuario">Usuário</label> <input id="usuario" name="usuario" type="text"/> </p> <p> <label for="senha">Senha</label> <input type="password" id="senha" name="senha"/> </p> <p> <input type="submit" id="login-submit" value="Login"/> <input type="reset" value="Limpar" id="login-limpar"/> </p> </form> </div> <div id="resposta"></div> </div> </div> <script type="text/javascript" src="js/jquery.form.js"></script> <script type="text/javascript"> $(document).ready(function(){ var options = { dataType: 'json', beforeSubmit: function() { $('.error_box').css('visibility', 'hidden'); $('#resposta').removeClass(); $('#resposta').html(""); $('#login-submit').val(" "); $('#login-submit').addClass("loading_buttom"); },
success: function(response) { $('#login-submit').val("Login"); $('#login-submit').removeClass("loading_buttom"); $('.error_box').remove(); if (response.error == null) { if(response.status == 'ok') { window.location=response.url; }else{ $('#resposta').addClass("errors"); $('#resposta').html(response.msg); } }else{ if (typeof(response.error.length) == 'undefined') { $('#resposta').addClass("errors"); $('#resposta').html('<span class="error">Verifique o(s) campo(s) com problema(s)</span>'); $.each(response.error, function(i, val) { $('#' + i).after('<div class="error_box login">'+val+'</div>'); }); } else { $('#resposta').html('<span class="error">'+response.error+'</span>'); } } }, error: function(XMLHttpRequest, textStatus, errorThrown) { $('#login-submit').val("Login"); $('#login-submit').removeClass("loading_buttom"); $('#resposta').addClass("errors"); //Print the error message if the request fails (possible reasons: "timeout", "error", "notmodified" and "parsererror") if(textStatus == 'error'){ $('#resposta').html('<span class="error">'+errorThrown+'</span>'); }else if(textStatus == 'parsererror'){ $('#resposta').html('<span class="error">'+XMLHttpRequest.responseText+'</span>'); } } }; $("#login").ajaxForm(options); }); </script> <?php include PATH_TEMPLATE . 'footer.php'; ?> <?php require_once realpath(dirname(__FILE__) . '/../application/includes/constants.php'); require_once PATH_CONTROLLERS.'LogController.php';
session_start(); if (!$_SESSION['logado']) { header('Location:' . URL_PUBLICO); exit(); } else { $db = LogController::getInstance(); $db->registraLogout($_SESSION['user']['uid']); unset($_SESSION); session_unset(); session_destroy(); header('Location: ' . URL_PUBLICO); } ?>
Aplicação de Acompanhamento de Logs
<?php require_once dirname(__FILE__) . '/../includes/DB.php'; /* * To change this template, choose Tools | Templates * and open the template in the editor. */ /** * Description of LogController * * @author luis */ class LogController { protected $db; protected static $instance; public static function getInstance() { if (!self::$instance) { self::$instance = new LogController(); } return self::$instance; } function __construct() { $this->db = DB::getInstance(); } function consulta($query) { if ($query) { try { $result = $this->db->query($query); $this->db->disconnect();
return $result; } catch (Exception $e) { echo($e->getMessage()); } } } function getUsers() { $query = "SELECT DISTINCT user FROM authorization ORDER BY user"; try { $result = $this->db->query($query); $this->db->disconnect(); return $result; } catch (Exception $e) { echo $e->getMessage(); } } function getAllNAS() { $query = "SELECT DISTINCT NAS FROM authorization ORDER BY NAS"; try { $result = $this->db->query($query); $this->db->disconnect(); return $result; } catch (Exception $e) { echo $e->getMessage(); } } } ?>
<?php $Config['mysql_ip'] = "localhost"; $Config['mysql_usuario'] = "xxx"; $Config['mysql_senha'] = "xxx"; $Config['mysql_base'] = "xxxx"; ?>
<?php define('APP_PATH', realpath(dirname(__FILE__) . '/../')); define('RAIZ_INCLUDES', APP_PATH.'/includes/'); ?> <?php require_once(dirname(__FILE__) . '/config.php'); class DB {
private $connection; private $host; private $user; private $password; private $database; private static $instance; public static function getInstance() { if (!self::$instance) { self::$instance = new DB(); } return self::$instance; } private function __construct() { global $Config; $this->host = $Config['mysql_ip']; $this->user = $Config['mysql_usuario']; $this->password = $Config['mysql_senha']; $this->database = $Config['mysql_base']; } public function __destruct() { $this->disconnect(); } public function connect() { if (!$this->connection = new mysqli($this->host, $this->user, $this->password,$this->database)) { throw new Exception("MySQL Connect: " . mysqli_error()); } } public function disconnect() { if (is_resource($this->connection)) { $this->connection->close(); } } public function query($query) { if (!is_resource($this->connection)) $this->connect(); if (!$result = $this->connection->query($query)) { throw new Exception("MySQL Query: " . mysqli_error()); } return $result; } public function parseResult($result){
} } ?>
<?php function dataValida($data) { if (preg_match("/^(\d{2})\/(\d{2})\/(\d{4})$/", $data, $matches)) { if (checkdate($matches[2], $matches[1], $matches[3])) { return true; } } return false; } function anti_injection($dado) { //Remove palavras que contenham sintaxe SQL: $dado = preg_replace("/(from|select|update|insert|delete|where|union|drop table|show tables|--|\\\\)/i","",$dado); $dado = trim($dado); //Limpa espaços vazio no início e fim da string $dado = strip_tags($dado); //Remove tags HTML e PHP $dado = addslashes($dado); //Adiciona barras invertidas a uma string return $dado; } ?>
<?php require_once realpath(dirname(__FILE__) . '/../application/includes/constants.php'); require_once APP_PATH . '/controllers/LogController.php'; //require_once APP_PATH . '/controllers/LDAPController.php'; require_once APP_PATH . '/includes/functions.php'; $tipo = isset($_REQUEST['type']) ? $_REQUEST['type'] : null; $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null; $userFilter = anti_injection(isset($_REQUEST['user_filter']) ? $_REQUEST['user_filter'] : null); $nasFilter = anti_injection(isset($_REQUEST['nas_filter']) ? $_REQUEST['nas_filter'] : null); $data_inicio = anti_injection(isset($_REQUEST['data_inicio']) ? $_REQUEST['data_inicio'] : null); $data_fim = anti_injection(isset($_REQUEST['data_fim']) ? $_REQUEST['data_fim'] : null); $ordenacao = anti_injection(isset($_REQUEST['ordem']) ? $_REQUEST['ordem'] : null); $comando = anti_injection(isset($_REQUEST['comando']) ? $_REQUEST['comando'] : null);
$status = anti_injection(isset($_REQUEST['status']) ? $_REQUEST['status'] : null); $page = isset($_GET['page']) ? $_GET['page'] : null; $limit = isset($_GET['rows']) ? $_GET['rows'] : null; if (isset($action) && $action == "show" && $userFilter) { $log = new LogController(); $whereclause = ""; if ($userFilter != "todos" && $userFilter) { $whereclause.=sprintf("user = '%s'", $userFilter); } if ($nasFilter != "todos" && $nasFilter) { if (strlen($whereclause) == 0) { $whereclause.=sprintf(" nas = '%s' ", $nasFilter); } else { $whereclause.=sprintf(" AND nas = '%s' ", $nasFilter); } } $data_inicio = str_replace("__/__/____", "", $data_inicio); if ($data_inicio) { if (dataValida($data_inicio)) { $temp = explode("/", $data_inicio); $data_inicio = $temp[2] . "-" . $temp[1] . "-" . $temp[0]; if (strlen($whereclause) == 0) { $whereclause.=sprintf(" data >= '%s'", $data_inicio); } else { $whereclause.=sprintf(" AND data >= '%s'", $data_inicio); } } else { $fields["data_inicio"] = "Início inválido"; } } $data_fim = str_replace("__/__/____", "", $data_fim); if ($data_fim) { if (dataValida($data_fim)) { $temp = explode("/", $data_fim); $data_fim = $temp[2] . "-" . $temp[1] . "-" . $temp[0]; if (strlen($whereclause) == 0) { $whereclause.=sprintf(" data <= '%s'", $data_fim); } else { $whereclause.=sprintf(" AND data <= '%s 23:59:59'", $data_fim); } } else { $fields["data_fim"] = "Final inválido"; } } if (!isset($fields)) { $query = "";
if ($tipo == 'auth') { if ($comando) { if (strlen($whereclause) == 0) { $whereclause.= " command LIKE '%$comando%'"; } else { $whereclause.=" AND command LIKE '%$comando%'"; } } $query = "SELECT COUNT(id) AS count FROM authorization " . ((strlen($whereclause) == 0) ? "" : "WHERE ") . $whereclause . ";"; } elseif ($tipo == 'access') { if ($status && $status != 'todos') { if (strlen($whereclause) == 0) { $whereclause.= " status LIKE '%$status%'"; } else { $whereclause.=" AND status LIKE '%$status%'"; } } $query = "SELECT COUNT(id) AS count FROM access " . ((strlen($whereclause) == 0) ? "" : "WHERE ") . $whereclause . ";"; } $result = $log->consulta($query); unset($query); $row = $result->fetch_array(MYSQLI_ASSOC); $count = $row['count']; if ($count > 0) { $total_pages = ceil($count / $limit); } else { $total_pages = 0; } if ($page > $total_pages) $page = $total_pages; if ($limit < 0) $limit = 0; $start = $limit * $page - $limit; if ($start < 0) $start = 0; $query = ""; if ($tipo == 'auth') { $query = "SELECT data, NAS, user,user_ip,command FROM authorization " . ((strlen($whereclause) == 0) ? "" : "WHERE ") . $whereclause . " ORDER BY data " . $ordenacao . " LIMIT " . $start . ", " . $limit; } elseif ($tipo == 'access') {
$query = "SELECT data, NAS, user,user_ip,status FROM access " . ((strlen($whereclause) == 0) ? "" : "WHERE ") . $whereclause . " ORDER BY data " . $ordenacao . " LIMIT " . $start . ", " . $limit; } else { header("HTTP/1.0 404 Not Found"); header("Status: 404 Not Found"); header('Location: errors/404.html'); die("Ação não suportada !"); } //die(var_dump($query)); $result = $log->consulta($query); $response = new stdClass(); $response->page = $page; $response->total = $total_pages; $response->records = $count; $i = 0; while ($row = $result->fetch_array(MYSQLI_ASSOC)) { $data = $row['data']; $data = strtotime($data); $data = date('d/m/Y H:i:s', $data); if (isset($row['command'])) { $dado = trim($row['command']); if (preg_match('/^permit/i', $dado)) { $dado = preg_replace('/^permit/i', '<strong><span style="color:green">permit</span></strong>', $dado); } else { //$comando = '<strong><span style="color:red">' . $comando . '</span></strong>'; $dado = preg_replace('/^deny/i', '<strong><span style="color:red">deny</span></strong>', $dado); } if (preg_match('/Group-Async/', $dado)) { $dado = preg_replace('/Group-Async /', '', $dado); } } elseif (isset($row['status'])) { $dado = trim($row['status']); if (preg_match('/^succeeded/i', $dado)) { $dado = '<span style="color:green">Logado com sucesso</span>'; } elseif (preg_match('/^failed/i', $dado)) { if (preg_match('/user/i', $dado)) { $dado = '<span style="color:red">Usuário não encontrado</span>'; } else { $dado = '<span style="color:red">Credenciais inválidas (Usuário e/ou senha incorretos)</span>'; }
} elseif (preg_match('/^denied/i', $dado)) { if (preg_match('/acl/i', $dado)) { $dado = '<span style="color:red">Acesso negado por ACL</span>'; } } elseif (preg_match('/^HTTP/', $dado)) { if (preg_match('/succeeded/', $dado)) { $dado = '<span style="color:green">Logado com sucesso (WEB)</span>'; } else if (preg_match('/failed/', $dado)) { $dado = '<span style="color:red">Login falhou (WEB)</span>'; } } } $response->rows[$i]['cell'] = array("<strong>" . $data . "</strong>", $row['NAS'], $row['user'], $row['user_ip'], $dado); $i++; } } else { $response->fields = $fields; } echo json_encode($response); } else { header("HTTP/1.0 404 Not Found"); header("Status: 404 Not Found"); header('Location: errors/404.html'); die("Ação não suportada !"); } ?>
<?php require_once realpath(dirname(__FILE__) . '/../application/includes/constants.php'); require_once APP_PATH . '/controllers/LogController.php'; //require_once APP_PATH . '/controllers/LDAPController.php'; require_once APP_PATH . '/includes/functions.php'; $tipo = isset($_REQUEST['type']) ? $_REQUEST['type'] : null; $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null; $userFilter = anti_injection(isset($_REQUEST['user_filter']) ? $_REQUEST['user_filter'] : null); $nasFilter = anti_injection(isset($_REQUEST['nas_filter']) ? $_REQUEST['nas_filter'] : null); $data_inicio = anti_injection(isset($_REQUEST['data_inicio']) ? $_REQUEST['data_inicio'] : null); $data_fim = anti_injection(isset($_REQUEST['data_fim']) ? $_REQUEST['data_fim'] : null); $ordenacao = anti_injection(isset($_REQUEST['ordem']) ? $_REQUEST['ordem']
: null); $comando = anti_injection(isset($_REQUEST['comando']) ? $_REQUEST['comando'] : null); $status = anti_injection(isset($_REQUEST['status']) ? $_REQUEST['status'] : null); $page = isset($_GET['page']) ? $_GET['page'] : null; $limit = isset($_GET['rows']) ? $_GET['rows'] : null; if (isset($action) && $action == "show" && $userFilter) { $log = new LogController(); $whereclause = ""; if ($userFilter != "todos" && $userFilter) { $whereclause.=sprintf("user = '%s'", $userFilter); } if ($nasFilter != "todos" && $nasFilter) { if (strlen($whereclause) == 0) { $whereclause.=sprintf(" nas = '%s' ", $nasFilter); } else { $whereclause.=sprintf(" AND nas = '%s' ", $nasFilter); } } $data_inicio = str_replace("__/__/____", "", $data_inicio); if ($data_inicio) { if (dataValida($data_inicio)) { $temp = explode("/", $data_inicio); $data_inicio = $temp[2] . "-" . $temp[1] . "-" . $temp[0]; if (strlen($whereclause) == 0) { $whereclause.=sprintf(" data >= '%s'", $data_inicio); } else { $whereclause.=sprintf(" AND data >= '%s'", $data_inicio); } } else { $fields["data_inicio"] = "Início inválido"; } } $data_fim = str_replace("__/__/____", "", $data_fim); if ($data_fim) { if (dataValida($data_fim)) { $temp = explode("/", $data_fim); $data_fim = $temp[2] . "-" . $temp[1] . "-" . $temp[0]; if (strlen($whereclause) == 0) { $whereclause.=sprintf(" data <= '%s'", $data_fim); } else { $whereclause.=sprintf(" AND data <= '%s 23:59:59'", $data_fim); } } else { $fields["data_fim"] = "Final inválido"; } }
if (!isset($fields)) { $query = ""; if ($tipo == 'auth') { if ($comando) { if (strlen($whereclause) == 0) { $whereclause.= " command LIKE '%$comando%'"; } else { $whereclause.=" AND command LIKE '%$comando%'"; } } $query = "SELECT COUNT(id) AS count FROM authorization " . ((strlen($whereclause) == 0) ? "" : "WHERE ") . $whereclause . ";"; } elseif ($tipo == 'access') { if ($status && $status != 'todos') { if (strlen($whereclause) == 0) { $whereclause.= " status LIKE '%$status%'"; } else { $whereclause.=" AND status LIKE '%$status%'"; } } $query = "SELECT COUNT(id) AS count FROM access " . ((strlen($whereclause) == 0) ? "" : "WHERE ") . $whereclause . ";"; } $result = $log->consulta($query); unset($query); $row = $result->fetch_array(MYSQLI_ASSOC); $count = $row['count']; if ($count > 0) { $total_pages = ceil($count / $limit); } else { $total_pages = 0; } if ($page > $total_pages) $page = $total_pages; if ($limit < 0) $limit = 0; $start = $limit * $page - $limit; if ($start < 0) $start = 0; $query = ""; if ($tipo == 'auth') { $query = "SELECT data, NAS, user,user_ip,command FROM authorization " . ((strlen($whereclause) == 0) ? "" : "WHERE ") . $whereclause .
" ORDER BY data " . $ordenacao . " LIMIT " . $start . ", " . $limit; } elseif ($tipo == 'access') { $query = "SELECT data, NAS, user,user_ip,status FROM access " . ((strlen($whereclause) == 0) ? "" : "WHERE ") . $whereclause . " ORDER BY data " . $ordenacao . " LIMIT " . $start . ", " . $limit; } else { header("HTTP/1.0 404 Not Found"); header("Status: 404 Not Found"); header('Location: errors/404.html'); die("Ação não suportada !"); } //die(var_dump($query)); $result = $log->consulta($query); $response = new stdClass(); $response->page = $page; $response->total = $total_pages; $response->records = $count; $i = 0; while ($row = $result->fetch_array(MYSQLI_ASSOC)) { $data = $row['data']; $data = strtotime($data); $data = date('d/m/Y H:i:s', $data); if (isset($row['command'])) { $dado = trim($row['command']); if (preg_match('/^permit/i', $dado)) { $dado = preg_replace('/^permit/i', '<strong><span style="color:green">permit</span></strong>', $dado); } else { //$comando = '<strong><span style="color:red">' . $comando . '</span></strong>'; $dado = preg_replace('/^deny/i', '<strong><span style="color:red">deny</span></strong>', $dado); } if (preg_match('/Group-Async/', $dado)) { $dado = preg_replace('/Group-Async /', '', $dado); } } elseif (isset($row['status'])) { $dado = trim($row['status']); if (preg_match('/^succeeded/i', $dado)) { $dado = '<span style="color:green">Logado com sucesso</span>'; } elseif (preg_match('/^failed/i', $dado)) { if (preg_match('/user/i', $dado)) { $dado = '<span style="color:red">Usuário não encontrado</span>'; } else {
$dado = '<span style="color:red">Credenciais inválidas (Usuário e/ou senha incorretos)</span>'; } } elseif (preg_match('/^denied/i', $dado)) { if (preg_match('/acl/i', $dado)) { $dado = '<span style="color:red">Acesso negado por ACL</span>'; } } elseif (preg_match('/^HTTP/', $dado)) { if (preg_match('/succeeded/', $dado)) { $dado = '<span style="color:green">Logado com sucesso (WEB)</span>'; } else if (preg_match('/failed/', $dado)) { $dado = '<span style="color:red">Login falhou (WEB)</span>'; } } } $response->rows[$i]['cell'] = array("<strong>" . $data . "</strong>", $row['NAS'], $row['user'], $row['user_ip'], $dado); $i++; } } else { $response->fields = $fields; } echo json_encode($response); } else { header("HTTP/1.0 404 Not Found"); header("Status: 404 Not Found"); header('Location: errors/404.html'); die("Ação não suportada !"); } ?>
#!/bin/bash CONF=/usr/local/etc/tac_plus.cfg CONF_NEW=/etc/tacacs/tac_plus.cfg.compare if [ ! -f $CONF_NEW ] then touch $CONF_NEW fi MD5_CONF=`md5sum $CONF | awk '{print $1}'` MD5_CONF_NEW=`md5sum $CONF_NEW | awk '{print $1}'` if [ "$MD5_CONF" != "$MD5_CONF_NEW" ] ; then /etc/init.d/tac_plus stop /bin/sleep 2
/etc/init.d/tac_plus start /bin/sleep 2 /bin/cp -p $CONF $CONF_NEW fi
#!/usr/bin/perl -w use DBI; use File::Tail; use Data::Dumper; $file=File::Tail->new(name=>"/var/log/tac_plus/access.log", maxinterval=>10,interval=>5); my $dbip="localhost"; my $dbname="xxx"; my $user="xxx"; my $pass="xxx"; while (defined($line=$file->read)) { if($line){ #quebrar a string pelos tabs(\t) e colocar em um array my @array = split("\t",$line); #quebra a posicao 0 do array para tirar o timezone. Entrada: 04/08/2011 14:35:31 -0300 | Saida: 04/08/2011 14:35:31 my @data = split(" ",$array[0]); $data = $data[0]." ".$data[1]; $array[1] =~ s/(: )|(' )|( ')/ /g; @temp = split(" +",$array[1]); my $status = ""; my $aux = 7; my $vty = "vty0"; if(defined($temp[7]) && $temp[7] !~ m/(succeeded|failed)/i){ $aux = 9; $vty = $temp[8]; } for($i=$aux; $i < @temp ;$i++){ $status .= $temp[$i]." "; } #$data = Data e Hora do Evento #$temp[0] = NAS #$temp[4] = USERNAME #$array[6] = USER IP #$array[8] = Terminal #$status = Se conseguiu logar ou nao if(defined($temp[6]) && $temp[6] =~ m/^\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b$/){ my $dbh = DBI-
>connect("dbi:mysql:$dbname:$dbip;mysql_connect_timeout=86400",$user,$pass) or die "Erro na conexao: $DBI::errstr\n"; my $sql_insert = "INSERT INTO access (data,NAS,user,terminal,user_ip,status) VALUES ('$data','$temp[0]','$temp[4]','$vty','$temp[6]','$status')"; #print $sql_insert; $dbh->do($sql_insert); $dbh->disconnect; } } } #!/usr/bin/perl -w use DBI; use File::Tail; $file=File::Tail->new(name=>"/var/log/tac_plus/authorization.log", maxinterval=>10,interval=>5); my $dbip="localhost"; my $dbname="xxx"; my $user="xxx"; my $pass="xxx "; while (defined($line=$file->read)) { if($line){ #quebrar a string pelos tabs(\t) e colocar em um array my @array = split("\t",$line); #quebra a posicao 0 do array para tirar o timezone. Entrada: 04/08/2011 14:35:31 -0300 | Saida: 04/08/2011 14:35:31 my @data = split(" ",$array[0]); $data = $data[0]." ".$data[1]; #concatena em uma string tudo que estiver a partir do indice 5 do array my $command = ""; for($i=5; $i < @array ;$i++){ $command .= $array[$i]." "; } my $dbh = DBI->connect("dbi:mysql:$dbname:$dbip;mysql_connect_timeout=86400",$user,$pass); #$data = Data e Hora do Evento #$array[1] = NAS #$array[2] = USERNAME #$array[3] = Terminal #$array[4] = USER IP #$command = Comandos do Usuário my $sql_insert = "INSERT INTO authorization
(data,NAS,user,terminal,user_ip,command) VALUES ('$data','$array[1]','$array[2]','$array[3]','$array[4]','$command')"; $dbh->do($sql_insert); $dbh->disconnect; } }
#!/bin/sh # Script para verificar se o MySQL está rodando corretamente. DB_USER=xxx DB_PASS=xxxx hostname=`/bin/hostname` alert_to="[email protected] [email protected] [email protected] [email protected] [email protected]" alert_cc="" alert_subject_down="[SAA UFSC - Alerta MySQL] Problema replicando MySQL em $hostname" alert_subject_up="[SAA UFSC - Alerta MySQL] MySQL replicando novamente em $hostname" alert_message_down="A replicação do servidor SLAVE em $hostname FALHOU!"; alert_message_up="A replicação do servidor SLAVE em $hostname voltou a FUNCIONAR!"; if [ ! -f /tmp/check.pin ] then touch /tmp/check.pin echo 0 > /tmp/check.pin fi check_value=$(cat /tmp/check.pin) status=$(mktemp) echo "show slave status\G" | mysql -u $DB_USER --password=$DB_PASS > $status 2>&1 IO_Run=$(cat $status | grep "Slave_IO_Running" | cut -f2 -d':') SQL_Run=$(cat $status | grep "Slave_SQL_Running" | cut -f2 -d':') if [ "$IO_Run" != " Yes" -o "$SQL_Run" != " Yes" ] then if [ $check_value -eq 0 ] then cat <<EOF | mail -a "Content-Type: text/plain; charset='ISO-8859-1'" -s "$alert_subject_down" $alert_to $cc $alert_message_down Para maiores informações: http://wiki.pop-sc.rnp.br/index.php/Recuperar_replicacao_mysql
------------------------------------------- Mensagem de STATUS do servidor MySQL: $(cat $status) EOF echo 1 > /tmp/check.pin fi elif [ $check_value -eq 1 ] then cat <<EOF | mail -a "Content-Type: text/plain; charset='ISO-8859-1'" -s "$alert_subject_up" $alert_to $cc $alert_message_up Para maiores informações: http://wiki.pop-sc.rnp.br/index.php/Recuperar_replicacao_mysql ------------------------------------------- Mensagem de STATUS do servidor MySQL: $(cat $status) EOF echo 0 > /tmp/check.pin fi rm $status
#!/bin/bash ###### # MONITORA ESPACO UTILIZADO NAS PARTICOES E ENVIA ALERTA CASO ESTEJA CHEGANDO AO LIMITE ESTABELECIDO # #### # EMAILS PARA ONDE SERAO ENVIADOS OS EMAILS DE ALERTA MAIL="[email protected] [email protected] [email protected] [email protected] [email protected]" # #### # PEGA IP DA MAQUINA IP=`ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}' | head -n 1` # # LIMITE MAXIMO (%) DE USO DO DISCO ATE ENVIAR O ALERTA ALERT=90 #
#### # VERIFICA A SITUACAO DAS TABELAS DE PARTICAO DO SISTEMA df -H | grep -vE '^Filesystem|tmpfs|cdrom' | df -h | awk '{if ($5 ~ /^\/.*/) print $4" "$5; else if($4 ~ /./) print $5" "$6;}' | grep -v "Mounted" | while read output; # #### # VERIFICA SE O TAMANHO DA PARTICAO PASSOU DO LIMITE ESTABELECIDO # do #echo $output usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 ) partition=$(echo $output | awk '{ print $2 }' ) if [ $usep -ge $ALERT ]; then echo -e "Particao \"$partition ($usep%)\" chegando ao limite em $(hostname) em $(date)\n\nIP do Servidor: $IP" | mail -s "[SAA UFSC - Alerta Disco] Particao atingindo limite em $(hostname)" $MAIL fi done
#!/bin/bash ########### ## SCRIPT PARA MONITORAR OS PROCESSOS ESSENCIAIS DO SISTEMA ########### #### # PEGA PID DO TACACS #TAC_PID=`cat /var/run/tac_plus.pid` if [ ! -f /var/run/tac_plus.pid ] then touch /var/run/tac_plus.pid echo tacacs+ > /var/run/tac_plus.pid fi TAC_PID=`cat /var/run/tac_plus.pid` #### # LISTA DE PROCESSOS A SEREM MONITORADOS PROCESSOS="$TAC_PID ucarp logs_auth.pl logs_access.pl mavis_tacplus_ldap.pl apache2 slapd mysqld" #### # VARIAVEIS MAIL=/tmp/mail_processos.txt HOSTNAME=`/bin/hostname` IP=`ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}' | head -n 1`
#### # CONFIGURACOES DE ENVIO DE EMAIL ALERT_TO="[email protected] [email protected] [email protected] [email protected] [email protected]" ALERT_SUBJECT="[SAA UFSC - Alerta Processos] Problema em processos em $HOSTNAME" #### # MONTA EMAIL echo "" >> $MAIL echo "MAQUINA: $HOSTNAME" >> $MAIL echo "IP: $IP" >> $MAIL echo "" >> $MAIL echo "" >> $MAIL echo "---- LISTA DE PROCESSO(S) PARADO(S) ----" >> $MAIL #### # VERIFICA PROCESSOS QUE ESTAO RODANDO E ENVIA EMAIL EM CASO DE QUEDA DE DETERMINADO SERVICO I=0 for PROC in ${PROCESSOS} do if ps ax | grep -v grep | grep $PROC > /dev/null then echo "$PROC OK, processo rodando..." > /dev/null else echo "$PROC NAO esta rodando..." > /dev/null echo $PROC >> $MAIL I=$(( $I + 1 )) fi done #### # ENVIA EMAIL COM PROCESSOS QUE ESTAO PARADOS if [ $I -gt 0 ] then cat <<EOF | mail -a "Content-Type: text/plain; charset='ISO-8859-1'" -s "$ALERT_SUBJECT" $ALERT_TO $(cat $MAIL) EOF fi #### # APAGA ARQUIVO TEMPORARIO QUE GERA CORPO DO EMAIL rm $MAIL exit 0
#!/bin/bash count=`mysql -e "show binary logs\G" -uxxxx -pxxxx | grep Log_name | awk -