加载中

创建经典插件

经典插件为 Elasticsearch 提供了自定义身份验证、授权、评分等机制。

插件发布生命周期

经典插件要求您为每个新的 Elasticsearch 版本构建一个新版本。 安装插件和加载插件时,将检查此版本。 如果存在 elasticsearch.version 不正确的插件,Elasticsearch 将拒绝启动。

经典插件是 ZIP 文件,由 JAR 文件和一个名为 plugin-descriptor.properties 的元数据文件组成,该文件是描述插件的 Java 属性文件。

请注意,只有插件根目录下的 JAR 文件才会添加到插件的类路径中。 如果需要其他资源,请将其打包到资源 JAR 中。

Elasticsearch 存储库包含插件示例。 其中一些包括

这些示例提供了入门所需的基本框架。 有关如何编写插件的更多信息,我们建议查看现有插件的源代码以获取灵感。

使用 bin/elasticsearch-plugin install file:///path/to/your/plugin 安装您的插件以进行测试。 仅当 Java 插件位于 plugins/ 目录中时,它才会自动加载。

某些插件可能需要额外的授权

Elasticsearch 限制了执行某些安全敏感操作的能力,这是其授权安全机制的一部分(例如,限制远程代码执行 (RCE) 漏洞可能造成的损失)。

授权模型基于 Java 模块。 授予 Java 模块的授权允许该模块的代码执行与该授权相关的安全敏感操作。 例如,创建线程的能力仅限于具有 manage_threads 授权的模块; 同样,从文件系统读取文件的能力仅限于具有该特定文件的 files 授权的模块。

实际上,授权允许插件代码调用一组定义明确的相应 JDK 方法; 如果没有授权,对这些 JDK 方法的调用将被拒绝并抛出 NotEntitledException。 插件可以包含可选的 entitlement-policy.yaml 文件来定义模块和所需的授权。 插件请求的任何其他授权将以大警告显示给用户,并且用户在以交互方式安装插件时必须确认它们。 因此,最好避免请求任何虚假授权!

如果您使用的是 Elasticsearch Gradle 构建系统,请将此文件放在 src/main/plugin-metadata 中,它将在单元测试期间应用。

授权策略适用于您的所有插件 jar 文件(您自己的代码和第三方依赖项)。 您必须相应地编写您的策略文件。 例如,如果一个插件使用 Example API 客户端来执行网络操作,它将需要一个可能如下所示的策略

org.elasticsearch.example-plugin:
  - manage_threads
com.example.api.client:
  - set_https_connection_properties
  - outbound_network

请注意,网络相关的授权是如何授予给 com.example.api.client 模块的,因为执行敏感网络操作的代码位于 example-api-client 依赖项中。

如果您的插件不是模块化的,则所有授权都必须在 catch-all ALL-UNNAMED 模块名称下指定

ALL-UNNAMED:
  - manage_threads
  - set_https_connection_properties
  - outbound_network

当前在 Elasticsearch 中实施和强制执行的、可供插件使用的授权如下

允许代码调用创建或修改 Java 线程上的属性的方法,例如 Thread#startThreadGroup#setMaxPriority

注意

此授权很少是必要的。 您的插件应使用 Elasticsearch 线程池和执行器(请参阅 Plugin#getExecutorBuilders)而不是创建和管理自己的线程。 当在 ES 线程池上执行时,插件应避免修改线程名称、优先级、守护程序状态和上下文类加载器。

但是,许多支持异步操作的第三方库,例如 Apache HTTP 客户端,需要创建和管理自己的线程。 在这种情况下,请求此授权是有意义的。

示例

org.example.module:
  - manage_threads
  1. 如果插件是非模块化的,则为 'ALL-UNNAMED'

允许代码调用方法来建立网络连接。 Elasticsearch 默认不授予任何网络访问权限; 每个需要直接连接到外部资源(例如,上传或下载数据)的插件都必须请求此授权。

示例

org.example.module:
  - outbound_network
  1. 如果插件是非模块化的,则为 'ALL-UNNAMED'

允许代码调用方法来更改已建立的 HTTPS 连接上的属性。 虽然这通常是无害的(例如,google API 客户端使用它来修改他们刚刚创建的 HTTPS 连接),但这些方法允许代码更改任意连接。

示例

org.example.module:
  - set_https_connection_properties
  1. 如果插件是非模块化的,则为 'ALL-UNNAMED'

允许代码调用方法来监听传入连接,以便外部资源可以直接连接到您的插件。 只有在绝对必要时才应使用此授权(例如,如果您依赖的库需要它进行身份验证)。 授予它会使 Elasticsearch 节点更容易受到攻击。 此授权已弃用,可能会在未来版本的 Elasticsearch 中删除。

示例

org.example.module:
  - inbound_network
  1. 如果插件是非模块化的,则为 'ALL-UNNAMED'

允许代码加载本机库并调用受限方法。 此授权还允许授予它的模块的本机访问。 本机代码可能会更改 JVM 或规避访问检查,例如文件或网络限制。

示例

org.example.module:
  - load_native_libraries
  1. 如果插件是非模块化的,则为 'ALL-UNNAMED'

允许代码访问文件系统,以读取或写入授权字段指定的路径。 托管 Elasticsearch 的操作系统的文件系统可能包含敏感文件,例如凭据。 某些文件应该始终可以被 Elasticsearch 访问,但插件无法直接访问它们:Elasticsearch 强制某些文件只能由其核心代码读取,而其他一些文件则根本无法读取或写入。 插件始终被授予对 Elasticsearch 配置目录的 read 访问权限和对临时目录的 read_write 访问权限; 如果插件需要读取、写入或访问其他文件或目录,则必须通过此授权指定它们。

可以指定 3 种不同类型的文件授权

  • path 指定绝对路径
  • relative_path 指定相对路径。 该路径将通过 relative_to 字段解析,该字段用于限定相对路径。 它可以是特定的 Elasticsearch 目录(configdata),也可以是用户主目录 (home)(运行 Elasticsearch 的用户的主目录)
  • relative_path 指定通过 relative_to 字段解析的路径,该字段可以具有以下值
    • config:Elasticsearch 配置目录
    • data:Elasticsearch 数据目录
    • home:运行 Elasticsearch 的用户的主目录
  • path_setting 指定通过 Elasticsearch 设置定义的路径。 该路径可以是绝对路径或相对路径; 在后一种情况下,该路径将使用 basedir_if_relative 路径解析(该路径可以采用与 relative_to 相同的值)

这 3 种类型中的每一种都有一些额外的字段

  • mode(必需):可以是 readread_write
  • platform(可选):指示此项仅适用于一个平台,该平台可以是 linuxmacoswindows 之一。 在其他平台上,该项将被忽略。 如果未指定此字段,则该项适用于所有平台。
  • exclusive:此路径的访问权限是此插件独有的; 这意味着其他插件将无法访问它,即使它们具有通常会授予对该路径的访问权限的授权。

示例

org.example.module:
  - files:
    - path: "/absolute/path"
      mode: read
    - relative_path: "relative/file.txt"
      relative_to: data
      mode: read_write
    - path_setting: setting.name
      basedir_if_relative: data
      mode: read
  1. 如果插件是非模块化的,则为 'ALL-UNNAMED'

允许代码设置一个或多个系统属性(例如,通过调用 System#setProperty)。 授予此授权的代码可以更改 properties 字段中列出的属性。 通常,最好避免动态更改系统属性,因为这可能会影响稍后读取该属性的代码。 系统属性的全局性质意味着一个插件可能会影响另一个插件,具体取决于加载顺序。

示例

org.example.module:
  - write_system_properties:
      properties:
        - property.one
        - property.two
  1. 如果插件是非模块化的,则为 'ALL-UNNAMED'

有关更多信息,请查看 Elasticsearch 存储库中的授权README

© . All rights reserved.