Veremos a partir de agora como aplicar controle de acesso no elasticsearch, utilizando um plugin opensource, bem como configurar um período de retenção.
Ativar apenas a autenticação é simples. Para limitar o acesso a interface do kibana, o comum tem sido configurar um webserver autenticado como proxy reverso. Neste caso, é fácil encontrar documentações envolvendo integração com o nginx, por exemplo. Também encontrei ajustes granulares via nginx, mas não gostei (gera uma complexidade desnecessária e fora de propósito).
Para controlar acesso de forma granular e exportar o dashboard, no formato pdf, o time de desenvolvimento do elasticsearch defende a utilização do plugin x-pack. Trata-se de uma solução eficiente e fácil de instalar. Infelizmente, o pacote disponível para download livremente é trial (30 dias). A solução é comercial.
Pesquisando por soluções alternativas, encontramos o Searchguard. A instalação não foi tão simples e alguns problemas nos fizeram abandonar. Assim como no x-pack, existe um plugin para o elasticsearch e outro para o kibana. A versão do plugin para o kibana ainda é Alpha. E, nos testes realizados, recebemos mensagens de erro interno na chamada de algumas funções.
A segunda alternativa que encontramos, conhecida como Readonly Rest, foi a mais simples, eficiente e atende a demanda da maioria dos administradores. Além disto, o plugin é disponibilizado sob licença GPL 3,
Demonstraremos uma configuração simples, supondo que duas filiais exportarão os logs de seus servidores proxy (peers) para a matriz, e forneceremos acesso ao dashboard limitando a visão apenas ao segmento de rede que fazem parte – impedindo que uma filial visualize os logs da outra.
Disponibilizei para download um pacote com os arquivos essenciais de configuração:
elk-readonlyrest.tar
Instalação e configuração do plugin ReadonlyREST no servidor
Não instale a versão readonlyrest-1.13.0_es5.1.2.zip. Preferencialmente, opte pelo download disponível na página oficial ou instale a versão avaliada na demonstração.
1. Instalação do plugin
/usr/share/elasticsearch/bin/elasticsearch-plugin install file:///diretorio/do/dowload/readonlyrest-1.13.0_es5.1.2.zip
2. Alteração em /etc/elasticsearch/elasticsearch.yml
Para que este layout funcione, cada filial informará um document-type único que será definido como index no servidor logstash (repare nos índices em negrito).
readonlyrest: enable: true response_if_req_forbidden: <h1>Forbidden</h1> access_control_rules: - name: Kibana Server type: allow auth_key: kibana:kibana - name: Logstash type: allow hosts: ["127.0.0.1"] auth_key: logstash:logstash # Grupos - name: Grupo filial 1 type: allow accept_x-forwarded-for_header: true kibana_access: ro actions: ["indices:data/read/*", "indices:admin/mappings/get", "indices:admin/mappings/fields/get*"] indices: ["<no-index>", "logstash-squid-filial1*", ".kibana*", "default"] groups: ["grpfilial1"] - name: Grupo filial 2 type: allow accept_x-forwarded-for_header: true kibana_access: ro actions: ["indices:data/read/*", "indices:admin/mappings/get", "indices:admin/mappings/fields/get*"] indices: ["<no-index>", "logstash-squid-filial2*", ".kibana*", "default"] groups: ["grpfilial2"] users: - username: filial1 auth_key: filial1:senh@fili@l1 groups: ["grpfilial1"] - username: filial2 auth_key: filial2:senh@fili@l2 groups: ["grpfilial2"]
Em caso de dúvidas, consulte os links:
https://github.com/sscarduzio/elasticsearch-readonlyrest-plugin
https://github.com/sscarduzio/elasticsearch-readonlyrest-plugin/wiki/Supported-Rules
3. Reiniciando o serviço (systemctl ou service)
systemctl restart elasticsearch
Configuração do servidor Logstash
Após reiniciar o serviço elasticsearch, qualquer conexão será validada. Portanto, informe uma conta de usuário válida no bloco “output” (usuário logstash).
O índice foi redefinido como “logstash-%{type}-%{+YYYY.MM.dd}” para diferenciar os dados por origem (document-type) e identificar o dia corrente (para controlar o período de retenção).
1. Alteração em /etc/logstash/conf.d/squid.conf
input { beats { host => "ip_servidor_logstash" port => 5044 ssl => false } } filter { if [type] =~ /(squid|squid-*)/ { grok { break_on_match => true match => [ "message", "%{NUMBER:timestamp}\s+%{NUMBER:response_time} %{IPORHOST:src_ip} %{WORD:squid_request_status}/%{NUMBER:http_status_code} %{NUMBER:reply_size_include_header:int} %{WORD:http_method} %{WORD:http_protocol}://%{HOSTNAME:dst_host}:%{NUMBER:tcp.port}%{NOTSPACE:request_url} %{NOTSPACE:user} %{WORD:squid}/(?:-|%{IP:dst_ip}) %{NOTSPACE:content_type}" ] match => [ "message", "%{NUMBER:timestamp}\s+%{NUMBER:response_time} %{IPORHOST:src_ip} %{WORD:squid_request_status}/%{NUMBER:http_status_code} %{NUMBER:reply_size_include_header:int} %{WORD:http_method} %{WORD:http_protocol}://%{HOSTNAME:dst_host}%{NOTSPACE:request_url} %{NOTSPACE:user} %{WORD:squid}/(?:-|%{IP:dst_ip}) %{NOTSPACE:content_type}" ] match => [ "message", "%{NUMBER:timestamp}\s+%{NUMBER:response_time} %{IPORHOST:src_ip} %{WORD:squid_request_status}/%{NUMBER:http_status_code} %{NUMBER:reply_size_include_header:int} %{WORD:http_method} %{HOSTNAME:dst_host}:%{NUMBER:tcp.port} %{NOTSPACE:user} %{WORD:squid}/(?:-|%{IP:dst_ip}) %{NOTSPACE:content_type}" ] add_tag => ["squid"] } geoip { source => "dst_ip" } } } output { elasticsearch { hosts => localhost ssl => false flush_size => 1000 index => "logstash-%{type}-%{+YYYY.MM.dd}" user => logstash password => logstash } }
2. Reiniciando o serviço (systemctl ou service)
systemctl restart logstash
Configuração do servidor Kibana
Para autenticar, configure a conta definida em “Kibana Server“. Vale lembrar que, de acordo com a configuração demonstrada, o usuário kibana terá acesso irrestrito ao ambiente. “O mesmo se aplica ao usuário logstash, desde que o endereço IP de origem seja local (127.0.0.1)”.
A opção elasticsearch.preserveHost foi definida como false para permitir o envio do IP de origem no header x-forwarded-for, possibilitando aplicar filtros por IP no plugin readonlyrest.
Pela interface do Kibana, crie cada index em “Management->Index Patterns->Add New“. Ou seja, em “index name or pattern” cadastre “logstash-squid-filial1-*” e repita o processo para cada filial. O botão “Create” ficará disponível desde que já exista um índice válido no elasticsearch.
1. Alteração em /etc/kibana/kibana.yml
# Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values. # The default is 'localhost', which usually means remote machines will not be able to connect. # To allow connections from remote users, set this parameter to a non-loopback address. server.host: "0.0.0.0" ... # The URL of the Elasticsearch instance to use for all your queries. elasticsearch.url: "http://localhost:9200" # When this setting’s value is true Kibana uses the hostname specified in the server.host # setting. When the value of this setting is false, Kibana uses the hostname of the host # that connects to this Kibana instance. #elasticsearch.preserveHost: true elasticsearch.preserveHost: false ... # If your Elasticsearch is protected with basic authentication, these settings provide # the username and password that the Kibana server uses to perform maintenance on the Kibana # index at startup. Your Kibana users still need to authenticate with Elasticsearch, which # is proxied through the Kibana server. elasticsearch.username: "kibana" elasticsearch.password: "kibana" ...
2. Reiniciando o serviço (systemctl ou service)
systemctl restart kibana
Configuração dos agentes Filebeat
Há apenas uma mudança significativa no arquivo /etc/filebeat/filebeat.yml. Ajuste o conteúdo de document-type de cada filial. Na primeira, configure como squid-filial1 e, na segunda, squid-filial2.
1. Alteração em /etc/filebeat/filebeat.yml
... # Each - is a prospector. Most options can be set at the prospector level, so # you can use different prospectors for various configurations. # Below are the prospector specific configurations. - input_type: log # Paths that should be crawled and fetched. Glob based paths. paths: - /var/log/squid/access.log document_type: squid-filial1 ...
2. Reiniciando o serviço (systemctl ou service)
systemctl restart filebeat
Configuração do período de retenção no servidor Elasticsearch
O controle de retenção será feito através da ferramenta Curator. A configuração base do Curator será definida no arquivo config.yml. Nele, configuraremos os parâmetros de conexão com o elasticsearch. Já a definição das ações (como remoção de index) será definida em action.yml.
Em nosso exemplo, o período de retenção será configurado para 1 ano (365 dias).
Se desejar consultar os índices disponíveis, utilize o comando:
curl -u logstash 'localhost:9200/_cat/indices?v'
1. Instalação da ferramenta Curator
sudo echo "deb http://packages.elastic.co/curator/4/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-5.x.list sudo apt-get update #Instalação do serviço apt-get install elasticsearch-curator mkdir /etc/curator
2. Configuração da ferramenta Curator
– Definição do arquivo /etc/curator/config.yml
--- # Remember, leave a key empty if there is no value. None will be a string, # not a Python "NoneType" client: hosts: - 127.0.0.1 port: 9200 url_prefix: use_ssl: False certificate: client_cert: client_key: ssl_no_validate: False http_auth: logstash:logstash timeout: 30 master_only: False logging: loglevel: INFO logfile: logformat: default blacklist: ['elasticsearch', 'urllib3']– Definição do arquivo /etc/curator/action.yml
--- # Remember, leave a key empty if there is no value. None will be a string, # not a Python "NoneType" # # Also remember that all examples have 'disable_action' set to True. If you # want to use this action as a template, be sure to set this to False after # copying it. actions: 1: action: delete_indices description: >- Delete indices older than 365 days (based on index name), for logstash- prefixed indices. Ignore the error if the filter does not result in an actionable list of indices (ignore_empty_list) and exit cleanly. options: ignore_empty_list: True timeout_override: continue_if_exception: False disable_action: False filters: - filtertype: pattern kind: prefix value: logstash-squid- exclude: - filtertype: age source: name direction: older timestring: '%Y.%m.%d' unit: days unit_count: 365 exclude:
3. Execução da ferramenta Curator
– Para automatizar o processo, inclua uma chamada no cron (diário)
curator --config /etc/curator/config.yml /etc/curator/action.yml
betolj, Gostei desse artigo.
.eu já utilizo o ELK, para logs do Pfsense, você conhece alguma maneira de coletar os logs do Squid do Pfsense e enviar para o ELK?