Infraestrutura Ágil

Soluções e métodos inteligentes para sua infra

ActiveMQ e Mcollective com SSL

| Comments

1. Melhorando a Segurança do Mcollective

1.1 ActiveMQ & Mcollective

Por padrão, quando instalamos o Mcollective utilizamos um tipo de conexão simples e sem criptografia entre o Mcollective e o ActiveMQ. Todos os hacklabs já publicados aqui neste blog ensinam como fazer esse procedimento simples e direto ao ponto, porém, nem sempre o simples é seguro, justamente por isto vamos agora aprofundar nossos estudos no aspecto segurança.

1.2 Consumindo mensagens na fila

No caso do Mcollective ele se conecta na porta 61613 TCP do ActiveMQ para consumir a fila Mcollective. No arquivo de configuração server.cfg do Mcollective colocamos as credenciais para acesso a fila específica, isso tudo trafega na rede sem criptografia - incluindo as credenciais de autenticação da fila.

1.3 Injetando mensagens na fila

Outro detalhe importante é a injeção de mensagens na fila mcollective do ActiveMQ. Esse procedimento é realizado pelo mcollective client. Em sua na configuração mais simples, o plugin de controle utilizado como security provider é o PSK, este, por sua vez, confere se uma mensagem injetada na fila foi assinada com a mesma PSK presente no arquivo de configuração server.cfg, caso a assinatura seja igual, o mcollective server consome a fila e aplica a mensagem encontrada.

O problema de tudo isso é que se copiarmos o arquivo server.cfg para client.cfg isso nos permite utilizar o comando mco para injetar mensagens na fila, e como a PSK será igual, o mcollective server vai confiar e exectar o comando presente na mensagem. Com isso todo o node mcollective server é virtualmente um cliente em potencial que poderia injetar mensagens na fila mcollective do ActiveMQ. Esse tipo de controle é fraco e perigoso.

1.4 Melhorando a segurança

Aqui vamos demonstrar como ativar SSL no ActiveMQ e no Mcollective para garantir a integridade e privacidade dos dados que estarão passando entre esses serviços.

Outra melhoria será o uso de certificados para os clientes, com isso mesmo que algo seja injetado na fila, isto terá que ter vindo com assinatura de um certificado de alguém devidamente autorizado, do contrário o mco server simplesmente ignora a mensagem.

Esse hacklab é uma continuação de:

  1. http://gutocarvalho.net/octopress/2015/08/21/activemq-e-mcollective-no-puppet-4/
  2. http://gutocarvalho.net/octopress/2015/08/18/instalando-puppet-4-agent-and-master/

Ter executado estes labs anteriormente é pré-requisito, vou vai usar as mesmas VMs.

2. ActiveMQ ativando SSL

O ActiveMQ roda em JVM e para realizarmos a configuração de SSL/TLS em uma aplicação rodando em JVM precisamos configurar um Truststore e um Keystore.

2.1. Identificando certificados

crie o diretorio abaixo para trabalharmos

mkdir /root/certs
mkdir /root/certs/activemq
mkdir /root/certs/activemq/private

acesse o diretório

cd /root/certs/activemq

utilize o puppetmaster CA para criar uma chave para o serviço do ActivemQ.

/opt/puppetlabs/puppet/bin/puppet cert generate activemq-service

saída

1
2
3
4
Notice: activemq-server has a waiting certificate request
Notice: Signed certificate request for activemq-service
Notice: Removing file Puppet::SSL::CertificateRequest activemq-service at '/etc/puppetlabs/puppet/ssl/ca/requests/activemq-service'
Notice: Removing file Puppet::SSL::CertificateRequest activemq-service at '/etc/puppetlabs/puppet/ssl/certificate_requests/activemq-service.pem'

copie os arquivos para o diretorio de trabalho

cp /etc/puppetlabs/puppet/ssl/certs/activemq-service.pem /root/certs/activemq
cp /etc/puppetlabs/puppet/ssl/private_keys/activemq-service.pem /root/certs/activemq/private

2.2. Criando trustkey para ActiveMQ

crie a trustkey usando a CA do Puppet (defina uma senha forte)

keytool -import -alias "PuppetCA" -file /etc/puppetlabs/puppet/ssl/certs/ca.pem -keystore truststore.jks
enter password and confirmed [yes]

verifique sua truststore

keytool -list -keystore truststore.jks

2.3 Criando keystore para ActiveMQ

concatene a chave publica e privada para criar a keystore

cat /root/certs/activemq/activemq-service.pem /root/certs/activemq/private/activemq-service.pem > /root/certs/activemq/activemq-temp.pem

converta o arquivo concatenado para o formato pkcs12 (as duas senhas solicitadas devem ser as mesmas export/source)

openssl pkcs12 -export -in activemq-temp.pem -out activemq.p12 -name activemq

crie a keystore (repita a senha da keystore)

keytool -importkeystore -destkeystore keystore.jks -srckeystore activemq.p12 -srcstoretype PKCS12 -alias activemq

verifique a keystore

keytool -list -keystore keystore.jks

2.4 Ajustando o ActiveMQ XML

Localize o trecho abaixo no arquivo /etc/activemq.xml

1
2
3
4
<transportConnectors>
  <transportConnector name="openwire" uri="tcp://0.0.0.0:61616"/>
  <transportConnector name="stomp+nio" uri="stomp://0.0.0.0:61613"/>
</transportConnectors>

adicione o conector ssl

1
2
3
4
5
<transportConnectors>
  <transportConnector name="openwire" uri="tcp://0.0.0.0:61616"/>
  <transportConnector name="stomp+nio" uri="stomp://0.0.0.0:61613"/>
  <transportConnector name="stomp+nio+ssl" uri="stomp+nio+ssl://0.0.0.0:61614?needClientAuth=true"/>
</transportConnectors>

adicione o bloco de configuração para carregar os certificados logo abaixo

1
2
3
4
5
6
<sslContext>
  <sslContext
    keyStore="/etc/activemq/ssl/keystore.jks" keyStorePassword="suasenha"
    trustStore="/etc/activemq/ssl/truststore.jks" trustStorePassword="suasenha"
  />
</sslContext>

copie os arquivos gerados para o path do sslContext

mkdir /etc/activemq/ssl
cp /root/certs/activemq/truststore.jks /etc/activemq/ssl
cp /root/certs/activemq/keystore.jks /etc/activemq/ssl

reinicie seu activemq e verifique se a porta 61614 subiu

netstat -ntpl|grep 61614

saída

tcp6       0      0 :::61614  :::*   LISTEN      42682/java

se a porta 61614 está em modo listen a configuração ocorreu com sucesso.

3. Mcollective Server

Precisamos fazer dois ajustes no mcollective server, o primeiro no conector do ActiveMQ, nele vamos habilitar o uso de SSL. O segundo ajuste será na parte do security provider que será utilizado para identificar mensagens que o Mcollective Server deve confiar.

A relação de confiança depende do CA, todos os certiticados devem ser gerados a partir do mesmo CA, estamos usando a infraestrutura PKI do Puppet por ser comum a todos os nodes.

3.1 ActiveMQ Plugin SSL

ajuste as configurações para o mcollective se conectar ao activemq de forma segura, aqui você pode apontar para os certificados puppet da própria máquina, veja o exemplo abaixo

1
2
3
4
plugin.activemq.pool.1.ssl = true
plugin.activemq.pool.1.ssl.ca = /etc/puppetlabs/puppet/ssl/ca/ca_crt.pem
plugin.activemq.pool.1.ssl.key = /etc/puppetlabs/puppet/ssl/private_keys/<nome_do_seu_host>.pem
plugin.activemq.pool.1.ssl.cert = /etc/puppetlabs/puppet/ssl/certs/<nome_do_seu_host>.pem

reinicie o mcollective

systemctl restart mcollective

verifique se houve uma mensagem on_connected no log do mcollective

tail -10 /var/log/mcollective.log |grep on_connected

caso veja uma linha similar a esta abaixo

[2015-09-09T12:42:58.586917 #16357]  INFO -- : activemq.rb:119:in `on_connected' Connected to stomp+ssl://mcollective@activemq.hacklab:61614

sua conexão com o ActiveMQ via SSL ocorreu com sucesso

3.2 Security Provider SSL

Agora vamos ajustar a relação de confiança para consumir mensagens devidamente assinadas na fila mcollective do ActiveMQ. Desabilite o método psk anteriormente configurado

#securityprovider = psk
#plugin.psk = hacklab

gere um par de chaves para usarmos em todos os nodes rodando o mcollective server, essa chave será utilizada para comunicação entre o client e server, ela vai estabelecer a relação de confiança e garantir que as mensagens injetadas na fila são fidedignas e confiáveis.

/opt/puppetlabs/puppet/bin/puppet cert generate mcollective-service

saída

1
2
3
4
Notice: activemq-server has a waiting certificate request
Notice: Signed certificate request for mco-service
Notice: Removing file Puppet::SSL::CertificateRequest mco-service at '/etc/puppetlabs/puppet/ssl/ca/requests/mco-service'
Notice: Removing file Puppet::SSL::CertificateRequest mco-service at '/etc/puppetlabs/puppet/ssl/certificate_requests/mco-service.pem'

copie os arquivos gerados para o diretório ssl

mkdir /etc/puppetlabs/mcollective/ssl 
cp /etc/puppetlabs/puppet/ssl/certs/mco-service.pem /etc/puppetlabs/mcollective/ssl/server.crt
cp /etc/puppetlabs/puppet/ssl/private_keys/mco-service.pem /etc/puppetlabs/mcollective/ssl/server.key

adicione o novo método de segurança

1
2
3
4
securityprovider = ssl
plugin.ssl_server_private = /etc/puppetlabs/mcollective/ssl/server.key
plugin.ssl_server_public = /etc/puppetlabs/mcollective/ssl/server.cert
plugin.ssl_client_cert_dir = /etc/puppetlabs/mcollective/ssl/clients/

todos os seus nodes mcollective devem possuir essas chaves no diretório ssl, distribua a chave via puppet

3.3 Certificado do cliente

Agora que temos o serviço ActiveMQ e Mcollective devidamente ajustados e configurados para uso de criptografia, precisamos então criar chaves e configurar o mcollective client para que esse consiga injetar mensagens confiáveis na fila do ActiveMQ - mensagens devidamente assinadas.

3.3.1 Gerando certificado para uso no cliente

gere um certificado para uso do mco client

/opt/puppetlabs/puppet/bin/puppet cert generate gutocarvalho

saída

1
2
3
4
Notice: gutocarvalho has a waiting certificate request
Notice: Signed certificate request for gutocarvalho
Notice: Removing file Puppet::SSL::CertificateRequest gutocarvalho at '/etc/puppetlabs/puppet/ssl/ca/requests/gutocarvalho.pem'
Notice: Removing file Puppet::SSL::CertificateRequest gutocarvalho at '/etc/puppetlabs/puppet/ssl/certificate_requests/gutocarvalho.pem'

certificado gerado!

3.3.2 Instalando certificado no mco server

crie um diretório para os certificados dos clientes

mkdir /etc/puppetlabs/mcollective/ssl/clients

copie a chave publica gerada para o diretorio clients em todos o nodes mcollective - use o puppet para isto

cp /etc/puppetlabs/puppet/ssl/certs/gutocarvalho.pem /etc/puppetlabs/mcollective/ssl/clients

reinicie o mcollective server

systemctl restart mcollective

com isso seu ambiente está pronto para ser orquestrado por aquele que possuir a chave privada do certificado gutocarvalho.pem

4. Mcollective Client

O cliente mcollective pode ser configurado de duas formas, a primeira criando um arquivo client.cfg no diretório /etc/puppetlabs/mcollective ou utilizando variáveis de ambiente

4.1 Configurando Cliente

4.1.2 Arquivo client.cfg

A forma mais simples de configurar o client é copiar o arquivo server.cfg para client.cfg no mesmo diretório e fazer pequenos ajustes no parte do security provider.

1
2
3
4
securityprovider = ssl
plugin.ssl_server_public = /etc/puppetlabs/mcollective/ssl/server.crt
plugin.ssl_client_private = /etc/puppetlabs/puppet/ssl/private_keys/gutocarvalho.pem
plugin.ssl_client_public = /etc/puppetlabs/puppet/ssl/certs/gutocarvalho.pem

No caso do client.cfg precisamos apontar qual a chave publica e privada do cliente e qual o certificado publico do servidor, só isso muda no arquivo todo, depois você pode orquestrar

/opt/puppetlabs/bin/mco ping

saída

activemq.hacklab                         time=96.14 ms
mco.hacklab                              time=128.27 ms

se houve retorno similar, as configurações foram realizadas com sucesso.

4.1.3 variáveis de ambiente

É possível ter várias chaves para clientes no diretório /etc/puppetlabs/mcollective/clients , mas não é possível configurar várias chaves no client.cfg. Neste caso podemos recorrer a variáveis de ambiente para carregar chaves diferenciadas.

 export MCOLLECTIVE_SSL_PRIVATE=/home/gutocarvalho/.mc/gutocarvalho-private.pem
 export MCOLLECTIVE_SSL_PUBLIC=/home/gutocarvalho/.mc/gutocarvalho-public.pem

E depois retome a orquestração.

4.1.4 chave de cliente compartilhada

Você pode ter uma chave de cliente compartilhada em todos os nodes e usar apenas essa chave para orquestrar, só fica difícil identificar quem foi que executou a orquestração, se quiser auditoria completa, cada sysadmin deve ter sua chave pública lá e usar sua chave privada para orquestrar, assim fica tudo rastreável.

5. Amarrando as pontas

Este hacklab trouxe uma abordagem para aumentar a segurança do serviço ActiveMQ e do serviço de orquestração Mcollective, após executá-lo toda a comunicação passa a ser criptografada e a orquestraçao só ocorre com chaves de clientes autorizadas.

Há muita coisa ainda para estudar no Mcollective, aguardem novos posts.

6. Referências

  • https://docs.puppetlabs.com/mcollective/
  • https://docs.puppetlabs.com/mcollective/reference/integration/activemq_ssl.html
  • https://docs.puppetlabs.com/mcollective/deploy/middleware/activemq_keystores.html
  • https://docs.puppetlabs.com/mcollective/reference/plugins/connector_activemq.html
  • https://docs.puppetlabs.com/mcollective/reference/plugins/security_ssl.html

Comments