TCC_LuisFernandoCordeiro_final.pdf - Repositório ...

186
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

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

[email protected]

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 -

F" " {'print $2'} | wc -l` #echo $count if [ $count -gt 5 ]; then for log in `mysql -e "show binary logs\G" -ucleaner -pcl3an | grep Log_name | awk -F" " {'print $2'}`; do if [ $count -lt 5 ]; then break; fi mysql -e "PURGE BINARY LOGS TO '$log';" -ucleaner -pcl3an ((count--)) done fi