{"id":57,"date":"2019-01-06T22:02:10","date_gmt":"2019-01-06T21:02:10","guid":{"rendered":"http:\/\/mhichri.com\/?p=57"},"modified":"2023-02-10T19:04:55","modified_gmt":"2023-02-10T18:04:55","slug":"secure-your-elasticsearch-cluster-for-free-with-searchguard","status":"publish","type":"post","link":"https:\/\/mhichri.com\/index.php\/2019\/01\/06\/secure-your-elasticsearch-cluster-for-free-with-searchguard\/","title":{"rendered":"Secure your Elasticsearch cluster &#8220;for free&#8221; with Searchguard"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">intro<\/h2>\n\n\n\n<p>If you want to secure your Elasticsearch cluster, you may use Shield (X-Pack component) , however, in order to use it, you need to pay \ud83d\ude41<\/p>\n\n\n\n<p>Another solution can be used in order to secure your Elasticsearch cluster &#8220;for free&#8221; \ud83d\ude00 ==&gt; Search guard<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Search guard offers the possibility to secure your Elasticsearch for free ! however, some features are NOT ! so you need to pay for a licence if you want for instance to implement active directory\/LDAP based authentication.<\/p>\n\n\n\n<p>You can check search guard site in order to get an idea of which features are free for use in a production environment : <a href=\"https:\/\/search-guard.com\/product\/\">https:\/\/search-guard.com\/product\/<\/a><\/p>\n\n\n\n<p>In this blog post, I will try to explain how to secure your Elasticsearch cluster with a basic authentication mechanism.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>First, you need an Elasticsearch cluster up\/running. You can check my previous blog in order to set one  : <a href=\"https:\/\/mhichri.com\/index.php\/2018\/02\/18\/setup-a-prod-elasticsearch-instance-on-aws-ec2-server\/\">https:\/\/mhichri.com\/index.php\/2018\/02\/18\/setup-a-prod-elasticsearch-instance-on-aws-ec2-server\/<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">setup<\/h2>\n\n\n\n<p> First of all, make sure that you have <strong>JAVA <\/strong>and <strong>OPENSSL <\/strong>installed on your server<\/p>\n\n\n\n<p><strong>1- install searchguard plugin for elasticsearch<\/strong>\u00a0:<br>.\/bin\/elasticsearch-plugin install -b com.floragunn:search-guard-6:6.5.4-24.0<\/p>\n\n\n\n<p>in order to check if the searchguard is correctly installed, you should find a folder called \u00ab&nbsp;search-guard-6&nbsp;\u00bb inside your elasticsearch_path\/plugins. For instance&nbsp;:&nbsp;<\/p>\n\n\n\n<p>[admin@localhost plugins]$ pwd<br>\/home\/admin\/elasticsearch\/elasticsearch-6.5.4\/plugins<br>[admin@localhost plugins]$ ll<br>total 8<br>drwxr-xr-x. 4 admin admin 4096&nbsp; 6 janv. 18:49 search-guard-6<br>[admin@localhost plugins]$<\/p>\n\n\n\n<p><strong>2 &#8211; then, you need to generate the keystore\/trustore files<\/strong>. In this example, we will use the example file provided by searchguard (not for production use).<\/p>\n\n\n\n<p><strong>2.1 &#8211; Download<\/strong>\u00a0:<\/p>\n\n\n\n<p>wget&nbsp;<a href=\"https:\/\/github.com\/floragunncom\/search-guard-ssl\/archive\/es-6.0.0.zip\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/floragunncom\/search-guard-ssl\/archive\/es-6.0.0.zip<\/a><\/p>\n\n\n\n<p>unzip es-6.0.0.zip<\/p>\n\n\n\n<p>cd search-guard-ssl-es-6.0.0\/<\/p>\n\n\n\n<p>cd example-pki-scripts<\/p>\n\n\n\n<p><strong>2.2 &#8211; we will then edit the example.sh file\u00a0:<\/strong><\/p>\n\n\n\n<p>cp example.sh example.sh.old<\/p>\n\n\n\n<p>cat example.sh \u21d2<br>#!\/bin\/bash<br>OPENSSL_VER=&#8221;$(openssl version)&#8221;<\/p>\n\n\n\n<p>if [[ $OPENSSL_VER == *&#8221;0.9&#8243;* ]]; then<br>&nbsp;&nbsp;&nbsp; echo &#8220;Your OpenSSL version is too old: $OPENSSL_VER&#8221;<br>&nbsp;&nbsp;&nbsp; echo &#8220;Please install version 1.0.1 or later&#8221;<br>&nbsp;&nbsp;&nbsp; exit -1<br>else<br>&nbsp;&nbsp;&nbsp; echo &#8220;Your OpenSSL version is: $OPENSSL_VER&#8221;<br>fi<\/p>\n\n\n\n<p>set -e<br>#.\/clean.sh<br>.\/gen_root_ca.sh capass changeit<br>.\/gen_node_cert.sh node1 changeit capass<br>#.\/gen_node_cert.sh 1 changeit capass<br>#.\/gen_node_cert.sh 2 changeit capass<br>#.\/gen_revoked_cert_openssl.sh &#8220;\/CN=<a href=\"http:\/\/revoked.example.com\/OU=SSL\/O=Test\/L=Test\/C=DE\" target=\"_blank\" rel=\"noreferrer noopener\">revoked.example.com\/OU=SSL\/O=Test\/L=Test\/C=DE<\/a>&#8221; &#8220;<a href=\"http:\/\/revoked.example.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">revoked.example.com<\/a>&#8221; &#8220;revoked&#8221; changeit capass<br>#.\/gen_node_cert_openssl.sh &#8220;\/CN=<a href=\"http:\/\/es-node.example.com\/OU=SSL\/O=Test\/L=Test\/C=DE\" target=\"_blank\" rel=\"noreferrer noopener\">es-node.example.com\/OU=SSL\/O=Test\/L=Test\/C=DE<\/a>&#8221; &#8220;<a href=\"http:\/\/es-node.example.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">es-node.example.com<\/a>&#8221; &#8220;es-node&#8221; changeit capass<br>#.\/gen_node_cert_openssl.sh &#8220;\/CN=<a href=\"http:\/\/node-4.example.com\/OU=SSL\/O=Test\/L=Test\/C=DE\" target=\"_blank\" rel=\"noreferrer noopener\">node-4.example.com\/OU=SSL\/O=Test\/L=Test\/C=DE<\/a>&#8221; &#8220;<a href=\"http:\/\/node-4.example.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">node-4.example.com<\/a>&#8221; &#8220;node-4&#8221; changeit capass<br>.\/gen_client_node_cert.sh admin_es changeit capass<br>#.\/gen_client_node_cert.sh kirk changeit capass<br>#.\/gen_client_node_cert.sh logstash changeit capass<br>#.\/gen_client_node_cert.sh filebeat changeit capass<br>#.\/gen_client_node_cert.sh kibana changeit capass<br>#.\/gen_client_node_cert.sh sgadmin changeit capass<br>#rm -f .\/*tmp*<\/p>\n\n\n\n<p>\u21d2 here we left&nbsp; the line where we will generate a Certification Authority (CA)<br>\u21d2&nbsp; we left also the line where we generate a keystore for the elasticsearch node named \u00ab&nbsp;node1&nbsp;\u00bb .<br>\u21d2 we left the line where we generate a client certificate in order to use it as an admin certificate (mandatory in order to update searchguard configuration. PS&nbsp;: you cannot use the node certificate as an admin certificate)<\/p>\n\n\n\n<p><strong>2.3 &#8211; then , we will edit also the file \u00ab\u00a0gen_node_cert\u00a0.sh\u00bb\u00a0:<\/strong><br>[admin@localhost example-pki-scripts]$ diff gen_node_cert.sh gen_node_cert.sh.old\u00a0<br>10c10<br>&lt; NODE_NAME=$1<br>&#8212;<br>> NODE_NAME=node-$1<\/p>\n\n\n\n<p>so here, we will only change NODE_NAME=$1 instead of node-$1<\/p>\n\n\n\n<p>make sure that you\u2019re using the correct node name (already setted in you conf\/elasticsearch.yml file)&nbsp;:<br><a href=\"http:\/\/node.name\/\" target=\"_blank\" rel=\"noreferrer noopener\">node.name<\/a>: node1<\/p>\n\n\n\n<p><strong>2.4 \u2013 run .\/example.sh<\/strong><\/p>\n\n\n\n<p>you should have these files created&nbsp;:&nbsp;<br>[admin@localhost example-pki-scripts]$ pwd<br>\/home\/admin\/elasticsearch\/search-guard-ssl-es-6.0.0\/example-pki-scripts<br>[admin@localhost example-pki-scripts]$ ls -rtlh<br>total 76K<br>-rwxr-xr-x. 1 admin admin 2,0K 24 nov.&nbsp;&nbsp; 2017 gen_root_ca.sh<br>-rwxr-xr-x. 1 admin admin 2,1K 24 nov.&nbsp;&nbsp; 2017 gen_revoked_cert_openssl.sh<br>-rwxr-xr-x. 1 admin admin 1,8K 24 nov.&nbsp;&nbsp; 2017 gen_node_cert_openssl.sh<br>-rwxr-xr-x. 1 admin admin 2,3K 24 nov.&nbsp;&nbsp; 2017 gen_client_node_cert.sh<br>drwxrwxr-x. 2 admin admin&nbsp;&nbsp; 49 24 nov.&nbsp;&nbsp; 2017 etc<br>-rwxr-xr-x. 1 admin admin&nbsp; 169 24 nov.&nbsp;&nbsp; 2017 clean.sh<br>-rwxr-xr-x. 1 admin admin 1,1K&nbsp; 6 janv. 19:30 example.sh.old<br>-rwxr-xr-x. 1 admin admin 1,1K&nbsp; 6 janv. 19:33 example.sh<br>-rwxr-xr-x. 1 admin admin 2,7K&nbsp; 6 janv. 19:36 gen_node_cert.sh.old<br>-rwxr-xr-x. 1 admin admin 2,7K&nbsp; 6 janv. 19:36 gen_node_cert.sh<br>drwxrwxr-x. 2 admin admin&nbsp;&nbsp;&nbsp; 6&nbsp; 6 janv. 19:44 crl<br>drwxrwxr-x. 2 admin admin&nbsp;&nbsp;&nbsp; 6&nbsp; 6 janv. 19:44 certs<br>drwxrwxr-x. 4 admin admin&nbsp; 182&nbsp; 6 janv. 19:44 ca<br>-rw-rw-r&#8211;. 1 admin admin 1,1K&nbsp; 6 janv. 19:44 truststore.jks<br>-rw-rw-r&#8211;. 1 admin admin 1,2K&nbsp; 6 janv. 19:45 node1.csr<br>-rw-rw-r&#8211;. 1 admin admin 1,6K&nbsp; 6 janv. 19:45 node1-signed.pem<br>-rw-rw-r&#8211;. 1 admin admin 4,5K&nbsp; 6 janv. 19:45 node1-keystore.jks<br>-rw-rw-r&#8211;. 1 admin admin 5,3K&nbsp; 6 janv. 19:45 node1-keystore.p12<br>-rw-rw-r&#8211;. 1 admin admin 1,9K&nbsp; 6 janv. 19:45 node1.key.pem<br>-rw-rw-r&#8211;. 1 admin admin 5,4K&nbsp; 6 janv. 19:45 node1.crt.pem<\/p>\n\n\n\n<p><strong>2.5 \u2013 now, we will copy the files that we need (node1-keystore.jks and truststore.jks) under elasticsearch_path\/conf directory\u00a0:<\/strong><\/p>\n\n\n\n<p>cp node1-keystore.jks \/home\/admin\/elasticsearch\/elasticsearch-6.5.4\/config\/<br>cp truststore.jks \/home\/admin\/elasticsearch\/elasticsearch-6.5.4\/config\/<\/p>\n\n\n\n<p><strong>2.6 get the OWNER\u00a0:<\/strong><\/p>\n\n\n\n<p>keytool -printcert -v -file \/home\/admin\/elasticsearch\/search-guard-ssl-es-6.0.0\/example-pki-scripts\/admin_es-signed.pem \u21d2<\/p>\n\n\n\n<p>CN=admin_es,OU=client,O=client,L=Test,C=DE<\/p>\n\n\n\n<p><strong>2.7 edit elasticsearch conf file (conf\/elasticsearch.yml)<\/strong><\/p>\n\n\n\n<p># Search guard<br>#<br>searchguard.ssl.transport.keystore_type: JKS<br>searchguard.ssl.transport.keystore_filepath: node1-keystore.jks<br>searchguard.ssl.transport.keystore_password: changeit<br>searchguard.ssl.transport.truststore_type: JKS<br>searchguard.ssl.transport.truststore_filepath: truststore.jks<br>searchguard.ssl.transport.truststore_password: changeit<br>searchguard.ssl.transport.enforce_hostname_verification: false<\/p>\n\n\n\n<p>searchguard.authcz.admin_dn:<br>&nbsp;&#8211; &#8220;CN=admin_es,OU=client,O=client,L=Test,C=DE&#8221;<\/p>\n\n\n\n<p>xpack.security.enabled: false<\/p>\n\n\n\n<p><strong>2.8 &#8211; run sgadmin<\/strong><\/p>\n\n\n\n<p>searchguard stores its configuration\/permissions in a specific indice in Elasticsearch. Search guard provides a file called \u00ab\u00a0<a rel=\"noreferrer noopener\" href=\"http:\/\/sgadmin.sg\/\" target=\"_blank\">sgadmin.sg<\/a>\u00a0\u00bb that helps you change the search guard configuration or permissions without restarting your elasticsearch cluster.<\/p>\n\n\n\n<p>You can find the \u00ab&nbsp;sgadmin.sh&nbsp;\u00bb file under \u00ab&nbsp;elasticsearch_path\/plugins\/search-guard-6\/tools&nbsp;\u00bb, for instance&nbsp;:<\/p>\n\n\n\n<p>[admin@localhost tools]$ pwd<br>\/home\/admin\/elasticsearch\/elasticsearch-6.5.4\/plugins\/search-guard-6\/tools<\/p>\n\n\n\n<p>run sgadmin\u00a0(here we will use keystore\/truststore)\u00a0:\u00a0<\/p>\n\n\n\n<p><br>[admin@localhost tools]$ .\/sgadmin.sh -cd ..\/sgconfig -icl -nhnv -ts \/home\/admin\/elasticsearch\/search-guard-ssl-es-6.0.0\/example-pki-scripts\/truststore.jks -tspass changeit -ks \/home\/admin\/elasticsearch\/search-guard-ssl-es-6.0.0\/example-pki-scripts\/admin_es-keystore.jks -kspass changeit<\/p>\n\n\n\n<p>\u21d2 output&nbsp;:<\/p>\n\n\n\n<p>WARNING: JAVA_HOME not set, will use \/usr\/bin\/java<br>Search Guard Admin v6<br>Will connect to localhost:9300 &#8230; done<br>Elasticsearch Version: 6.5.4<br>Search Guard Version: 6.5.4-24.0<br>Connected as CN=admin_es,OU=client,O=client,L=Test,C=DE<br>Contacting elasticsearch cluster &#8216;elasticsearch&#8217; and wait for YELLOW clusterstate &#8230;<br>Clustername: application-mhichri<br>Clusterstate: <strong>GREEN<\/strong><br>Number of nodes: 1<br>Number of data nodes: 1<br>searchguard index does not exists, attempt to create it &#8230; done (0-all replicas)<br>Populate config from \/home\/admin\/elasticsearch\/elasticsearch-6.5.4\/plugins\/search-guard-6\/sgconfig<br>Will update &#8216;sg\/config&#8217; with ..\/sgconfig\/sg_config.yml\u00a0<br>\u00a0\u00a0 SUCC: Configuration for &#8216;config&#8217; created or updated<br>Will update &#8216;sg\/roles&#8217; with ..\/sgconfig\/sg_roles.yml\u00a0<br>\u00a0\u00a0 SUCC: Configuration for &#8216;roles&#8217; created or updated<br>Will update &#8216;sg\/rolesmapping&#8217; with ..\/sgconfig\/sg_roles_mapping.yml\u00a0<br>\u00a0\u00a0 SUCC: Configuration for &#8216;rolesmapping&#8217; created or updated<br>Will update &#8216;sg\/internalusers&#8217; with ..\/sgconfig\/sg_internal_users.yml\u00a0<br>\u00a0\u00a0 SUCC: Configuration for &#8216;internalusers&#8217; created or updated<br>Will update &#8216;sg\/actiongroups&#8217; with ..\/sgconfig\/sg_action_groups.yml\u00a0<br>\u00a0\u00a0 SUCC: Configuration for &#8216;actiongroups&#8217; created or updated<br><strong>Done with success<\/strong><\/p>\n\n\n\n<p>[admin@localhost tools]$&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<p>now, when you try to connect to&nbsp;<a href=\"http:\/\/localhost:9200\/\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/localhost:9200<\/a>&nbsp;, an authentication window will prompt asking for a username\/password.<\/p>\n\n\n\n<p>By default, there is an admin user that already exists with these credentials\u00a0:<br><em>username\u00a0: admin<br>password\u00a0: admin<\/em><br><\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1015\" height=\"482\" src=\"https:\/\/mhichri.com\/wp-content\/uploads\/2019\/01\/searchguard.png\" alt=\"\" class=\"wp-image-61\" srcset=\"https:\/\/mhichri.com\/wp-content\/uploads\/2019\/01\/searchguard.png 1015w, https:\/\/mhichri.com\/wp-content\/uploads\/2019\/01\/searchguard-300x142.png 300w, https:\/\/mhichri.com\/wp-content\/uploads\/2019\/01\/searchguard-768x365.png 768w\" sizes=\"(max-width: 1015px) 100vw, 1015px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>intro If you want to secure your Elasticsearch cluster, you may use Shield (X-Pack component) , however, in order to use it, you need to pay \ud83d\ude41 Another solution can be used in order to secure your Elasticsearch cluster &#8220;for free&#8221; \ud83d\ude00 ==&gt; Search guard Search guard offers the possibility to secure your Elasticsearch for &hellip;<\/p>\n<p class=\"read-more\"> <a class=\"\" href=\"https:\/\/mhichri.com\/index.php\/2019\/01\/06\/secure-your-elasticsearch-cluster-for-free-with-searchguard\/\"> <span class=\"screen-reader-text\">Secure your Elasticsearch cluster &#8220;for free&#8221; with Searchguard<\/span> Read More &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"","footnotes":""},"categories":[5],"tags":[],"_links":{"self":[{"href":"https:\/\/mhichri.com\/index.php\/wp-json\/wp\/v2\/posts\/57"}],"collection":[{"href":"https:\/\/mhichri.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mhichri.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mhichri.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mhichri.com\/index.php\/wp-json\/wp\/v2\/comments?post=57"}],"version-history":[{"count":4,"href":"https:\/\/mhichri.com\/index.php\/wp-json\/wp\/v2\/posts\/57\/revisions"}],"predecessor-version":[{"id":62,"href":"https:\/\/mhichri.com\/index.php\/wp-json\/wp\/v2\/posts\/57\/revisions\/62"}],"wp:attachment":[{"href":"https:\/\/mhichri.com\/index.php\/wp-json\/wp\/v2\/media?parent=57"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mhichri.com\/index.php\/wp-json\/wp\/v2\/categories?post=57"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mhichri.com\/index.php\/wp-json\/wp\/v2\/tags?post=57"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}