Criando uma central de comandos remotos Ali do Amaral Pedrozo Curso de Pós Graduação em Redes e Segurança de Sistemas Pontifícia Universidade Católica do Paraná Curitiba, Outubro de 2009 Resumo Administrar Servidores Linux não é uma tarefa fácil. Por exemplo, uma simples troca de senha, é algo simples quando se tem um número pequeno de servidores em uma rede local, porém quando o número de servidores é grande e nem todos eles estão conectados a mesma rede local (estão distribuídos também pela internet), outros fatores contribuem para que esta tarefa deixe de ser simples. Uma empresa administra cerca de trezentos servidores Linux e um dos itens da política de segurança interna, é a troca periódica de senhas (usuário root) a cada dois meses. Hoje este processo de troca é feito manualmente acessando os servidores via ssh (Secure Shell). Considerando que todos os servidores possuam acesso à internet, como esse processo de troca poderia ser feito de forma automatizada? Vejamos agora outra situação. A empresa possui, para atender seus clientes, uma equipe técnica composta de trinta colaboradores, e todos possuem acesso a senha dos servidores Linux. O que aconteceria se um colaborador da equipe fosse desligado da empresa e tivesse más intenções? Como seria possível a troca de senha dos trezentos clientes de uma única vez, de forma que os clientes ficassem seguros contra um colaborador descontente? Esta é a proposta deste artigo. Criar uma central de comandos remotos, onde é possível de forma automatizada, alterar a senha de todos os clientes de uma única vez. 1 Introdução A empresa utilizada como escopo do artigo, possui um software comercial desenvolvido em Xharbour (Compilador compatível com linguage Clipper, tendo como características principais ser software livre e multiplataforma, ele converte os arquivos com extensão .PRG em .C, usando depois um compilador C para gerar os arquivos executáveis.) [1]. Tal software é instalado em um servidor Linux cuja distribuição utilizada é : CentOS - The Community Enterprise Operating System, atualmente na versão 5.3 [2]. O presente artigo irá concentrar-se não em uma solução completa de segurança para esta empresa, mais sim em uma solução para um item falho no momento que é a troca de senhas de maneira automatizada. 2 Entendendo o problema Todos os servidores desta empresa possuem uma senha que esta em conformidade com as recomendações da cartilha “Práticas de Segurança para Administradores de Redes Internet” distribuída pelo cert.br (Centro de Estudos, Respostas e Tratamento de Incidentes de Segurança no Brasil). Porém, ter uma uma única senha padrão para trezentos servidores é praticamente inviável, pois, quando revelada, facilita muito o trabalho de um invasor. Em vista disso, foi criado uma senha padrão especifica para cada cliente. Por exemplo, um cliente chamado “Negócios S.A.”, teria a senha “#paNEGdr@0#”, ou seja, seu prefixo padrão é “#pa”, seu sufixo padrão é “dr@0#” e seu miolo são as três primeiras letras do nome da empresa escritos em maiúsculo. Assim, para a empresa “Relogios S.A.”, a senha seria “#paRELdr@0#”. Este padrão muda a cada dois meses. [3] O dia a dia da empresa fornecedora do software é o suporte a seus clientes e um dos itens de suporte envolve o acesso aos servidores Linux com a conta de administrador, justificando assim a necessidade de cada um dos trinta colaboradores da equipe técnica possuir o “padrão de senhas”. A situação problema encontrada nesta empresa pode ser exemplificado da seguinte forma: 1. Existe uma política de troca de senhas a cada dois meses que não é devidamente cumprida, pois os colaboradores responsáveis por esse procedimento geralmente, não conseguem completar essa tarefa (por falta de tempo, por preguiça, por ter que ir fisicamente ao servidor que não possui acesso externo, ou por qualquer outro fator). Assim durante um ano, é possível encontrar nos clientes “6 padrões de senhas” diferentes. 2. Sua politica de segurança interna define que quando um colaborador tem que ser desligado da empresa, deve-se trocar todas as senhas existentes imediatamente. Porem, se já existe a dificuldade de trocar as senhas em dois meses que é o tempo padrão, é praticamente impossível trocar todas as senhas após a ocorrência deste fato. O que acontece nesta empresa, e em muitas outras, é que “o setor de informática é utilizado para resolver problemas de ordem administrativa e não de ordem tecnológica ”. 3 Apresentando uma solução Apresentado esta problemática, o presente artigo se propõe a desenvolver uma ferramenta simples mas eficiente, que irá trocar as senhas dos servidores de forma automatizada. A solução se dará da seguinte forma: 1. Criação de um servidor que será utilizado como “Central de Comandos Remotos”. Neste servidor ficarão cadastrados todos os servidores linux clientes. 2. Criação de um Shell Script (Sequências de comandos escritas em arquivos textos, que são interpretados por uma shell) em Bash (Interpretador de comandos que permite a execução de sequências de comandos direto no prompt do sistema ou escritas em arquivos textos) “server.sh” que ficará disponível no servidor central para organizar a execução de comandos remotos nos servidores clientes. 3. Criação de um Shell Script em Bash “cliente.sh” que será instalado em cada servidor cliente, cujo funcionamento está exemplificado na figura 1. Figura 1 – Funcionamento do Shell Script “cliente.sh”. 4 Reunindo ferramentas Para criação de toda a estrutura necessária para o funcionamento desta solução, foram utilizadas as seguintes ferramentas: Open SSH (Secure Shell) Programa que permite a conexão com outro computador na rede através de comunicação criptografada [4]. Netfilter (Iptables) Módulo que fornece ao Linux funções de firewall[5]. Regula o trafego de dados entre redes distintas e impede a transmissão/recepção de acessos não autorizados de uma rede para a outra, além de fazer NAT1, log dos pacotes que trafegam na rede, etc. [6]. PortKnocking (PK) Mecanismo que permite abrir portas externas em um firewall, através de uma sequência préestabelecida de conexão em portas que estão fechadas. Uma vez que o firewall recebe uma sequência de conexão correta, ele automaticamente libera acesso externo para este host. Seu principal foco é a prevenção contra ferramentas de port scanning [7], pois inicialmente todas as portas estão fechadas e apenas será liberado o acesso se uma sequência de “PK” correta for feita. PK é muito utilizado para permitir acessos a porta 22, a porta do SSH [8]. JailKit Conjunto de ferramentas que limitam contas de usuários para arquivos específicos usando chroot [9] e outros comandos específicos. Através deste kit é possível criar um ambiente limitado apenas com as aplicações que o administrador do sistema julgue necessário, aumentando o nível de segurança do sistema operacional [10]. Estas ferramentas foram escolhidas, para resolver as seguintes questões de segurança: 1. Acesso não autorizado Através do iptables, será possível a criação de um firewall restritivo que não permitirá acesso algum ao servidor central e através do PortKnocking, somentes os clientes poderão acessar o servidor central, já que , somente eles terão a sequência de PK correta. 2. Comunicação Segura Através do Openssh, os clientes se comunicação com o servidor através de uma comunicação criptografada. 3. Ambientes controlados Através do JailKit, cada cliente quando conectar no servidor terá acesso apenas a sua “jaula”. De posse destes conceitos podemos iniciar a parte prática. 1 Network Address Translation 5 Preparando o Servidor Central de Comandos Remotos A Central de comandos remotos, utilizou como distribuição o “CentOS 5.3 32bits com kernel 2.6.18-128”. A instalação das outras ferramentas envolvidas na criação da central serão omitidas, e apenas serão exemplificados seus modelos de uso. Configuração do Firewall Agora, vamos inicialmente configurar um firewall simples, para isso vamos utilizar este pequeno script: servidor servidor servidor servidor servidor ~# ~# ~# ~# ~# mkdir /opt/firewall -p cd /opt/firewall wget -c http://www.linuxnotes.com.br/rshcmd/firewall.sh chmod 755 firewall.sh ./firewal.sh start Configuração do PortKnocking Com o firewall básico preparado, o próximo passo é configurar o PK. Para isso, a configuração minima é a seguinte: servidor ~# vi /etc/knockd.conf [options] logfile = /var/log/knockd.log [openSSH] sequence = 1,2,3,4 seq_timeout = 5 command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn [closeSSH] sequence = 5,6,7,8 seq_timeout = 5 command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn Efetuado a configuração, podemos iniciar o PK da seguinte forma: servidor ~# knockd -i eth0 -d -c /etc/knockd.conf Configuração do Shell Script “server.sh” Vamos agora instalar o script “server.sh” e criar as pastas necessárias: servidor servidor servidor servidor ~# ~# ~# ~# cd /opt wget -c http://www.linuxnotes.com.br/rshcmd/server.sh chmod 755 server.sh mkdir /opt/clientes Configuração do Clientes dentro do JailKit Agora vamo adicionar ao servidor o primeiro cliente chamado de “cliente01” dentro da pasta “/opt/clientes”. servidor ~# /opt/server.sh -j cliente01 /opt/clientes Verificando se usuario jah nao existe no jail Criando usuario: [CMD] useradd -m cliente01 [CMD] passwd cliente01 Changing password for user cliente01. New UNIX password: ********** Considerações Finais do Servidor Central Neste momento já temos a seguinte estrutura: 1. Servidor Central instalado 2. Firewall ativado 3. PortKnocking ativado 4. Shell Script “server.sh” configurado Desta maneira se encerra a configuração inicial da central de comandos remotos, e de uma jaula inicial, vamos agora para a instalação do cliente. 6 Preparando o Cliente Os servidores clientes utilizados neste artigo possuem como distribuição o “CentOS 5.3 32bits com kernel 2.6.18-128”, porém, poderia ser utilizado qualquer outra distribuição, desde que respeitado os seguintes pré-requisitos: 1. OpenSSH Server 2. Acesso a internet Configuração de Conexão com o Servidor Central Inicialmente temos que criar um par de chaves para conexão remota via ssh sem senha: cliente ~# ssh-keygen -t dsa Generating public/private dsa key pair. Enter file in which to save the key (/root/.ssh/id_dsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_dsa. Your public key has been saved in /root/.ssh/id_dsa.pub. The key fingerprint is: 17:5d:80:1d:9f:71:48:32:89:55:76:d0:e2:e7:cd:90 root@cliente Vamos agora fazer uma cópia da chave pública em nosso servidor central. Antes, vamos parar o firewall para que possamos copiar as chaves. servidor~# /opt/firewall/firewall.sh stop cliente ~# scp ~/.ssh/id_dsa.pub cliente01@server:~cliente01/.ssh/authorized_keys2 servidor~# /opt/firewall/firewall.sh start Após copiar a chave pública, vamos ativar o firewall no servidor novamente. Configuração do Shell Script “cliente.sh” Vamos agora configurar o shell script que ficará rodando no cliente: cliente cliente cliente cliente ~# ~# ~# ~# mkdir /opt/rshcmd -p cd /opt/rshcmd wget -c http://www.linuxnotes.com.br/rshcmd/cliente.sh chmod 755 /opt/rshcmd/cliente.sh Aqui devemos apenas alterar algumas variáveis, são elas: cliente ~# vi cliente.sh $USUARIO=“cliente01” $HOST=”200.200.200.200” $PORTA=”22” Que define o usuário do servidor central. Que define o IP do servidor central Que define a porta do servidor central. Feito isso, apenas vamos inicializar o script: cliente ~# /opt/rshcmd/cliente.sh & Caso queira ver o script em ação, ative o modo debug: cliente ~# /opt/rshcmd/cliente.sh 1 & Neste momento já temos o cliente e o servidor configurados. 7 Executando comandos remotos A proposta do artigo é demonstrar uma maneira automatizada de alterar senhas de servidores remotos de forma centralizada, segura e padronizada. Então, com ajuda das ferramentas expostas anteriormente, podemos fazer o seguinte: 1. Criar um arquivo com os comandos que desejamos que sejam executados no cliente. servidor ~# vi comandos.txt echo “senhanova” | passwd --stdin root 2. Utilizar o script “server.sh” para ordenar que os clientes efetuem os comandos definidos no arquivo “comandos.txt”: servidor ~# ./server.sh -c cliente01 comandos.txt /opt/clientes 3. Para visualizar os comandos que foram executados e para visualizar os resultados obtivos de suas execuções no servidor cliente remoto, basta acessar a pasta “control/cmd/log”. servidor ~# su cliente01 cliente01@servidor~$ cd control/cmd/log cliente01@servidor~$ cat cmd.140920092002 echo “senhanova” | passwd --stdin root cliente01@servidor~$ cat res.140920092002 Changing password for user root. passwd: all authentication tokens updated successfully. Assim, os arquivos “cmd.*” e “res.*”, contém respectivamente os comandos que foram executados em um dado momento (cmd.*), assim como a resposta do comando (res.*). 8 Conclusão Este artigo contemplou a solução do problema de “troca de senha automatizada”. Através do conjunto de ferramentas exposto, foi possível criar uma infraestrutura simples que permitiu a execução automatizada da troca de senhas. Se observarmos um pouco a fundo, o conjunto de scripts “server.sh” e “cliente.sh”, podem ser utilizados para qualquer outro procedimento automatizado que o usuário imaginar, bastando para isso, apenas algumas adaptações, o limite é a própria imaginação. Por exemplo, digamos que os clientes exemplificados neste artigo, tivesse apenas acesso de saída para a internet através da porta 80, como seria possível com a estrutura atual, acessar externamente este servidor? Simples, através do seguinte comando: servidor# vi comandos.txt ssh -R 80:localhost:22 empresa@servercentral servidor# ./server.sh -c cliente01 comandos.txt /opt/clientes Desta forma, no servidor central, localmente (dentro do jail do cliente), seria possível se conectar no servidor remoto através do seguinte comando: servidor# ssh -l root localhost -p 80 Esta técnica chamada-se “Connect Back”, e é utilizada pelo “LogMeIn” [11], cujo objetivo é que o cliente se conecte ao servidor, e não o servidor ao cliente. Com esta técnica é possível, acessar qualquer host através de um firewall, isso porque geralmente, apenas o trafego que entra no filtro de pacotes é controlado. Outro exemplo de uso do conjunto de scripts do artigo, poderia ser uma aplicação WEB (vou sugerir a utilização de CGI [12]), que informe os endereços ips de todos os clientes remotos: servidor# vi comandos.txt ifconfig eth0 | grep "inet end" | cut -d ":" -f 2 | cut -d " " -f 2 servidor# ./server.sh -c cliente01 comandos.txt /opt/clientes servidor# cat /opt/clientes/cliente01/jail/home/cliente01/control/cmd/log/res.xxxxxx 192.168.0.100 Assim, poderia-se criar outra aplicação que percorreria as jaulas, leria estes dados, e os formataria de forma a exibi-los em uma página web (CGI). 9 Referências [1] Xharbour. Extended xBase Compiler. Acessado em setembro de 2009. Disponível em: http://www.xharbour.org/. [2] CentOS. The Community ENTerprise Operating System. Acessado em setembro de 2009. Disponível em: http://www.centos.org/ [3] cert.br. Práticas de Segurança para Administradores de Rede Internet. Acessado em setembro de 2009. Disponível em: http://www.cert.br/docs/seg-adm-redes/seg-admredes.html#subsec3.4 [4] Openssh. Keeping Your Communiqués secret. Acessado em setembro de 2009. Disponível em: http://www.openssh.com/ [5] Firewall. Acessado em Outubro de 2009. Disponível em: http://pt.wikipedia.org/wiki/Firewall [6] Netfilter. Acessado em Setembro de 2009. Disponível em: http://www.netfilter.org/ [7] PortScanning. Acessado em setembro de 2009. Disponível em: http://netsecurity.about.com/cs/hackertools/a/aa121303.htm [8] PortKnocking. A stealthy system for network authentication across closed ports. Acessado em setembro de 2009. Disponível em: http://www.portknocking.org/ [9] Chroot. Acessado em setembro de 2009. Disponível em: http://pt.wikipedia.org/wiki/Chroot [10] Jailkit. Acessado em setembro de 2009. Disponível em http://olivier.sessink.nl/jailkit/ [11] LogMeIn. Acessado em Outubro de 2009. Disponível em: http://www.logmein.com/ [12] CGI. Common Gateway Interface. Acessado em setembro de 2009. Disponível em: http://pt.wikipedia.org/wiki/CGI