As emocionantes aventuras de um sysadmin linux na procura pelo uptime perfeito!

PKI: Indo de Gnomint para EJBCA

Posted: abril 1st, 2010 | Author: coredump | Filed under: Linux e Open Source, segurança | Tags: , , ,

Uma das coisas que eu sempre me preocupo em fazer ao chegar em um novo trabalho para lidar com infraestrutura é instalar uma série de serviços para ajudar na administração. Isso inclui wikis, monitoramento, um sistema de tickets de serviço, e por ai vai. Outra coisa é criar uma estrutura básica de PKI para emissão de certificados SSL para servidores e outros serviços.

Gerenciar uma Certificate Authority (Autoridade Certificadora ou CA) pode ser feito de várias formas, desde usando os comandos do openssl na mão, passando por utilizar as facilidades de PKI do Active Directory do Windows e algumas ferramentas gráficas como o Gnomint.

Até a semana passada eu estava realmente usando o Gnomint, mas tive uma série de problemas, principalmente com encoding e com um plano de utilizar essa PKI de forma mais ampla. O Gnomint é ótimo para gerenciar pequenas PKIs, mas quando você pensa em emitir milhares de certificados SSL, vocẽ precisa de algo mais parrudo.

Acabei lendo sobre o EJBCA, que é uma aplicação que roda em JBoss e tem uns usuários bem famosos (incluindo o SERASA, aqui no Brasil). O EJBCA foi então a escolha para gerência da PKI.

A instalação dele no Debian (Lenny) foi bem simples, basicamente porque o pacote JBoss do Debian atualmente não faz porra nenhuma, e você tem de baixar o mesmo do site do JBoss e instalar na mão (isso quer dizer descompactar para algum lugar, eu sugiro o /opt). Algumas coisas que eu fiz e podem ajudar:

  • Instalar o JDK6 e o ant via pacote do Debian mesmo: sun-java6-sdk e ant, o ant instala como ant-gcj mas funcionou certinho.
  • Baixar do site da Sun a JCE (Java Cryptography Extensions), e colocar os conteúdos do zip em /usr/lib/jvm/java-6-sun-1.6.0.12/jre/lib/security – isso é necessário para que o Java aceite algumas características mais pesadas em certificados, como senhas com mais de 7 caracteres.
  • Baixe o EJBCA e descompacte no /opt também. Eles não avisam, mas um monte de coisas precisa ser feita desse diretório, ou seja, não se pode simplesmente instalar e apagar, tem de guardar e fazer backup.
  • Configurar as variáveis JAVA_HOME e APPSRV_HOME (apontando para onde está o JBoss) no seu ambiente corretamente. Isso é uma mão na roda e evita que você rode a parada com uma jvm diferente da que você quer. Configure também as variáveis ANT_OPTS e JAVA_OPTS para incluir os parâmetros de memória, eu uso “-Xms128m -Xmx768m” em uma  VM de 1 GB de memória.
  • Se você vai usar poucos certificados, ou está instalando para testar, pode utilizar o banco de dados padrão que é em memória. Caso contrário, instale o postgresql-8.3 (ou mais atual).

Com isso você mata os pré-requisitos do EJBCA. De resto, o guia de instalação dele é bem certinho. Mas basicamente o que você tem de fazer é:

  • Dentro do diretório do EJBCA tem o diretório conf, onde você deve copiar o ejbca.properties.sample para ejbca.properties e configurar. Algumas coisas são bem avançadas como por exemplo guardar as chaves e certificados em dispositivos de hardware, mas no meu caso a maioria dos padrões serviu bem.
  • Leia o arquivo database.properties.sample e o documento howto databases que tem dentro do /doc do EJBCA. Lá tem os comandos para se criar o banco postgres mas basicamente você cria um usuário ejbca com uma senha qualquer, e um banco com este usuário sendo o owner.

O resto do guia é bem mastigado. Lembre-se que o login na interface administrativa só é feito via Certificado, então depois de instalado não perca o arquivo superadmin.p12 queé gerado na instalação e deve ser importado no seu browser para que se possa acessar a interface.

Dentro do diretório do EJBCA existem também documentos descrevendo a utilização de vários servidores de aplicação diferentes assim como outros bancos de dados.

A outra parte foi mais complicada. Eu tinha de pegar os certificados e as chaves privadas das minhas CAs internas do Gnomint e colocá-las no EJBCA. Seria simples, se o Gnomint exportasse o PKCS#12 direito, mas aparentemente ele faz alguma besteira no formato e o EJBCA dá um erro. A solução foi a seguinte, e pode ser utilizada para migração de várias outras formas de PKI para o EJBCA:

  • No Gnomint, exportei separadamente o certificado da minha Root CA para um arquivo e a chave privada da mesma para outro.
  • Usando o openssl, criei um arquivo PKCS#12 usando estes dois arquivos, com o seguinte comando:

sudo openssl pkcs12 -export -out rootca.p12 -inkey rootca.key -in rootca.pem -name privateKey

  • Isso ai cria um arquivo que o EJBCA alegremente importou como a minha nova RootCA, via interface gráfica, sem estresse.
  • Caso você, como eu, tenha de importar CAs subordinadas (sempre uma boa idéia), você tem de repetir o procedimento acima para cada uma (exportar chave e certificado de cada uma), mas tem uma pegadinha: no caso de CAs subordinadas, você tem de incluir no comando openssl a opção -certfile rootca.pem. Porquê disso, você deve perguntar. Porquê sem isso, a cadeia (chain) de certificados fica incorreta no PKCS#12 e quando a Sub CA for importada ela vai aparecer como auto-assinada, e não assinada pela sua Root CA (ou seja, sua cadeia vai ficar quebrada).
  • Eu tive de importar também alguns certificados já emitidos para servidores aqui. Isso não é extremamente necessário, mas se não for feito você vai ficar sem uma forma de revogar estes certificados pelo EJBCA futuramente. Existe uma ferramenta chamada bin/ejbca.sh do EJBCA que faz essa importação sem trauma.

Depois disso, só alegria. O EJBCA tem uma interface pública que fica disponível na porta 8080, onde são publicados as CRL (Certificate Revocation Lists) e também onde usuários podem submeter CSRs (Certificate Signing Request) para geração de novos certificados. A interface administrativa roda na porta 8443 e só pode ser acessada por quem tem o certificado correto instalado no browser, e cuida do resto da PKI.

PKIs são dados sensíveis. Você deve ter backups seguros das configurações e principalmente das keychains das suas CAs. Se você perde uma chave ou um certificado Raiz, você perde toda a segurança que ele propõe, e vai ter de re-emitir TODOS os seus certificados. Lembre-se de limitar o acesso a interface administrativa e a própria máquina, várias camadas de firewall são aconselhadas.

A minha PKI roda numa máquina virtualizada, mas eu não aconselho isso para qualquer lugar onde os certificados serão utilizados em funões críticas. Uma máquina virtualizada é altamente mais sucetível a ataques e a roubo de dados (afinal de contas, se roubar a imagem, rouba-se tudo).

O próximo passo é dar uma conferida na integração do EJBCA com LDAP, para ver como fica uma PKI realmente grande e integrada com outros sistemas.

intel

6 Comments »

Para ser um Sysadmin

Posted: março 7th, 2010 | Author: coredump | Filed under: Linux e Open Source, segurança | Tags: , ,

Vendo o formspring do fike eu tentei me lembrar do que um bom sysadmin precisa. Eu e ele terminamos o papo no gtalk, e eis a lista sem uma ordem específica:

  1. Sistemas Operacionais e Organização de Computadores (não adianta tentar ser um sysadmin sem ter um amplo conhecimento de como o SO e Hardware funcionam)
  2. Rede (mesma coisa ali de cima, e aqui estamos falando daquelas chatices de TCP/IP, cabeçalhos, window size, mtu e tudo mais, não só roteamento)
  3. Programação (tem de saber algum shell script, e mais uma linguagem de verdade)
  4. Conceito das linguagens utilizadas no ambiente que vai se administrar (java, python, etc…)
  5. Banco de Dados (como eles funcionam, transações, locking, particionamento, tuning)
  6. Inglês (isso é óbvio)

Mas dai você vai dizer “porra, mas esse monte de coisa?”. Acredite, o seu ambiente vai dar merda e você pelo menos tem de ter conhecimento o bastante para apontar a falha (além de ter de resolver).

intel

1 Comment »

Como funciona a parada da Gestão da Porta 25

Posted: maio 22nd, 2009 | Author: coredump | Filed under: Linux e Open Source, segurança | Tags: , ,

Baseado nesse post do br-linux e nas dúvidas do povo no twitter, resolvi escrever um post rápido sobre o como funciona. Pode ser que tenha algo faltando ou errado, se tiver avisem nos comentários.

É assim:

Imagine que você tem um email email@longe.cu que fica longe.

Atualmente sua máquina conecta na porta 25 do servidor smtp.longe.cu para enviar email para qualquer lugar. Para isso ele deve pedir uma senha para permitir que você consiga enviar email e fazer relay.

Com a gerência da porta 25, vc não conseguiria fazer isso mais, a porta seria bloqueada. Teria algumas opções:

  • Passar a usar SMTP com TLS/SSL que usa a porta 900 e algo.
  • Usar um MSA (Mail Submission Agent) do seu provedor de conexão.

Esse MSA basicamente é um servidor que aceita conexões na porta 487, num formato igual ao SMTP mas com alguns relaxamentos de cabeçalho. Esse servidor tem de estar configurado para fazer relay para qualquer lugar do planeta, desde que a conexão venha da rede que ele serve, independente do FROM do email.
Então o seu cliente de correio envia a sua mensagem como você mesmo (email@longe.cu) para o MSA que daí envia ele pra o TO dele.

FROM: email@longe.cu
TO: bleh@gmail.com; bleh@uol.com.br; bleh@longe.cu

O que o MSA faz é enviar via SMTP (e aí entra o MTA) para os MXs responsáveis pelos dominios gmail, uol e longe.cu

Então sua mensagem continua saindo com seu email, da mesma forma de antes, só não vai ser do SMTP do domínio do email, mas isso não faz muita diferença.

Algumas vantagens/desvantagens que eu vejo:

  • Os provedores de conexão tem mais controle sobre o que sai na sua rede de SMTP. Evita que faixas inteiras sejam banidas por causa de 1 spammer enviando emails diretamente lá de dentro;
  • Até onde eu vi isso quebra SPF;
  • Provedores de conexão poderiam bloquear envio de certos tipos de mensagem e etc.

intel

2 Comments »

Os 25 erros de programação mais perigosos segundo a SANS

Posted: janeiro 22nd, 2009 | Author: coredump | Filed under: segurança | Tags: , ,

Saiu no site da SANS a lista criada com o consenso entre varios profissionais e empresas do ramo de segurança e desenvolvimento descrevendo os 25 erros de programação mais perigosos para o desenvolvimento seguro. Eu vou traduzir os nomes e informação básicos mas o melhor é ler o artigo na íntegra, em inglês.

Os erros estão separados em três categorias: Interação insegura entre componentes, Gerenciamento arriscado de recursos, Defensas porosas.

Categoria: Interação insegura entre componentes

  1. Validação Imprópria de Entradas: Entradas que recebem dados e os aceitam mesmo sem certificar que eles são do tipo/formato esperado.
  2. Codificação ou Escape Impróprios de Saída: Saídas que não são codificadas ou escapadas corretamente são a maior fonte de ataques de injeção de código.
  3. Falha ao Preservar a Estrutura da Busca SQL (conhecido como Injeção de SQL): Se os atacantes podem influenciar as procuras SQL do seu programa, então eles podem controlar o seu banco de dados.
  4. Falha ao Preservar a Estrutura do Código da Página (conhecido como “Cross-site Scripting”): Assim como o anterior, se os atacantes podem injetar código ou scripts em sua página, eles podem controlar a página.
  5. Falha ao Preservar a Estrutura de Comandos do Sistema Operacional: Se você permitir que entradas ilegais sejam passadas para aplicativos do sistema operacional, o atacante pode controlar o servidor.
  6. Transmissão de Dados Sensíveis em Texto Puro: Senhas, dados de cartão e qualquer informação considerada sensível deve ser criptografada.
  7. Falsificação de Requisição Entre Sites: Um atacante pode criar uma requisição que é enviada a outro site forjando a origem e fazendo o mesmo partir de um usuário inocente, aproveitando credenciais de autenticação e acessos.
  8. Condição de Corrida: Atacantes vão sempre procurar por condições de corrida no software para conferir se alguma informação importante não é obtida no processo.
  9. Vazamento de Informações em Mensagens de Erro: Atacantes vão procurar por mensagens de erro que descrevam mais que o necessário, como nomes de campos SQL, objetos e bibliotecas sendo utilizadas.

Categoria: Gerenciamento arriscado de recursos:

  1. Falha ao Limitar Operações aos Limites de um Buffer de Memória: O conhecido buffer overflow.
  2. Controle Externo de Dados Sensíveis: Informações críticas que são mantidas fora de um banco de dados por questões de performance não deviam ser facilmente acessíveis por atacantes.
  3. Controle Externo de de Caminho ou Nome de Arquivo: Quando você usa dados externos para montar um nome de arquivo ou caminho de gravação, você está se arriscando a ser atacado.
  4. Caminho de Procura Inseguro: Se o caminho de procura de recursos estiver em algum lugar sob controle de um atacante, bibliotecas ou código pode ser inserido a revelia.
  5. Falha ao Controlar a Geração de Código: Caso o atacante consiga influenciar a geração de código dinâmico (se geração de código dinâmico for utilizada no programa) ele poderá controlar todo seu código.
  6. Download de Código sem Verificação de Integridade: Se você executa código obtido por download, você confia na fonte. Atacantes podem aproveitar esta confiança.
  7. Desligamento ou Liberação Impróprias de Recursos: Arquivos, conexões e classes precisam ser corretamente encerradas.
  8. Inicialização Imprópria: Dados, bibliotecas e sistemas inicializados incorretamente podem abrir margens para problemas.
  9. Cálculos Incorretos: Quando o atacante tem algum controle sobre as entradas usadas em operações matemáticas, isso pode gerar vulnerabilidades.

Categoria: Defensas porosas:

  1. Controle de Acesso Impróprio: Se você não garante que seus usuários estão fazendo apenas o que deviam, os atacantes irão se aproveitar de sua autenticação.
  2. Uso de um Algoritmo Criptográfico Quebrado ou Vulnerável: Utilização de algoritmos fracos ou comprometidos levam a falhas de criptografia e vulnerabilidades.
  3. Senha no Código: deixar um usuário e uma senha no próprio código traz inúmeros problemas.
  4. Permissão de Acesso Insegura para Recurso Crítico: Configurações, arquivos de dados e bancos de dados devem ter suas permissões de acesso protegidas.
  5. Uso de Valores Insuficientemente Aleatórios: Se você usa tipos de segurança que dependem de aleatoriedade, usar um gerador aleatório insuficiente só vai causar problemas.
  6. Execução com Privilégios Desnecessários: Se seu programa precisa de privilégios elevados para executar suas funções, ele deve abrir mão destes direitos assim que ele termina de executar as ações que precisavam dos privilégios.
  7. Aplicação de Segurança do Lado do Servidor pelo Cliente: Atacantes podem usar engenharia reversa em um cliente de software e escrever seus próprios clientes removendo testes e aplicações de segurança.

Algumas coisas foram realmente chatas de traduzir, sinta-se livre para sugerir correções.

intel

PS: Lembre-se sempre “os 25 mais” não quer dizer “os 25 únicos”. Grain of Salt faz bem.

8 Comments »

Desenvolvimento seguro e software livre – Dica 4: Operação Segura

Posted: janeiro 11th, 2009 | Author: coredump | Filed under: Linux e Open Source, segurança | Tags: ,

CadeadoCheque esta tag para ver os demais posts desta série.

Operação Segura

A prática final no desenvolvimento seguro é especialmente importante para projetos de Software Livre. A Operação Segura refere-se a todo o suporte que deve ser oferecido às aplicações e sistemas depois dos mesmos serem lançados e disponibilizados como uma “versão final”.

A operação segura não se refere apenas ao suporte comum dado em listas e fórums de discussão mas também ao fornecimento de canais de comunicação específicos para problemas e soluções relacionados a segurança que vão surgir de acordo com a popularização do software.

O primeiro ponto que tem de se observar nesta estrutura de suporte é o como o projeto vai lidar com falhas de segurança descobertas in the wild (ou seja, na operação normal de um software já lançado). Muitos defendem o Full Disclosure mas existem alguns projetos que lidam com as vulnerabilidades em segredo até uma correção estar disponível.

Outro ponto importante é a definição clara de como os avisos/relatórios que tratem de vulnerabilidades serão enviados e recebidos pelo projeto. É aconselhável que exista um canal rápido e conhecido (um email ou formulário de fácil acesso) pelo qual relatórios sobre novas vulnerabilidades (ou mesmo bugs relativos à segurança) possam ser enviados e tratados pela equipe responsável em tempo hábil, sem a necessidade de vigiar centenas de emails sobre suporte genéricos na lista de usuários.

Caso o projeto opte pelo Full Disclosure, os desenvolvedores tem de estar atentos à esta política e tomar as devidas precauções. Mesmo sem o Full Disclosure, os desenvolvedores tem de ter em mente que um especialista em segurança pode descobrir uma falha simplesmente analisando atualizações no repositório de controle de versões. Correções ou formas de se remediar uma falha devem ser feitas públicas e amplamente conhecidas o mais rápido possível após a descoberta/publicação de uma falha.

Internamente, as falhas de segurança encontradas após o lançamento devem realimentar o processo de análise de risco para que este possa se concentrar nas áreas próximas a onde a falha foi encontrada, no intuito de conferir a efetividade das correções e o possível aparecimento de problemas decorrentes de novo código adicionado muitas vezes as pressas.

Conclusão

Este foi o último post desta série. As cinco práticas descritas são na verdade uma simplificação de sistemas mais elaborados e menos flexíveis de desenvolvimento seguro, visando facilitar a implantação destas práticas a projetos descentralizados e muitas vezes não tão grandes assim de Software Livre. Os interessados em saber mais ou dar suas opiniões podem deixar seus comentários ou entrar em contato.

intel

1 Comment »