摘要

ElasticSearch是一个基于Lucene的分布式搜索和分析引擎。Elasticsearch能够以快速有效的方式对各种数据进行存储和索引。当前ES已经广泛应用于各个领域,包括应用程序搜索、网站搜索、企业搜索、日志处理和分析、基础设施指标和容器监测、应用程序性能监测、地理空间数据分析和可视化、安全分析、业务分析等。由于大部分ES没有增加安全策略,导致数据可能被别人随意访问。简单放一则案例:在线交易经纪商FBS曝光20TB数据,160亿条记录。所以我们使用ES的时候要注意数据安全问题。一般来说我们的ES如果运行在内网,相对来说是比较安全的。为了保证Elasticsearch数据安全,我们需要对ES进行鉴权设计。

Elasticsearch鉴权方式选择

ES鉴权方式包括但不限于以下几种方式:

  1. 关闭外网,使用Nginx配置转发;
  2. X-pack认证方式;
  3. shield权限管理(收费);
  4. SearchGuard,search-guard是shield的替代品,提供加密,身份验证和授权,基于search guard SSL;
    Nginx转发需要额外引入nginx,相当于在ES应用上层进行处理,不考虑;
    shield权限管理需要收费,只可以免费30天,也不考虑;
    SearchGuard需要额外引入组件,我们的安全需求级别不高,也不考虑;
    所以我们选择了X-pack认证方式,使用ES自带的工具组件来完成对Elasticsearch集群的安全访问,X-pack普通用户认证功能永久免费。

X-pack认证方式

X-Pack is an Elastic Stack extension that provides security, alerting, monitoring, reporting, machine learning, and many other capabilities. By default, when you install Elasticsearch, X-Pack is installed.

X-Pack是一个Elastic Stack的扩展组建,提供了安全、警报、监视、报告、机器学习和许多其他功能。默认情况下Elasticsearch安装就会安装X-Pack。
X-pack免费提供了的账号密码认证功能,可通过在elasticsearch.yml进行本地配置。也可以通过ES的security api进行设置。
X-pack提供基于LDAP/kerbors/SAML/AD等认证收费方式。

X-pack认证方式配置

单机版Elasticsearch认证

单机版Elasticsearch认证相对来说比较简单粗暴。

1. 启动X-pack安全配置

打开Elasticsearch根目录下config/elasticsearch.yml文件,将xpack.security.enabled值改为true,默认ES是关闭X-pack安全配置的。

# 开启xpack安全认证,默认为false
xpack.security.enabled: true

2. 重新启动ES

通过systemctl 重启 ES服务,并通过浏览器访问当前ES服务,会发现弹出了用户名密码输入框。因为已经启用了安全认证,所以需要用户名密码。

3. 为ES内置用户生成密码

为ES内置用户生成密码有两种方式:一是通过默认方式自动生成密码,一种是手动一个个用户输入密码;
设置默认密码命令:
./bin/elasticsearch-setup-passwords auto
手动输入密码命令:
./bin/elasticsearch-setup-passwords interactive
两种方式分别对内置用户:elastic、apm_system、kibana、logstash_system、beats_system、remote_monitoring_user,设置了密码。

4. 验证

通过浏览器访问当前ES服务,弹出用户名密码输入框,使用elastic用户及其密码进行登录。elastic用户拥有superadmin权限,自然包括web访问权限。

5.新增用户及授权

请参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api.html

集群版ES认证

elasticsearch集群开启鉴权步骤:

  1. 进入其中一台es安装机器,进入es安装目录(例如:/opt/elasticsearch-7.7.1),执行ll命令查看es所属用户,并执行su命令切换至es所属用户;
  2. 在es安装目录执行“./bin/elasticsearch-certutil ca”命令,生成CA证书;执行过程中需要输入CA的密码和输出文件,直接回车CA密码默认为空,输出文件位置为默认位置;
  3. 继续执行“./bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12”命令,需要输入CA密码时直接回车为空,需要输入文件位置默认为空,生成证书和私钥,执行完之后证书和私钥将会生成在上一步的elastic-stack-ca.p12文件中;
  4. 移动elastic-certificates.p12文件到config目录下,复制证书elastic-certificates.p12文件到集群其他机器es目录的config目录下,特别注意,是elastic-certificates.p12;
    使用es所属用户,编辑es安装目录下config/elasticsearch.yml文件,新增如下配置:
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate 
xpack.security.transport.ssl.keystore.path: /opt/elasticsearch-7.7.1/config/elastic-certificates.p12 
xpack.security.transport.ssl.truststore.path: /opt/elasticsearch-7.7.1/config/elastic-certificates.p12

所有集群机器都需要新增;

:/opt/elasticsearch-7.7.1/config/elastic-certificates.p12 需要改为es安装机器实际目录

  1. 执行“systemctl restart elasticsearch”重启集群所有es,稍等一会执行“systemctl status elasticsearch”查看是否重启成功,需要保证三台机器全部重启成功;(systemctl 命令切到root用户执行,执行完切回来)

  2. 在es的安装目录执行“./bin/elasticsearch-setup-passwords interactive”命令生成密码;需要对elastic、apm_system、kibana、logstash_system、beats_system、remote_monitoring_user等用户生成密码,我们密码统一用123456;

  • 报下面这个错,请稍等一会儿再试,表示223机器es还没有重启好:
Connection failure to: http://x.x.x.x:9200/_security/_authenticate?pretty failed: 拒绝连接 (Connection refused)`
  • 报下面这个错,表示集群没有全部重启成功
ERROR: Failed to set password for user [apm_system].

验证:

浏览器访问“http://${ip}:9200/_cluster/health?pretty”,输入用户:elastic密码:123456登陆验证集群是否开启x-pack认证成功,如果成功将会有类似如下返回:

{
  "cluster_name" : "ES-cluster",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 3,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 5,
  "active_shards" : 10,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}

注:${ip}需要改成实际es安装机器ip。

JDK版本错误

Caused by: java.security.UnrecoverableKeyException: Encrypt Private Key failed: unrecognized algorit 见博客

附一:java 连接ESdemo

依赖:

<dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>7.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.1.0</version>
        </dependency>

java client demo

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
import org.elasticsearch.client.RestHighLevelClient;
public class EsUtil {
    public static RestHighLevelClient getClient() {
        /** 用户认证对象 */
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        /** 设置账号密码 */
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("elastic", "123456"));
        /** 创建rest client对象 */
        RestClientBuilder builder = RestClient.builder(new HttpHost("127.0.0.1", 9200))
                .setHttpClientConfigCallback(new HttpClientConfigCallback() {
                    @Override
                    public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                        return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                    }
                });
        RestHighLevelClient client = new RestHighLevelClient(builder);
        return client;
    }
    
    /**
     * 单条保存  
     * @param index
     * @param id
     * @param m
     */
    public static void saveData(String index,String id,Map<String, Object> m){
        try {
            RestHighLevelClient client = getClient();
            
            IndexRequest indexRequest = new IndexRequest(index)
                .id( id)
                .source(m);
            client.index(indexRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    
    public static void main(String[] args) {
        Date d = new Date();
        String id = d.getTime()+"";
        
        Map<String, Object> m = new HashMap<String, Object>();
        m.put("id", id);
        m.put("area_id", 1);
        m.put("camera_id", 1);
        m.put("log_time","2019-08-01 11:11:11");
        m.put("age", 1);
        EsUtil.saveData("global_house_list",id,m);
    }
}

附二:

springboot内置es配置项示例:

#是否启用es
elasticsearch.enabled = true
# es集群名称
elasticsearch.clusterName = cluster-assetMap
#es数据库用户名
elasticsearch.userName = elastic
#es数据库密码
elasticsearch.password = 123456
# es host ip 地址(单机)
elasticsearch.hosts[0] = 10.x.x.171:9200
# es host ip 地址
elasticsearch.hosts[1] = 10.x.x.172:9200
# es host ip 地址
elasticsearch.hosts[2] = 10.x.x.173:9200
# es 请求方式
elasticsearch.scheme = http
# es 连接超时
elasticsearch.connectTimeOut = 1000
# es socket 连接超时
elasticsearch.socketTimeOut = 30000
# es 请求超时
elasticsearch.connectionRequestTimeOut = 500
# es 最大连接数
elasticsearch.maxConnectNum = 100
# es 每个路由的最大连接数
elasticsearch.maxConnectNumPerRoute = 100

参考:

  1. Set up X-Pack;
  2. Elasticsearch 安全功能入门;
  3. elasticsearch集群的安全认证模式;
  4. ElasticSearch X-Pack之用户认证;
  5. java xpack密码连接elasticsearch 7.1集群
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐