2014-02-21

Securing Kibana and Elasticsearch with HTTPS/SSL




Encrypting Kibana and Elasticsearch web connections with SSL.

In a previous blog, I covered setting up Elasticsearch, Logstash and Kibana with Lumberjack. Kibana is the web-based front-end to Elasticsearch. By default it will use a standard, unencrypted HTTP connection to communicate with Elasticsearch. This post covers ensuring that all communication to and from Kibana and Elasticsearch are encrypted using SSL.

>>>Click here to do all this with just one Copy & Paste<<<

Enabling SSL for Kibana

This will force an HTTPS connection from the browser to the web server.

SSL Apache support was already turned on by default in our EC2 instances. Check for /etc/httpd/conf.d/ssl.conf which will have the settings enabled, or else make sure that there is an httpd config file with these options enabled:

LoadModule ssl_module modules/mod_ssl.so

... and a virtualhost with these options enabled:

SSLEngine on

If these files are missing, check the Addendum at the bottom of this post.

To enable and force SSL on the Kibana site, add this to a dedicated config file, such as /etc/httpd/conf.d/kibana.conf:

<Directory /var/www/html/kibana>
 SSLRequireSSL
</Directory>

Restarting the web server will result in requests to http://yourip/kibana being forced onto https. However, as Kibana will likely be making AJAX requests to http://yourip:9200/, many browsers will block this unsecured connection from a secure web page. It may also be blocked by XSS rules, as it is on a different port.


Enabling SSL for Elasticsearch

This will force the browser to use SSL to talk to Elasticsearch.

This method places Apache in between the browser and Elasticsearch as a reverse proxy. The web browser sends ES requests to the Apache server which, in turn, redirects these requests to Elasticsearch. The connection between the browser and Apache can be encrypted over HTTPS as though it were a normal web request. Provided that Apache and Elasticsearch are on the same machine, it means that the unencrypted connection to Elasticsearch cannot be intercepted over the internet.

The reverse proxy accepts the incoming Elasticsearch requests on port 443 (https) and pushes them to Elasticsearch on port 9200, which is what Elasticsearch is expecting. Now that ES requests are on the same port as the Kibana web site, the AJAX requests should go through.

We are going to direct requests to https://yourip/elasticsearch to http://localhost:9200/. Add these to the /etc/httpd/conf.d/kibana.conf:

ProxyRequests off
ProxyPass /elasticsearch/ http://elasticsearchhost:9200/

<Location /elasticsearch/>
 ProxyPassReverse /
 SSLRequireSSL
</Location>

Kibana needs to be told which URL to use to communicate with Elasticsearch. Edit /var/www/html/kibana/config.js

and change

elasticsearch: "http://elasticsearchhost:9200",

to

elasticsearch: "https://kibanahost/elasticsearch",

elasticsearchhost and kibanahost should be replaced with the IP addresses or DNS hostnames of the elasticsearch server and the kibana server. If they are both on the same machine, they can be replaced with localhost

Restart Apache with:

sudo service httpd restart

That should all be working. Make sure that port 443 is allowed through your firewalls.


Addendum

If you could not find some of the files mentioned, it is possible to put all of the config in one file. Create a file such as /etc/httpd/conf.d/ssl.conf and add everything to it:

Listen 443
LoadModule ssl_module modules/mod_ssl.so

<VirtualHost _default_:443>
        DocumentRoot "/var/www/html/kibana"
        ErrorLog logs/ssl_error_log
        TransferLog logs/ssl_access_log
        LogLevel warn

        SSLEngine on
        SSLProtocol all -SSLv2
        SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
        SSLCertificateFile /etc/pki/tls/certs/localhost.crt
        SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

        ProxyRequests off
        ProxyPass /elasticsearch/ http://elasticsearchhost:9200/

        <Location /elasticsearch/>
                ProxyPassReverse /
                SSLRequireSSL
        </Location>

        <Directory /var/www/html/kibana>
                SSLRequireSSL
        </Directory>
</VirtualHost>

Don't forget to change /var/www/html/kibana/config.js so that the elasticsearch: value is https://kibanahost/elasticsearch, replacing kibanahost with the IP address or hostname of the Kibana machine.

You might also need to install mod_ssl:

sudo yum install openssl mod_ssl

I did this when booting from a blank Amazon Linux EC2 AMI. This assumes that there is nothing else being served by SSL on port 443.

No comments:

Post a Comment