Exploration on elasticsearch authority of elStack

  Stack

Preface

As mentioned above in Netty’s use of the Honeycomb API gateway technology decryption, the API gateway “accepts outside and inside” and forwards outside requests to various internal capture services. In the gateway, not only can authentication, encryption and decryption, routing and current limiting functions be performed; If you want to know the statistics related to each service interface, such as the number of calls, call time, number of successes, number of failures, etc., you can bury the node in the gateway, collect relevant information, put it into elasticsearch (es) through logstash, and obtain statistical information of each service interface in kibana or through http request of es.

ELK framework

图

Some time ago, there was a demand. Our es needs to be provided as a service. Considering that sensitive data is stored in es, it is necessary to add rights management function to es. There are about three schemes for searching es permission management:

  • Elstackofficial security plug-in X-Pack Securit
  • Essecurity plug-in Search Guard
  • Self-actualized Rights Management

Considering that X-Pack Security is a fee-paying software, the cost of developing a rights management module is relatively high. Finally, the community version of Search Guard is selected, and the supported functions have already met the current requirements.
图

Search Guard installation process

  • Stop Elasticsearch

ps -ef | grep elasticsearch | grep -v grep |
awk {‘print $2’} | xargs kill -9

  • Install Search Guard

/opt/soft/elasticsearch-5.5.1-guard/bin/
elasticsearch-plugin install -b
com.floragunn:search-guard-5:5.5.1-14

If the online server cannot access the external network, the corresponding version of Search Guard can be downloaded in advance and installed in local mode.

/opt/soft/elasticsearch-5.5.1-guard/bin/
elasticsearch-plugin install -b
file:///opt/soft/search-guard-5-5.5.1-15.zip

  • Generate certificates and configure es

    If es is installed in the test environment, the script provided by the software can be used to generate CA and corresponding certificates, and es is automatically configured.

    sh /opt/soft/elasticsearch-5.5.1-guard/plugins/search-guard-5/tools/install_demo_configuration.sh

    However, the above methods are not applicable to online environment. Our es hopes that the online environment can provide access control, so it uses search-guard-ssl to generate online certificates.

First, the search-guard-ssl project was downloaded.

git clone https://github.com/floragunncom/search-guard-ssl.git
生成证书,可以参考官方文档详细说明
  • It is recommended to modify the certificate information and password

example-pki-scripts/etc/root-ca.conf
example-pki-scripts/etc/signing-ca.conf

Execute certificate generation script

sh ./example.sh

Copy the corresponding certificate to the config folder of es

Modify es configuration

cluster.name: honeycomb-es-guard-5.5.1# node 1 to 5
node.name: node-1 
path.data: /data01/elasticsearch-guard
path.logs: /opt/logs/elasticsearch-guard

network.host: 0.0.0.0

http.cors.enabled: true
http.cors.allow-origin: "*"
thread_pool.bulk.queue_size: 50

searchguard.ssl.transport.keystore_filepath: node-1-keystore.jks
searchguard.ssl.transport.keystore_password: node_es
searchguard.ssl.transport.truststore_filepath: truststore.jks
searchguard.ssl.transport.truststore_password: r_ca_honeycomb
searchguard.ssl.transport.enforce_hostname_verification: false
searchguard.ssl.transport.enable_openssl_if_available: true
searchguard.ssl.transport.resolve_hostname: false

searchguard.ssl.http.enabled: true
searchguard.ssl.http.keystore_filepath: node-1-keystore.jks
searchguard.ssl.http.keystore_password: node_es
searchguard.ssl.http.truststore_filepath: truststore.jks
searchguard.ssl.http.truststore_password: r_ca_honeycomb

searchguard.authcz.admin_dn:
  - CN=*,OU=client,O=client,L=test, C=de
  - CN=kirk,OU=client,O=client,L=test,C=DE
searchguard.ssl.http.clientauth_mode: NONE
  • Restart Elasticsearch.

    su elk
    /opt/soft/elasticsearch-5.5.1-guard/bin/elasticsearch -d

  • Initialise the Search Guard index by running sgadmin
    <span style="font-family:monospace;font-size:14px;">/opt/soft/elasticsearch-5.5.1-guard/plugins/search-guard-5/tools/sgadmin.sh -cd /opt/soft/elasticsearch-5.5.1-guard/plugins/search-guard-5/sgconfig/ -cn honeycomb-es-guard-5.5.1 -ks /opt/soft/elasticsearch-5.5.1-guard/config/kirk-keystore.jks -kspass ki_ca_1 -ts /opt/soft/elasticsearch-5.5.1-guard/config/truststore.jks -tspass r_ca_honeycomb –nhnv</span>

test result

curl -k -u admin:admin ‘https://localhost:9200/_searchguard/authinfo? pretty’

图

ELK framework after es installed Search Guard
图

Kibana modification steps

Install plug-ins

/opt/soft/kibana-5.5.1-linux-x86_64-guard/bin/kibana-plugin install file:///opt/soft/searchguard-kibana-5.5.1-4.zip

Kibana configuration

server.port: 5601

server.host: “0.0.0.0”

elasticsearch.url: “https://localhost:9200”

kibana.index: “.kibana”

elasticsearch.username: “kibanaserver”

elasticsearch.password: “kibanaserver”

elasticsearch.ssl.verificationMode: none

  • start kibana

/opt/soft/kibana-5.5.1-linux-x86_64-guard/bin/kibana &

  • Access page

图

Logstash modification steps

Logstash was not installed successfully after it was configured according to official documents and consulted with Search Guard authorities. The operation process and problem phenomena are listed here. If any readers know about it, please feel free to comment.

  • Configure logstash to use HTTPS instead of HTTP.

For example, hosts => “https:// … “

  • If you want to verify the server’s certificate (optional, but recommended), you need to provide the path to the keystore containing your Root CA as well.

Logstash does not need to verify es’ certificate, so SSL _ certificate _ verification = > false is set.
For certificate verification, you need to configure the CA path and password.

  • Configure the logstash username and password.

Final configuration

output {
  elasticsearch {
        hosts => ["https://xx.xx.xx.32:9200"]
        index => "%{log_project}-%{+YYYY-MM-dd}"

        ssl => true
        ssl_certificate_verification => false
        #truststore => "/opt/soft/elasticsearch-5.5.1-guard/config/truststore.jks"
        #truststore_password => r_ca_honeycomb

        user => logstash
        password => logstash
  }
}
  • start logstash

    /opt/soft/logstash-2.4.1-guard/bin/logstash -f /opt/soft/logstash-2.4.1-guard/conf/honeycomb-logstash.conf

Problem

1. Search Guard recommends that logstash do not perform certificate verification and do not need to provide truststore and truststore_password. However, after pressing the operation, the process starts successfully, but there is still a fail prompt.


** WARNING ** Detected UNSAFE options in elasticsearch output configuration!
** WARNING ** You have enabled encryption but DISABLED certificate verification.
** WARNING ** To make sure your data is secure change :ssl_certificate_verification to true {:level=>:warn}
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target {:class=>"Manticore::ClientProtocolException", :level=>:error}
Pipeline main started

2. logstash always reports an error when sending data to es after startup.

Attempted to send a bulk request to Elasticsearch configured at '["https://xx.xx.xx.32:9200"]',
 but an error occurred and it failed! Are you sure you can reach elasticsearch from this machine using the configuration provided? 
{:error_message=>"PKIX path building failed: 
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested 
target", :error_class=>"Manticore::ClientProtocolException", :backtrace=>["/opt/soft/logstash-
2.4.1-guard/vendor/bundle/jruby/1.9/gems/manticore-0.6.0-java/lib/manticore/response.rb:37:in `initialize'", 
"org/jruby/RubyProc.java:281:in `call'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/manticore-0.6.0-java/lib/manticore/response.rb:79:in `call'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/manticore-0.6.0-java/lib/manticore/response.rb:256:in `call_once'",
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/manticore-0.6.0-java/lib/manticore/response.rb:153:in `code'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/elasticsearch-transport-1.1.0/lib/elasticsearch/transport/transport/http/manticore.rb:84:in `perform_request'",
"org/jruby/RubyProc.java:281:in `call'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/elasticsearch-transport-1.1.0/lib/elasticsearch/transport/transport/base.rb:257:in `perform_request'",
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/elasticsearch-transport-1.1.0/lib/elasticsearch/transport/transport/http/manticore.rb:67:in `perform_request'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/elasticsearch-transport-1.1.0/lib/elasticsearch/transport/client.rb:128:in `perform_request'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/elasticsearch-api-1.1.0/lib/elasticsearch/api/actions/bulk.rb:93:in `bulk'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-output-elasticsearch-2.7.1-java/lib/logstash/outputs/elasticsearch/http_client.rb:53:in `non_threadsafe_bulk'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-output-elasticsearch-2.7.1-java/lib/logstash/outputs/elasticsearch/http_client.rb:38:in `bulk'", 
"org/jruby/ext/thread/Mutex.java:149:in `synchronize'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-output-elasticsearch-2.7.1-java/lib/logstash/outputs/elasticsearch/http_client.rb:38:in `bulk'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-output-elasticsearch-2.7.1-java/lib/logstash/outputs/elasticsearch/common.rb:172:in `safe_bulk'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-output-elasticsearch-2.7.1-java/lib/logstash/outputs/elasticsearch/common.rb:101:in `submit'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-output-elasticsearch-2.7.1-java/lib/logstash/outputs/elasticsearch/common.rb:86:in `retrying_submit'", "/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-output-elasticsearch-2.7.1-java/lib/logstash/outputs/elasticsearch/common.rb:29:in `multi_receive'", "org/jruby/RubyArray.java:1653:in `each_slice'", "/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-output-elasticsearch-2.7.1-java/lib/logstash/outputs/elasticsearch/common.rb:28:in `multi_receive'", "/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.1-java/lib/logstash/output_delegator.rb:130:in `worker_multi_receive'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.1-java/lib/logstash/output_delegator.rb:114:in `multi_receive'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.1-java/lib/logstash/pipeline.rb:301:in `output_batch'", 
"org/jruby/RubyHash.java:1342:in `each'", "/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.1-java/lib/logstash/pipeline.rb:301:in `output_batch'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.1-java/lib/logstash/pipeline.rb:232:in `worker_loop'", 
"/opt/soft/logstash-2.4.1-guard/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.1-java/lib/logstash/pipeline.rb:201:in `start_workers'"], :level=>:error}

It seems that the purpose of looking at the log is unreachable, but on the logstash machine, it can be accessed by passing the command test.
curl -k -u logstash:logstash ‘https://xx.xx.xx.32:9200/_searchguard/authinfo? pretty’

图

In addition, es has a print error log.

[2017-08-24T10:39:20,834][ERROR][c.f.s.h.SearchGuardHttpServerTransport] [node-2] SSL Problem Received fatal alert: certificate_unknown
javax.net.ssl.SSLException: Received fatal alert: certificate_unknown
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) ~[?:?]
        at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1666) ~[?:?]
        at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1634) ~[?:?]
        at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1800) ~[?:?]
        at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1083) ~[?:?]
        at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:907) ~[?:?]
        at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:781) ~[?:?]
        at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624) ~[?:1.8.0_131]
        at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:254) ~[netty-handler-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1156) ~[netty-handler-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1078) ~[netty-handler-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) ~[netty-codec-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428) ~[netty-codec-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) ~[netty-codec-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:544) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:498) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) [netty-common-4.1.11.Final.jar:4.1.11.Final]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]
[2017-08-24T10:39:21,663][ERROR][c.f.s.h.SearchGuardHttpServerTransport] [node-2] SSL Problem Received fatal alert: certificate_unknown
javax.net.ssl.SSLException: Received fatal alert: certificate_unknown
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) ~[?:?]
        at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1666) ~[?:?]
        at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1634) ~[?:?]
        at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1800) ~[?:?]
        at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1083) ~[?:?]
        at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:907) ~[?:?]
        at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:781) ~[?:?]
        at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624) ~[?:1.8.0_131]
        at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:254) ~[netty-handler-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1156) ~[netty-handler-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1078) ~[netty-handler-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) ~[netty-codec-4.1.11.Final.jar:4.1.11.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428) ~[netty-codec-4.1.11.Final.jar:4.1.11.Final]

3. The error log of es above shows that es does not know the certificate (it should be a client certificate), but it has been configured not to do client authentication. Why?

Es partial configuration

searchguard.ssl.http.clientauth_mode: NONE

Summary

Although the communication between logstash and es has not been successful for the time being, some experience and achievements have been accumulated in the process of trying to open es permissions.

  1. Using a method similar to curl in this article (http request), use es service directly
  2. How does es with Search Guard provide domain name access to realize back-end multipoint service/routing?

Nginx can handle https requests from outside, but currently it does not support https proxy, i.e. nginx cannot access https service at the back end. If you still use Search Guard, you can consider using a four-tier load balancer lvs or a hardware load balancer to transmit the request to the back-end server. In addition, Squid is recommended in Zhihu’s articles.

References

https://floragunn.com/

https://github.com/floragunnc …

https://github.com/floragunnc …

https://github.com/floragunnc …

https://github.com/floragunnc …

https://github.com/floragunnc …

https://github.com/floragunnc …

https://forum.nginx.org/read ….

https://www.zhihu.com/questio …

Author: Honeycomb Team

Yixin Institute of Technology