Elasticsearch 安全和权限管理

Elasticsearch 安全和权限管理

一、身份验证

Elasticsearch 支持多种身份验证方式,包括基本身份验证、LDAP 身份验证、Active Directory 身份验证和 SAML 身份验证等。

1.1、基本身份验证

1、修改配置文件重启
修改配置文件config/elasticsearch.yml,写入以下配置:

xpack.security.enabled: true
discovery.type: single-node
xpack.security.transport.ssl.enabled: true

2、设置密码

./bin/elasticsearch-setup-passwords interactive

会为4个用户设置密码:
elastic, kibana, logstash_system,beats_system
其中:

elastic 账号:内置的超级用户,拥有 superuser 角色。
kibana 账号:用来连接 elasticsearch 并与之通信。Kibana 服务器以该用户身份提交请求以访问集群监视 API 和 .kibana 索引,不能访问 index。
logstash_system 账号:用户 Logstash 在 Elasticsearch 中存储监控信息时使用。

3、修改密码
以下命令将 elastic 密码修改为 “123456”:

curl -H "Content-Type:application/json" -XPOST -u elastic 'http://127.0.0.1:9200/_xpack/security/user/elastic/_password' -d '{ "password" : "123456" }'

1.2、基于令牌的身份验证

1、检查许可证类型:
确认你当前的 Elasticsearch 许可证类型。可以通过以下命令检查当前许可证:

GET /_license

2、升级到合适的许可证:
试用许可证: 你可以申请一个免费的 30 天试用许可证,它包含所有的 X-Pack 功能。通过以下 API 请求来激活试用许可证:

POST /_license/start_trial?acknowledge=true

基于令牌的身份验证允许用户使用访问令牌(access token)来访问 Elasticsearch。访问令牌是一个短期有效的字符串,可以通过用户名和密码获取。在 Elasticsearch中,可以通过以下步骤配置基于令牌的身份验证:
1、获取访问令牌:

POST /_security/oauth2/token
{
“grant_type” : “password”,
“username” : “my_admin”,
“password” : “mypassword”
}

返回的响应中包含访问令牌:

{
    "access_token": "o5GwAxZDNXBXMEVhMlFBU2haOTFsamhzbG53",
    "type": "Bearer",
    "expires_in": 1200,
    "refresh_token": "o5GwAxY3RU1ZSE1VTFJ0cU5UV0tLSXdhdGp3"
}

2、使用访问令牌访问 Elasticsearch:

curl -H "Authorization: Bearer AAEAAWVsYXN0aWNzZWFyY2gtdG9rZW4tZm9yLWV4YW1wbGU" http://localhost:9200/_cluster/health

1.3、基于证书的身份验证

基于证书的身份验证允许用户使用客户端证书来访问 Elasticsearch。在 Elasticsearch 中,可以通过以下步骤配置基于证书的身份验证:
elasticsearch.yml 配置文件中启用基于证书的身份验证:

xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.client_authentication: required

配置客户端证书和私钥:

xpack.security.http.ssl.keystore.path: “http.p12”
xpack.security.http.ssl.truststore.path: “http.p12”

使用客户端证书访问 Elasticsearch:

curl --cert client.crt --key client.key https://localhost:9200/_cluster/health

1.4 LDAP 身份验证

LDAP 身份验证是一种常见的身份验证方式,它使用 LDAP 目录来存储用户信息和密码。在 Elasticsearch 中,可以通过配置
elasticsearch.yml 文件来启用 LDAP 身份验证,例如:

xpack.security.authc:
  realms:
    ldap:
      type: ldap
      order: 1
      url: "ldap://ldap.example.com:389"
      bind_dn: "cn=admin,dc=example,dc=com"
      bind_password: "password"
      user_search:
        base_dn: "ou=people,dc=example,dc=com"
        filter: "(uid={0})"

这里的 ldap 表示使用 LDAP 进行身份验证,url 表示 LDAP 服务器的地址和端口号,bind_dn 和
bind_password 表示 LDAP 管理员的用户名和密码,user_search 表示用户信息的搜索条件。

1.5、Active Directory 身份验证

Active Directory 身份验证是一种常见的身份验证方式,它使用 Active Directory 目录来存储用户信息和密码。在
Elasticsearch 中,可以通过配置 elasticsearch.yml 文件来启用 Active Directory 身份验证,例如:

xpack.security.authc:
  realms:
    ad:
      type: active_directory
      order: 2
      url: "ldap://ad.example.com:389"
      bind_dn: "cn=admin,dc=example,dc=com"
      bind_password: "password"
      user_search:
        base_dn: "ou=people,dc=example,dc=com"
        filter: "(sAMAccountName={0})"

这里的 ad 表示使用 Active Directory 进行身份验证,其他配置项与 LDAP 身份验证类似。

1.6、SAML 身份验证

SAML 身份验证是一种基于标准的身份验证方式,它使用 SAML 协议来实现身份验证。在 Elasticsearch 中,可以通过配置
elasticsearch.yml 文件来启用 SAML 身份验证,例如:

xpack.security.authc:
  realms:
    saml:
      type: saml
      order: 3
      idp:
        metadata_path: "/path/to/idp-metadata.xml"
      sp:
        entity_id: "https://elasticsearch.example.com"
        acs: "https://elasticsearch.example.com/api/security/v1/saml"

这里的 saml 表示使用 SAML 进行身份验证,idp 表示身份提供者的元数据路径,sp 表示服务提供者的实体 ID 和断言消费服务的URL。

二、授权

授权是确定用户可以访问哪些资源和执行哪些操作的过程。在 Elasticsearch 中,可以通过角色和权限来实现授权。

2.1、角色和权限

在 Elasticsearch 中,角色是一组权限的集合,权限是一组允许或拒绝执行特定操作的规则。角色可以分配给用户,以便控制用户可以访问的资源和执行的操作。
Elasticsearch 提供了一些预定义的角色,例如:

  • superuser:具有所有权限的用户,可以执行任何操作。
  • kibana_admin:具有管理 Kibana 的权限,可以创建和管理仪表板、可视化等。
  • monitoring_user:具有访问监控数据的权限,可以查看 Elasticsearch 集群的性能和状态。

2.2、创建自定义角色

除了预定义的角色外,还可以创建自定义角色。例如,创建一个名为 read_only 的角色,只允许用户读取索引中的数据:

PUT /_security/role/read_only
{
  "indices": [
    {
      "names": [ "*" ],
      "privileges": [ "read" ]
    }
  ]
}

创建一个名为 index_manager 的角色,允许用户创建和删除索引,但不能对数据进行读写操作:

PUT /_security/role/index_manager
{
  "indices": [
    {
      "names": [ "*" ],
      "privileges": [ "create_index", "delete_index" ]
    }
  ]
}

2.3、分配角色给用户

创建角色后,可以将其分配给用户。例如,将 read_only 角色分配给名为 my_user 的用户:

POST /_security/user/my_user
{
  "password" : "mypassword",
  "roles" : [ "read_only" ],
  "full_name" : "My User"
}

现在,my_user 只能读取索引中的数据,无法执行其他操作,如创建或删除索引。

2.4、使用角色模板

角色模板是一种动态生成角色的方法,可以根据用户的属性来生成角色。例如,创建一个名为 user_specific_index
的角色模板,允许用户访问其用户名作为前缀的索引:

PUT /_security/role/user_specific_index
{
  "indices": [
    {
      "names": [ "{user.name}_*" ],
      "privileges": [ "read", "write" ]
    }
  ]
}

现在,名为 john 的用户可以访问 john_* 索引,而名为 jane 的用户可以访问 jane_* 索引。

2.5、使用 API 键进行授权

API 键是一种用于授权的机制,允许用户使用 API 键来访问 Elasticsearch,而无需提供用户名和密码。API
键可以具有与用户相同或更少的权限。要创建 API 键,请执行以下操作:

POST /_security/api_key
{
  "name": "my_api_key",
  "role_descriptors": {
    "read_only": {
      "indices": [
        {
          "names": [ "*" ],
          "privileges": [ "read" ]
        }
      ]
    }
  }
}

返回的响应中包含 API 键:

{
  "id" : "VuaCfGcBCdbkQmijuKPS",
  "name" : "my_api_key",
  "api_key" : "ui2lp2axTNmsyakw9tvNnw"
}

使用 API 键访问 Elasticsearch:

curl -H "Authorization: ApiKey VuaCfGcBCdbkQmijuKPS:ui2lp2axTNmsyakw9tvNnw" http://localhost:9200/_cluster/health

2.6、访问控制

基于角色的访问控制(RBAC)是一种授权策略,通过将权限分配给角色,然后将角色分配给用户来实现。在 Elasticsearch 中,可以使用 RBAC来控制用户对索引、文档和字段的访问权限。

2.6.1、索引级别的访问控制

在 Elasticsearch 中,可以为角色分配特定索引的访问权限。例如,创建一个名为 logs_read 的角色,只允许用户读取名为
logs-* 的索引:

PUT /_security/role/logs_read
{
  "indices": [
    {
      "names": [ "logs-*" ],
      "privileges": [ "read" ]
    }
  ]
}

将 logs_read 角色分配给名为 log_viewer 的用户:

POST /_security/user/log_viewer
{
  "password" : "mypassword",
  "roles" : [ "logs_read" ],
  "full_name" : "Log Viewer"
}

现在,log_viewer 用户只能读取 logs-* 索引,无法访问其他索引。
配置 elasticsearch.yml 文件方式:

xpack.security.authz:
  roles:
    admin:
      cluster:
        - all
      indices:
        - names: '*'
          privileges:
            - all
    user:
      cluster:
        - monitor
      indices:
        - names: 'logs-*'
          privileges:
            - read

这里的 admin 和 user 表示角色名称,cluster 表示集群级别的权限,indices 表示索引级别的权限。在定义完角色和权限后,可以将用户分配到不同的角色,例如:

POST /_security/user/john/_roles
{
  "roles": ["admin"]
}

这里的 john 表示用户名,admin 表示要分配的角色名称。

2.6.2 字段级别的访问控制 (Field-Level Security, FLS)

字段级别的访问控制(FLS)允许您限制用户访问文档中特定字段的权限。例如,创建一个名为 logs_read_sensitive 的角色,只允许用户读取 logs-* 索引中的 timestamp 和 message 字段:

PUT /_security/role/logs_read_sensitive
{
  "indices": [
    {
      "names": [ "logs-*" ],
      "privileges": [ "read" ],
      "field_security" : {
        "grant" : [ "timestamp", "message" ]
      }
    }
  ]
}

将 logs_read_sensitive 角色分配给名为 sensitive_log_viewer 的用户:

POST /_security/user/sensitive_log_viewer
{
  "password" : "mypassword",
  "roles" : [ "logs_read_sensitive" ],
  "full_name" : "Sensitive Log Viewer"
}

现在,sensitive_log_viewer 用户只能访问 logs-* 索引中的 timestamp 和 message 字段,无法访问其他字段。

配置 elasticsearch.yml 文件方式:

xpack.security.field_level_security:
  enabled: true
  grant:
    - field: "user"
      value: "john"
      except: ["password"]

这里的 enabled 表示是否启用字段级别的访问控制,grant 表示允许访问的字段和值。在定义完字段级别的访问控制后,可以将其应用到索引中,例如:

PUT /logs
{
  "mappings": {
    "properties": {
      "user": {
        "type": "text",
        "fielddata": true,
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      },
      "password": {
        "type": "text",
        "fielddata": true,
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      }
    }
  },
  "settings": {
    "index": {
      "query": {
        "default_field": "user"
      },
      "security": {
        "field_level_security": {
          "grant": [
            {
              "field": "user",
              "value": "john",
              "except": ["password"]
            }
          ]
        }
      }
    }
  }
}

这里的 logs 表示索引名称,user 和 password 表示字段名称。在定义完索引后,可以使用查询 DSL 来访问索引中的数据,例如:

GET /logs/_search
{
  "query": {
    "match": {
      "user": "john"
    }
  }
}

2.6.3、文档级别的访问控制 (Document-Level Security, DLS)

文档级别的访问控制(DLS)允许您限制用户访问特定文档的权限。例如,创建一个名为 logs_read_team1 的角色,只允许用户读取 logs-* 索引中 team 字段值为 team1 的文档:

PUT /_security/role/logs_read_team1
{
  "indices": [
    {
      "names": [ "logs-*" ],
      "privileges": [ "read" ],
      "query": {
        "term": { "team": "team1" }
      }
    }
  ]
}

将 logs_read_team1 角色分配给名为 team1_log_viewer 的用户:

POST /_security/user/team1_log_viewer
{
  "password" : "mypassword",
  "roles" : [ "logs_read_team1" ],
  "full_name" : "Team1 Log Viewer"
}

现在,team1_log_viewer 用户只能访问 logs-* 索引中 team 字段值为 team1 的文档,无法访问其他文档。

2.6.4、IP 白名单

您可以通过配置 Elasticsearch 的网络层来限制哪些 IP 地址可以访问 Elasticsearch。这可以通过在 elasticsearch.yml 配置文件中设置 http.host 和 http.publish_host 参数来实现。
例如,只允许来自 IP 地址 192.168.1.100 的请求访问 Elasticsearch:

http.host: 192.168.1.100
http.publish_host: 192.168.1.100

请注意,这种方法只限制了哪些 IP 地址可以访问 Elasticsearch,而不限制用户可以执行的操作。因此,建议将 IP
白名单与其他访问控制方法(如基于角色的访问控制)结合使用。

2.6.5、匿名访问

Elasticsearch 支持配置匿名访问,允许未经身份验证的用户访问
Elasticsearch。匿名用户将被分配一个或多个预定义的角色,以限制其访问权限。
要启用匿名访问,请在 elasticsearch.yml 配置文件中添加以下配置:

xpack.security.authc:
  anonymous:
    username: _anonymous
    roles: read_only
    authz_exception: true

在此示例中,匿名用户将被分配 read_only 角色,只能读取索引中的数据。请注意,启用匿名访问可能会导致安全风险,因此请谨慎使用。

2.6.6、跨集群复制 (Cross-Cluster Replication, CCR)

跨集群复制(CCR)是一种在多个 Elasticsearch 集群之间同步数据的方法。通过CCR,可以将数据从一个集群(称为领导者集群)复制到另一个集群(称为追随者集群)。这可以用于实现地理冗余、负载均衡和数据访问控制。
在 CCR 中,可以为追随者集群中的用户分配不同的角色和权限,以限制其对领导者集群中的数据的访问。例如,可以允许追随者集群中的用户只读取特定索引,而不允许他们修改数据或访问其他索引。

要配置 CCR,请按照以下步骤操作:
1、在领导者集群和追随者集群中启用 CCR:

xpack.security.enabled: true
xpack.ccr.enabled: true

2、在追随者集群中创建一个远程集群连接,指向领导者集群:

cluster.remote.leader_cluster:
seeds: [“leader_cluster_ip:9300”]

3、在追随者集群中创建一个跟随索引,以复制领导者集群中的数据:

PUT /follower_index/_ccr/follow
{
“remote_cluster”: “leader_cluster”,
“leader_index”: “leader_index”
}

4、为追随者集群中的用户分配角色和权限,以限制其对领导者集群中的数据的访问。

总之,Elasticsearch 提供了多种访问控制功能,包括基于角色的访问控制、字段级别的访问控制和文档级别的访问控制。通过正确配置这些功能,可以确保 Elasticsearch 系统的安全性和满足企业级应用的需求。

三、加密

为了保护数据的安全和隐私,Elasticsearch 提供了多种加密功能,包括传输层安全(TLS)和数据加密。

3.1、传输层安全(TLS)

传输层安全(TLS)是一种加密协议,用于在网络上保护数据的传输。在 Elasticsearch 中,可以通过以下步骤启用 TLS:
1、生成证书和私钥,可以使用 Elasticsearch 的 elasticsearch-certutil 工具生成自签名证书。
2、在 elasticsearch.yml 配置文件中启用 TLS:

xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: “elastic-certificates.p12”
xpack.security.transport.ssl.truststore.path: “elastic-certificates.p12”

3、重启 Elasticsearch 以应用更改。

3.2、数据加密

3.2.1、磁盘加密

Elasticsearch 本身不提供数据加密功能。但是,你可以使用文件系统级别的加密来保护 Elasticsearch 存储的数据。以下是一些建议:

  • 使用文件系统级别的加密,如 dm-crypt(Linux)、BitLocker(Windows)或 FileVault(macOS)。这些工具可以对 Elasticsearch 数据存储的文件进行加密,从而保护数据的安全。
  • 使用硬件加密,如自加密硬盘(Self-Encrypting Drives,SEDs)。这些硬盘具有内置的加密功能,可以在硬件级别对数据进行加密,提供更高的安全性和性能。

3.2.2、快照加密

Elasticsearch 支持创建快照以备份数据。为了保护快照中的数据,可以使用以下方法对快照进行加密:

  • 使用加密的存储服务,如 Amazon S3 或 Google Cloud Storage。这些服务提供了服务器端加密(Server-Side Encryption,SSE)功能,可以自动对存储的数据进行加密。
  • 使用客户端加密库,如 Amazon S3 Encryption Client 或 Google Cloud Storage Client Libraries。这些库提供了客户端加密(Client-Side Encryption,CSE)功能,可以在上传数据到存储服务之前对数据进行加密。

3.2.3、数据脱敏

数据脱敏是一种数据保护技术,通过对敏感数据进行处理,使其无法识别特定个人,同时保留数据的可用性。在 Elasticsearch
中,可以使用以下方法对数据进行脱敏:

  • 使用 Ingest Node 处理数据。Ingest Node 是 Elasticsearch 的一个功能,可以在数据索引之前对数据进行预处理。可以使用 Ingest Pipelines 和 Processors 对敏感数据进行脱敏处理,如删除、替换或哈希。
  • 使用 Logstash 处理数据。Logstash 是一个数据处理管道,可以从多种来源获取数据,对数据进行处理,然后将数据发送到 Elasticsearch。你可以使用 Logstash 的 Filters 对敏感数据进行脱敏处理,如删除、替换或哈希。

四、 审计

审计是记录和分析用户活动的过程,以确保系统的安全和合规性。Elasticsearch 提供了审计日志功能,可以记录用户执行的操作和产生的事件。
要启用审计日志,需要在 elasticsearch.yml 配置文件中添加以下配置:

xpack.security.audit.enabled: true

启用审计日志后,Elasticsearch 将记录用户执行的操作和产生的事件,并将其存储在日志文件中。可以通过 Kibana
或其他日志分析工具查看和分析审计日志。
总之,Elasticsearch 提供了一系列安全和权限管理功能,包括身份验证、授权、加密和审计。通过正确配置这些功能,可以确保 Elasticsearch
系统的安全和合规性。

参考:

https://blog.csdn.net/wangluoanquan111/article/details/136620283
https://www.cnblogs.com/Choleen/p/17053514.html

评论

暂无

添加新评论