sábado, 30 de julho de 2011

Port knocking + Iptables fechando portas abertas a internet

Introdução.

Você já se preocupou com a quantidade de portas abertas no firewall da sua empresa, a porta 22 precisa para o acesso SSH, a 3389 para o terminal Server, a 5900 para o VNC?

Claro que a gente não se preocupa isso é bobagem, afinal nós profissionais de TI sempre temos pouca coisa para fazer e estamos constantemente trocando senhas de todos os serviços, atualizando o sistema, monitorando logs, e usamos tunelamento*. Além disso, não usamos portas padrões para o ssh, ele está rodando na porta “60500” e nenhum Hacker* irá descobrir isso :D. Bom brincadeiras a parte afinal em qualquer chat de Stripts* a palavra nmap* rola solta.

Sabemos no entanto que é praticamente impossível não possuir nenhuma porta aberta para o uso externo. Afinal temos servidores pop (porta 110), smtp (porta 25), e o próprio servidor web (porta 80) que devem estar “bem abertas” para o acesso. No entanto podemos minimizar o problema abrindo outras portas apenas quando realmente for necessário.

A idéia de um Port knocking é exatamente essa. As portas de serviços como o do Ssh ficam fechadas para acesso externo até segunda ordem a não ser que você solicite a abertura.

*Tunelamento resumidamente seria a conexão entre duas máquinas utilizando-se de uma porta qualquer onde podem trafegar informações de qualquer serviço mesmo que utilizem outra porta. Um bom exemplo de protocolo que suporta tunelamento é o Security Shell (ssh).

*Hacker diz respeito ao usuário que estuda um sistema ou hardware de computador, procurar entender seu mecanismo e como ele funciona a fim de aperfeiçoá-lo. Ao contrário do que divulga a mídia onde o Hacker é o usuário que invade sistemas e os danifica, ela está se referindo na verdade ao Cracker. Um Hacker pode invadi um sistema a fim de apontar falhas a serem corrigidas no entanto jamais causará prejuízos ou roubo de informações sigilosas.

*Scripts antigamente denominado de Lamer é o usuário que apesar de não compreender exatamente como um sistema ou mecanismo funciona utiliza-se de ferramentas criadas por outros. Esses causam prejuízos, danificam sistemas com o único intuito de ganhar fama ou dinheiro.

*Nmap software utilizado para escaneamento de redes a procura de informações diversas de um host.


Knockd

O knockd é um servidor port knoking que utiliza a lógica de combinações de portas, ou seja, caso uma tentativa de conexão externa respeite uma lógica de portas previamente definidas, a porta realmente requerida será aberta.

Um serviço knockd fica ativo em seu servidor monitorando todas as tentativas de conexões externas, caso a ordem das tentativas de conexões em portas distintas respeitem a ordem definida no seu arquivo de configuração uma regra é ativada e adicionada ao firewall.

Imaginamos que precisamos acesso a porta 3389, tentaremos inicialmente a conexão no servidor pelas portas 5000, 6000 e 7000 respectivamente (também fechadas), o serviço knockd estará monitorando essa tentativa e disparando a regra correspondente liberando acesso a porta 3389 no firewall.

Da mesma forma que a porta é aberta após finalizarmos a conexão uma outra regra é definida para fechar a porta.

O que foi utilizado

Para esse tutorial foram utilizados os sistemas Ubuntu server 11.04 configurado como firewall que possui duas placas de redes uma para acesso da internet e outro para a rede local, uma máquina cliente da rede local com Windows 2008 R2, ip 192.168.1.18, rodando o Terminal Server na porta 3389 (“Windows com W viu :)”) e uma maquina externa a rede Windows Seven que irá acessar o TS da internet.

Nosso objetivo será manter a porta 3389 fechada para acesso externo no firewall e abri-la apenas (não para toda a internet) ao cliente externo que entrou com a seqüência de portas definidas no arquivo de configuração do knocking.

Instalação e configuração do servidor

Para instalar o knockd como root digite:

#apt-get install knockd

Edite o arquivo de configuração:

# mcedit /etc/knockd.conf

Apague o conteúdo padrão do arquivo e preencha com o seguinte conteúdo:

#--INICIO--#

[options]

UseSyslog

[OPENTS2003]

sequence = 7000,8000,9000

seq_timeout = 5

command = /sbin/iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 3389 -j DNAT -s %IP% --to 192.168.1.18

tcpflags = syn

[CLOSETS2003]

sequence = 9000,8000,7000

seq_timeout = 5

command = sbin/iptables -t nat -D PREROUTING -p tcp -i eth0 --dport 3389 -j DNAT -s %IP% --to 192.168.1.18

tcpflags = syn

#--FIM--#

As linhas mais importantes desse arquivo são:

sequence = 7000,8000,9000
é onde definimos a seqüência de portas tcp que devem respeitada para a adição da regra da linha command = /sbin/iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 3389 -j DNAT -s %IP% --to 192.168.1.18
no firewall.

sequence = 9000,8000,7000 é onde definimos a seqüência de portas tcp que devem respeitada para a remoção da regra da linha command = /sbin/iptables -t nat -D PREROUTING -p tcp -i eth0 --dport 3389 -j DNAT -s %IP% --to 192.168.1.18 do firewall.


Execute o knockd com o seguinte comando:

knockd –i eth0 –d –c /etc/knockd.conf

Obs: Neste tutorial considere eth0 a placa do firewall ligada à internet.

Dicas:

*Você pode adicionar no final do arquivo /etc/rc.local o comando knockd –i eth0 –d –c /etc/knockd.conf afim de o serviço do knocking iniciar junto com o servidor.

*Podem ser adicionadas novas regras OPEN e CLOSE no arquivo de configuração do knocking.


Configuração o cliente knockd no Windows

Com o servidor em pleno funcionamento vamos baixar o cliente knockd para Windows e criar um pequeno script para executá-lo e disparar a solicitação de abertura da porta 3389 ao servidor além de abrir o cliente do Terminal Server para acesso.

Baixe o cliente knock para Windows no link abaixo:

http://www.zeroflux.org/proj/knock/files/knock-win32.zip

Cria uma pasta no c:\ com o nome de knockcli

Descompacte o arquivo baixado, entre na pasta Release e copie o executável knock.exe para a pasta c:\knockcli

Abra o bloco de notas e digite o seguinte conteúdo:

c:
cd\
cd knockcli
knock “ipdoservidor” 7000:tcp 8000:tcp 9000:tcp
cls
echo "Mantenha essa janela aberta"
%windir%\system32\mstsc.exe
knock “ipdoservidor” 9000:tcp 8000:tcp 7000:tcp


Salve com o arquivo com o nome de iniciaTS.cmd


Configuração o cliente knockd em uma máquina Linux (Ubuntu).

Para instalar cliente do knockd no Linux o comando é o mesmo do servidor, como root:

#apt-get install knockd

Podemos agora criar um pequeno script que irá executar o cliente knocking, abrir o cliente TS (Rdesktop) e ao término da sessão do TS fechar a porta novamente.

Em um terminal crie o arquivo exemplo.sh no diretório de sua preferência (não precisa ser como root):

$ mcedit /home/itn/exemplo.sh

Adicione o seguinte conteúdo ao arquivo:

#!/bin/bash
knock “ipdoservidor” 7000:tcp 8000:tcp 9000:tcp
rdesktop “ipdoservidor”
knock “ipdoservidor” 9000:tcp 8000:tcp 7000:tcp

As linhas

knock “ipdoservidor” 7000:tcp 8000:tcp 9000:tcp é a seqüência de solicitação de conexão de portas definidas no servidor para abrir a porta 3389.

knock “ipdoservidor” 9000:tcp 8000:tcp 7000:tcp é a seqüência de solicitação de conexão de portas definidas no servidor para fechamento da porta 3389.

Marque o arquivo como executável:

$ chmod +x /home/itn/exemplo.sh

Execute o arquivo (clicando sobre ou via terminal).

$ /home/itn/exemplo.sh

Conclusão


Esse tutorial foi uma pequena demonstração do uso prático de um Port knocking, sendo que o limite para o seu uso é a imaginação. Concluímos também que com esse pequeno guia podemos dormir mais tranqüilos sabendo que a “temida” porta 3389 está fechada dando um pouco mais de dor de cabeça ao Scripts, Hacker ou curiosos de plantão .

Referências

KNOCKD, a port-knocking server. Disponível em: Acesso em: 29 jul. 2011.

sexta-feira, 29 de julho de 2011

Cfengine tutorial prático de instalação cliente – servidor.

Introdução

Cfengine é um software utilizado para automatizar tarefas como instalação de programas e configurações de serviços em máquinas clientes de forma centralizada e controlada agilizando e otimizando o trabalho do profissional de TI.

O objetivo deste tutorial é demonstrar de maneira prática a instalação e configuração básica de um servidor Cfengine e de seus clientes, utilizando comunicação segura através de chaves criptografadas.

Para esse tutorial foi utilizado como servidor o Ubuntu server 11.04 e como cliente o Ubuntu desktop 10.10, no entanto o Cfengine pode ser configurado em diversos sistemas operacionais até mesmo no Windows (para utilizá-lo no Windows será preciso a instalação prévia do Cygwin).


Principais componentes do Cfengine:

Cabe aqui uma pequena definição dos componentes principais do Cfengine:

cf-promises – É um verificador e compilador para os arquivos de promises. É usado principalmente para checar as configurações desses arquivos.

cf-agent - Verifica as mudanças no diretório de atualizações do servidor a faz a sincronia no cliente.

cf-serverd – É o componente responsável por receber as requisições dos clientes e executar as políticas de um cliente. Segundo CFENGINE não é possível o envio operações de (push).

cf-execd – É o agendador de tarefas do Cfengine. Ele também coleta e executa saídas do cf-agent. Além de poder ser configurado para enviar emails ao administrador se necessário.

cf-runagent - É um programa auxiliar pode se comunicar com o cf-serverd e solicitar que ele execute o cf-agent.

cf-report - Gera relatórios em uma variedade de formatos para exportação ou
integração com outros sistemas.


Instalação e configuração no servidor


Como administrador execute o comando:

#apt-get install cfengine3

Crie na raiz uma pasta com o nome de cfengine e dentro desta uma pasta inputs.

# mkdir /cfengine
# mkdir /cfengine/inputs

Para configuração do servidor precisaremos criar quatro arquivos.

Arquivo 1: Dentro da pasta /cfengine crie o arquivo cf-serverd.cf com o seguinte conteúdo:

#--Inicio--#

body server control {

trustkeysfrom => { "192.168.1.18", "192.168.1.17" };

allowconnects => { "192.168.1.18", "192.168.1.17" };

maxconnections => "10";

logallconnections => "true";

}

bundle server access_rules {

access: "/cfengine/"

admit => { "192\.168\..*" };

}

#--Fim--#

As linhas

trustkeysfrom => { "192.168.1.18", "192.168.1.17" };
allowconnects => { "192.168.1.18", "192.168.1.17" };

é o lugar onde serão adicionados os ips das máquinas clientes que irão ter acesso ao servidor.


As linhas

access:

"/cfengine/"

admit => { "192\.168\..*" };

representam a pasta que os clientes terão acesso ao servidor, e a faixa de ips dos clientes com acesso autorizado.

Arquivo 2: Dentro da pasta /cfengine crie o arquivo update.cf com o seguinte conteúdo:

#--Inicio--#

body copy_from remote(server, path) {

servers => { "${server}" };

encrypt => "true";

trustkey => "true";

source => "${path}";

compare => "digest";

preserve => "true";

verify => "true";

purge => "true";

}

body depth_search recurse {

depth => "inf";

}

bundle agent update {

vars:

any::

"cfserverd" string =>"192.168.1.1";

"policyfiles" string =>"/cfengine";

"server_inputs" string =>"${policyfiles}/inputs";

"client_inputs" string =>"${sys.workdir}/inputs";

files:

any::

"${client_inputs}"

copy_from => remote("${cfserverd}","${server_inputs}"),

depth_search => recurse;

}

#--Fim--#



Na linha

"cfserverd" string =>"192.168.1.1";

é onde adicionamos o ip do servidor.


Na linha

"policyfiles" string =>"/cfengine";

Adicionamos a política de acesso a pasta cfengine (a mesma definida nas linhas access:

"/cfengine/" do arquivo cf-serverd.cf


Arquivo 3: Dentro da pasta /cfengine crie o arquivo promises.cf com o seguinte conteúdo:

#--Inicio--#

body common control {

bundlesequence => {

"update" };

inputs => { "update.cf","cf-serverd.cf" };

}

bundle agent hello {

commands:

any::

"/bin/date";

reports:

linux::

"Ola Mundo.";

}

#--Fim--#


Arquivo 4: Dentro da pasta /cfengine crie o arquivo failsafe.cf com o seguinte conteúdo:

#--Inicio--#

body common control{

bundlesequence => { "update" };

inputs => { "update.cf" };

}

#--Fim--#

Obs: Quando utilizarmos posteriormente o cf-agent ele sempre irá ler o arquivo promises.cf durante sua execução. Sendo assim todos os comandos a serem executados devem estar neste arquivo ou referenciado nele. Sendo assim o arquivo failsafe.cf não é realmente obrigatório, mas no entanto caso exista algum problema no arquivo promises.cf o cf-agent irá ler o arquivo failsafe.cf, que por sua vez chama o arquivo update.cf e busca atualizações ou correções no servidor.

Com os quatro arquivo prontos precisamos copiá-los para a pasta /etc/cfengine3 e move-los para /cfengine/inputs:

# cp promises.cf failsafe.cf update.cf cf-serverd.cf /etc/cfengine3
# mv promises.cf failsafe.cf update.cf cf-serverd.cf inputs

Agora geramos as chaves no servidor:

#cf-key

Afim de o servidor ler as configurações execute o comando:

#cf-serverd --verbose --no-fork

Quando a mensagem:

No new promises found
Waiting at incoming select...

finalize o processo CTRL+C.


Agora com o servidor configurado ele já pode ser iniciado:

#cf-serverd

Obs: A porta default do Cfengine é a 5308 sendo necessário ela estar liberada no servidor afim de permitir as conexões dos clientes.


Configuração do cliente:

Para configurar os clientes iniciamos com a instalação do pacote:

# apt-get install cfengine3

Geramos as chaves com o comando:

# cf-key

Precisamos agora copiar manualmente os arquivos failsafe.cf e update.cf criados anteriormente no servidor para a pasta /etc/cfengine3 do cliente.

Como root entre na pasta /etc/cfengine3 e execute o comando abaixo:

# cd /etc/cfengine3
#cf-agent –K --verbose –bootstrap

Se tudo estiver certo na pasta /var/lib/cfengine3/ppkeys do cliente irá aparacer a chave root-192.168.1.1.pub e no servidor root-192.168.1.18.pub (ou root-“ip que você configurou para o cliente”.pub).


Execute agora o comando:

# cf-agent

Com esse comando os arquivos da pasta /var/lib/cfengine3/inputs do cliente serão sempre sincronizados com conteúdo da pasta /cfengine/inputs no servidor.

Configurando cliente para atualizar automaticamente.

Claro que na prática o cf-agent não é executado manualmente no cliente afim de executarmos sincronização com o servidor, para isso utilizamos um outro componente do Cfengine o cf-execd que irá ficar ativo no cliente e de tempos em tempos executando o cf-agent a procura de atualizações.

Obs: Muitos utilizam para esse fim o próprio cron, no entanto não é recomendável uma vez que o cf-execd trás diversos recursos incorporados como o criação de logs para cada execução, além disso o cf-execd foi criado exclusivamente para tarefa de agendamento do Cfengine.

Crie o arquivo cf-execd.cf na pasta /etc/cfengine3

#--Inicio--#

body executor control {

splaytime => "1";

mailto => "root@192.168.1.1";

smtpserver => "192.168.1.1";

mailmaxlines => "1000";

schedule => { "Min00_05", "Min30_35" };

executorfacility => "LOG_DAEMON";

}

bundle agent executor {

processes:

any::

"cf-execd"

restart_class => "start_cfexecd";

commands:

start_cfexecd::

"/usr/local/sbin/cf-execd";

}

#--Fim--#

Execute o comando:

# cf-execd

Como teste final você pode criar algum arquivo no diretório /cfengine/inputs no servidor, aguardar o tempo programado no arquivo cf-execd.cf para atualização e verificar se o diretório /var/lib/cfengine3/inputs do cliente foi sincronizado.

Conclusão

Devido à falta de material em português que mostrassem de maneira prática e direta a configuração do Cfengine resolvi escrever esse tutorial. O objetivo não era ensinar a utilização prática, mas como configurar a comunicação entre o servidor e os clientes.

Agora com o servidor e os clientes comunicando-se, será preciso estudar sínteses de comandos e criação de configurações para o arquivo “promises.cf” afim de realmente automatizar as tarefas poder aplicar o Cfegine de maneira produtiva.

Referências

CFENGINE. Disponível em: <http:// www. cfengine. org> Acesso em: 28 jul. 2011.

CFENGINE 3, concept guide. Mark Burges.