ActiveMQ e Mcollective com SSL
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:
- http://gutocarvalho.net/octopress/2015/08/21/activemq-e-mcollective-no-puppet-4/
- 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
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
<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
<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
<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
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
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
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
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.
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