From 469db9e35dee1df4bba1db8f79edb6078fbb7482 Mon Sep 17 00:00:00 2001 From: Swann Croiset Date: Mon, 20 Jun 2016 18:02:35 +0200 Subject: [PATCH] Add authentication for Kibana An Apache virtual host is configured as a reverse proxy to enforce basic HTTP authentication. DocImpact Kibana has now credentials Change-Id: I65f44534581531a9ff923b54a4b08f77df070040 --- .../puppet/manifests/firewall.pp | 6 ++ .../puppet/manifests/haproxy.pp | 2 +- .../puppet/manifests/hiera_override.pp | 6 +- deployment_scripts/puppet/manifests/kibana.pp | 10 +++ .../lma_logging_analytics/.fixtures.yml | 6 ++ .../manifests/kibana_authentication.pp | 62 +++++++++++++++++++ .../lma_logging_analytics/manifests/params.pp | 1 + .../lma_logging_analytics/metadata.json | 5 +- ...ng_analytics_kibana_authentication_spec.rb | 37 +++++++++++ .../templates/apache_kibana_proxy.conf.erb | 30 +++++++++ environment_config.yaml | 22 ++++++- pre_build_hook | 4 ++ 12 files changed, 186 insertions(+), 5 deletions(-) create mode 100644 deployment_scripts/puppet/modules/lma_logging_analytics/manifests/kibana_authentication.pp create mode 100644 deployment_scripts/puppet/modules/lma_logging_analytics/spec/classes/lma_logging_analytics_kibana_authentication_spec.rb create mode 100644 deployment_scripts/puppet/modules/lma_logging_analytics/templates/apache_kibana_proxy.conf.erb diff --git a/deployment_scripts/puppet/manifests/firewall.pp b/deployment_scripts/puppet/manifests/firewall.pp index 53832a0..91582f2 100644 --- a/deployment_scripts/puppet/manifests/firewall.pp +++ b/deployment_scripts/puppet/manifests/firewall.pp @@ -74,6 +74,12 @@ firewall { '101 kibana': action => 'accept', } +firewall { '101 proxy-kibana': + port => hiera('lma::elasticsearch::apache_port'), + proto => 'tcp', + action => 'accept', +} + firewall { '999 drop all other requests': proto => 'all', chain => 'INPUT', diff --git a/deployment_scripts/puppet/manifests/haproxy.pp b/deployment_scripts/puppet/manifests/haproxy.pp index 14c36e4..6c3039b 100644 --- a/deployment_scripts/puppet/manifests/haproxy.pp +++ b/deployment_scripts/puppet/manifests/haproxy.pp @@ -15,7 +15,7 @@ notice('fuel-plugin-elasticsearch-kibana: haproxy.pp') $es_port = hiera('lma::elasticsearch::rest_port') -$kibana_backend_port = hiera('lma::elasticsearch::kibana_port') +$kibana_backend_port = hiera('lma::elasticsearch::apache_port') $kibana_frontend_port = hiera('lma::elasticsearch::kibana_frontend_port') $vip = hiera('lma::elasticsearch::vip') diff --git a/deployment_scripts/puppet/manifests/hiera_override.pp b/deployment_scripts/puppet/manifests/hiera_override.pp index dfa4af3..4f89eb5 100644 --- a/deployment_scripts/puppet/manifests/hiera_override.pp +++ b/deployment_scripts/puppet/manifests/hiera_override.pp @@ -66,7 +66,7 @@ if is_integer($elasticsearch_kibana['recover_after_nodes']) and $elasticsearch_k $instance_name = 'es-01' $logs_dir = "/var/log/elasticsearch/${instance_name}" -$tls_enabled = $elasticsearch_kibana['tls_enabled'] +$tls_enabled = $elasticsearch_kibana['tls_enabled'] or false if $tls_enabled { $kibana_hostname = $elasticsearch_kibana['kibana_hostname'] $cert_base_dir = '/etc/haproxy' @@ -102,6 +102,7 @@ lma::elasticsearch::vip: <%= @vip %> lma::elasticsearch::es_haproxy_service: elasticsearch-rest lma::elasticsearch::listen_address: <%= @listen_address%> lma::elasticsearch::kibana_frontend_port: 80 +lma::elasticsearch::apache_port: 80 lma::elasticsearch::kibana_port: 5601 lma::elasticsearch::kibana_index: .kibana lma::elasticsearch::rest_port: 9200 @@ -121,12 +122,13 @@ lma::elasticsearch::jvm_size: <%= @elasticsearch_kibana["jvm_heap_size"] %> lma::elasticsearch::instance_name: <%= @instance_name %> lma::elasticsearch::node_name: "<%= @fqdn %>_es-01" lma::elasticsearch::cluster_name: lma - lma::kibana::tls::enabled: <%= @tls_enabled %> <% if @tls_enabled -%> lma::kibana::tls::hostname: <%= @kibana_hostname %> lma::kibana::tls::cert_file_path: <%= @cert_file_path %> <% end -%> +lma::kibana::username: <%= @elasticsearch_kibana["kibana_username"] %> +lma::kibana::password: <%= @elasticsearch_kibana["kibana_password"] %> ') file { $hiera_file: diff --git a/deployment_scripts/puppet/manifests/kibana.pp b/deployment_scripts/puppet/manifests/kibana.pp index 2fbf7c2..d9c1178 100644 --- a/deployment_scripts/puppet/manifests/kibana.pp +++ b/deployment_scripts/puppet/manifests/kibana.pp @@ -21,3 +21,13 @@ class { 'lma_logging_analytics::kibana': es_port => hiera('lma::elasticsearch::rest_port'), version => '4.5.1', } + +class { 'lma_logging_analytics::kibana_authentication': + listen_address => hiera('lma::elasticsearch::listen_address'), + listen_port => hiera('lma::elasticsearch::apache_port'), + kibana_address => hiera('lma::elasticsearch::listen_address'), + kibana_port => hiera('lma::elasticsearch::kibana_port'), + username => hiera('lma::kibana::username'), + password => hiera('lma::kibana::password'), + require => Class[lma_logging_analytics::kibana], +} diff --git a/deployment_scripts/puppet/modules/lma_logging_analytics/.fixtures.yml b/deployment_scripts/puppet/modules/lma_logging_analytics/.fixtures.yml index ea4f5d3..b5d7c40 100644 --- a/deployment_scripts/puppet/modules/lma_logging_analytics/.fixtures.yml +++ b/deployment_scripts/puppet/modules/lma_logging_analytics/.fixtures.yml @@ -9,5 +9,11 @@ fixtures: concat: repo: "git://github.com/puppetlabs/puppetlabs-concat" ref: "1.2.4" + apache: + repo: "git://github.com/puppetlabs/puppetlabs-apache" + ref: "1.5.0" + htpasswd: + repo: "git://github.com/leinaddm/puppet-htpasswd" + ref: "0.0.3" symlinks: lma_logging_analytics: "#{source_dir}" diff --git a/deployment_scripts/puppet/modules/lma_logging_analytics/manifests/kibana_authentication.pp b/deployment_scripts/puppet/modules/lma_logging_analytics/manifests/kibana_authentication.pp new file mode 100644 index 0000000..efb5701 --- /dev/null +++ b/deployment_scripts/puppet/modules/lma_logging_analytics/manifests/kibana_authentication.pp @@ -0,0 +1,62 @@ +# Copyright 2016 Mirantis, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Class lma_logging_analytics::kibana_authentication + +class lma_logging_analytics::kibana_authentication ( + $listen_address, + $listen_port, + $kibana_port, + $kibana_address, + $username, + $password, +) { + + include lma_logging_analytics::params + + $apache_modules = ['proxy', 'proxy_http', 'rewrite', + 'authn_file', 'auth_basic', 'authz_user'] + + ## Configure apache + class { 'apache': + # be good citizen by not erasing other configurations + purge_configs => false, + default_confd_files => false, + default_vhost => false, + mpm_module => false, + default_mods => $apache_modules, + } + + apache::listen { "${listen_address}:${listen_port}": } + + $htpasswd_file = $lma_logging_analytics::params::apache_htpasswd_file + htpasswd { $username: + cryptpasswd => ht_md5($password, 'salt'), + target => $htpasswd_file, + require => Class['apache'], + } + + file { $htpasswd_file: + ensure => present, + mode => '0440', + owner => $::apache::user, + group => $::apache::group, + require => Class[Apache], + } + + apache::custom_config { 'kibana-proxy': + content => template('lma_logging_analytics/apache_kibana_proxy.conf.erb'), + require => [Class['apache'], File[$htpasswd_file]], + } +} diff --git a/deployment_scripts/puppet/modules/lma_logging_analytics/manifests/params.pp b/deployment_scripts/puppet/modules/lma_logging_analytics/manifests/params.pp index f097506..a242cbe 100644 --- a/deployment_scripts/puppet/modules/lma_logging_analytics/manifests/params.pp +++ b/deployment_scripts/puppet/modules/lma_logging_analytics/manifests/params.pp @@ -20,6 +20,7 @@ class lma_logging_analytics::params { $kibana_dir = '/opt/kibana' $kibana_config = "${kibana_dir}/config.js" + $apache_htpasswd_file = '/etc/apache2/kibana.htpasswd' $kibana_dashboard_prefix = 'Logging, Monitoring and Alerting - ' $kibana_default_route = join(['/dashboard/elasticsearch/', $kibana_dashboard_prefix, 'Logs'], '') $kibana_replicas = 0 diff --git a/deployment_scripts/puppet/modules/lma_logging_analytics/metadata.json b/deployment_scripts/puppet/modules/lma_logging_analytics/metadata.json index cb01570..4968294 100644 --- a/deployment_scripts/puppet/modules/lma_logging_analytics/metadata.json +++ b/deployment_scripts/puppet/modules/lma_logging_analytics/metadata.json @@ -21,6 +21,9 @@ "dependencies": [ {"name": "puppetlabs/stdlib", "version_requirement": "4.x"}, {"name": "jfryman/nginx", "version_requirement": ">= 0.2.2"}, - {"name": "elasticsearch/elasticsearch", "version_requirement": ">= 0.10.x"} + {"name": "elasticsearch/elasticsearch", "version_requirement": ">= 0.10.x"}, + {"name": "puppetlabs/concat", "version_requirement": "1.2.3"}, + {"name": "puppetlabs/apache", "version_requirement": "1.5.0"}, + {"name": "leinaddm/htpasswd", "version_requirement": ">= 0.0.3"} ] } diff --git a/deployment_scripts/puppet/modules/lma_logging_analytics/spec/classes/lma_logging_analytics_kibana_authentication_spec.rb b/deployment_scripts/puppet/modules/lma_logging_analytics/spec/classes/lma_logging_analytics_kibana_authentication_spec.rb new file mode 100644 index 0000000..b6d1f1c --- /dev/null +++ b/deployment_scripts/puppet/modules/lma_logging_analytics/spec/classes/lma_logging_analytics_kibana_authentication_spec.rb @@ -0,0 +1,37 @@ +# Copyright 2016 Mirantis, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +require 'spec_helper' + +describe 'lma_logging_analytics::kibana_authentication' do + let(:facts) do + {:kernel => 'Linux', :operatingsystem => 'Ubuntu', + :operatingsystemrelease => '12.4', :osfamily => 'Debian', + :concat_basedir => '/foo' } + end + + let(:params) do + {:listen_address => '127.0.0.1', :listen_port => 80, + :kibana_address => '127.0.0.1', :kibana_port => 5106, + :username => 'foouser', :password => 'foopass' + } + end + + it { + should contain_class('apache') + should contain_apache__custom_config('kibana-proxy') + should contain_htpasswd('foouser') + should contain_file('/etc/apache2/kibana.htpasswd') + } +end + diff --git a/deployment_scripts/puppet/modules/lma_logging_analytics/templates/apache_kibana_proxy.conf.erb b/deployment_scripts/puppet/modules/lma_logging_analytics/templates/apache_kibana_proxy.conf.erb new file mode 100644 index 0000000..f2fc6a4 --- /dev/null +++ b/deployment_scripts/puppet/modules/lma_logging_analytics/templates/apache_kibana_proxy.conf.erb @@ -0,0 +1,30 @@ +# ************************************ +# Vhost template in module lma_logging_analytics +# Managed by Puppet +# ************************************ + +:<%= @listen_port %>> + ServerName kibana + DocumentRoot "/opt/kibana" + + ProxyRequests Off + + + Order Allow,Deny + Allow From All + AuthName "Kibana Access" + AuthType Basic + AuthUserFile <%= @htpasswd_file %> + require valid-user + + + ProxyPass / http://<%= @kibana_address %>:<%= @kibana_port %> + ProxyPassReverse / http://<%= @kibana_address %>:<%= @kibana_port %> + RewriteEngine on + RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f + RewriteRule .* http://<%= @kibana_address %>:<%= @kibana_port %>%{REQUEST_URI} [P,QSA] + + ErrorLog "/var/log/apache2/kibana_error.log" + ServerSignature Off + CustomLog "/var/log/apache2/kibana_access.log" combined + diff --git a/environment_config.yaml b/environment_config.yaml index 00af811..88847ab 100644 --- a/environment_config.yaml +++ b/environment_config.yaml @@ -26,12 +26,32 @@ attributes: value: '1' label: 'JVM heap size' description: 'in GB (between 1 and 32). The amount of memory reserved for the JVM.' - weight: 18 + weight: 16 type: "text" regex: source: '^([1-9]|[12][0-9]|3[0-2])$' error: 'Enter a value between 1 and 32' + kibana_username: + value: 'lma' + label: 'User name' + description: 'The username to access Kibana.' + weight: 17 + type: "text" + regex: + source: '\S' + error: "You must provide a username." + + kibana_password: + value: '' + label: 'User password' + description: 'The password to access Kibana.' + weight: 18 + type: "password" + regex: + source: '^[\S]{4,}$' + error: "You must provide a password with at least 4 characters" + advanced_settings: label: "Advanced settings" value: false diff --git a/pre_build_hook b/pre_build_hook index ad65d95..d171fd7 100755 --- a/pre_build_hook +++ b/pre_build_hook @@ -10,6 +10,8 @@ ELASTICSEARCH_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/elasticsearc # Dependency for Elasticsearch 0.10.x DATACAT_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/richardc-datacat-0.6.2.tar.gz" FIREWALL_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/puppetlabs-firewall-1.7.2.tar.gz" +APACHE_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/puppetlabs-apache-1.4.0.tar.gz" +HTPASSWD_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/leinaddm-htpasswd-0.0.3.tar.gz" TZ_VERSION="2016d-0ubuntu0.14.04_all" @@ -37,6 +39,8 @@ download_puppet_module "stdlib" "$STDLIB_TARBALL_URL" download_puppet_module "elasticsearch" "$ELASTICSEARCH_TARBALL_URL" download_puppet_module "firewall" "$FIREWALL_TARBALL_URL" download_puppet_module "datacat" "$DATACAT_TARBALL_URL" +download_puppet_module "apache" "${APACHE_TARBALL_URL}" +download_puppet_module "htpasswd" "${HTPASSWD_TARBALL_URL}" # Update tzdata-java package to remove strict dependency on tzdata (see LP bug #1560436)