9.2 身份验证 (Authentication) Elasticsearch 安全:深入理解身份验证 (Authentication) 9.2 身份验证 (Authentication) 身份验证是验证用户身份的过程。在 Elasticsearch 中,身份验证确定用户是否是其声称的身份。 Elasticsearch 提供了多种身份验证方式,可以根据不同的安全需求进行选择。 9.2.1 Elasticsearch 内置身份验证 Elasticsearch 默认启用内置身份验证机制,它依赖于 用户和密码。 首次启动 Elasticsearch 时,需要设置 用户的密码。 9.2.1.1 设置内置用户密码 使用 工具可以设置内置用户的密码。 该命令会提示你为内置用户(如 、 等)设置密码。
9.2 身份验证 (Authentication)
身份验证是验证用户身份的过程。在 Elasticsearch 中,身份验证确定用户是否是其声称的身份。 Elasticsearch 提供了多种身份验证方式,可以根据不同的安全需求进行选择。
9.2.1 Elasticsearch 内置身份验证
Elasticsearch 默认启用内置身份验证机制,它依赖于 elasticsearch 用户和密码。 首次启动 Elasticsearch 时,需要设置 elasticsearch 用户的密码。
9.2.1.1 设置内置用户密码
使用 elasticsearch-setup-passwords 工具可以设置内置用户的密码。
./bin/elasticsearch-setup-passwords interactive
该命令会提示你为内置用户(如 elasticsearch、kibana_system 等)设置密码。选择 "interactive" 模式允许你逐个设置密码。设置完成后,这些密码将存储在 Elasticsearch 的密钥库中。
9.2.1.2 通过用户名和密码进行身份验证
设置密码后,可以使用用户名和密码进行身份验证。可以通过多种方式进行身份验证,例如:
HTTP Basic Authentication: 在 HTTP 请求头中包含 Authorization 字段,格式为 Basic <base64 encoded username:password>。
curl -u elastic:your_password -XGET "http://localhost:9200/_cat/indices?v"
Elasticsearch Java High Level REST Client: 在 Java 代码中使用 UsernamePasswordCredentials 类。
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("elastic", "your_password")); RestClientBuilder builder = RestClient.builder( new HttpHost("localhost", 9200, "http")) .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)); RestHighLevelClient client = new RestHighLevelClient(builder); // 使用 client 执行操作
9.2.2 身份验证领域 (Authentication Realms)
Elasticsearch 使用身份验证领域来配置和管理不同的身份验证方法。领域定义了如何验证用户身份。 Elasticsearch 提供了多种内置领域,并允许自定义领域。
9.2.2.1 内置领域类型
native 领域: 使用 Elasticsearch 内部用户数据库进行身份验证。 这就是之前使用 elasticsearch-setup-passwords 工具设置密码的用户。
file 领域: 从 users 和 users_roles 文件中读取用户信息进行身份验证。 这种方式不推荐用于生产环境,因为它安全性较低。
ldap 领域: 使用 LDAP 服务器进行身份验证。
active_directory 领域: 使用 Active Directory 服务器进行身份验证。
pki 领域: 使用客户端证书进行身份验证。
kerberos 领域: 使用 Kerberos 协议进行身份验证。
oidc 领域: 使用 OpenID Connect 协议进行身份验证。
saml 领域: 使用 SAML 协议进行身份验证。
9.2.2.2 配置领域
可以通过 elasticsearch.yml 文件配置领域。 例如,配置一个 LDAP 领域:
xpack.security.authc.realms.ldap1: type: ldap order: 2 url: "ldap://ldap.example.com:389" user_dn: "uid={0},ou=people,dc=example,dc=com" group_search: base_dn: "ou=groups,dc=example,dc=com" user_search: base_dn: "ou=people,dc=example,dc=com"
type: 指定领域类型,这里是 ldap。
order: 指定领域的优先级。数字越小,优先级越高。
url: LDAP 服务器的 URL。
user_dn: 用户 DN 模板。{0} 会被替换为用户名。
group_search: 配置如何搜索用户所属的组。
user_search: 配置如何搜索用户。
配置完成后,需要重启 Elasticsearch 节点。
9.2.2.3 领域顺序
领域顺序非常重要。 Elasticsearch 会按照配置的顺序尝试使用不同的领域进行身份验证。 如果一个领域验证失败,Elasticsearch 会尝试下一个领域。
9.2.3 使用 Kibana 进行身份验证
Kibana 也需要进行身份验证才能访问 Elasticsearch 集群。 Kibana 默认使用 Elasticsearch 的身份验证机制。 需要配置 Kibana 连接到 Elasticsearch 集群时使用的用户名和密码。
在 kibana.yml 文件中配置:
elasticsearch.hosts: ["http://localhost:9200"] elasticsearch.username: "kibana_system" elasticsearch.password: "your_kibana_system_password"
kibana_system 用户是 Kibana 用于与 Elasticsearch 通信的内置用户。 需要使用 elasticsearch-setup-passwords 工具为该用户设置密码。
9.2.4 代码实践:使用 LDAP 领域进行身份验证
以下是一个使用 LDAP 领域进行身份验证的 Java 代码示例:
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.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import java.io.IOException; public class LDAPAuthenticationExample { public static void main(String[] args) throws IOException { final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("ldap_user", "ldap_password")); // 替换为你的 LDAP 用户名和密码 RestClientBuilder builder = RestClient.builder( new HttpHost("localhost", 9200, "http")) .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)); RestHighLevelClient client = new RestHighLevelClient(builder); try { // 使用 client 执行操作,例如获取集群信息 System.out.println(client.info()); } catch (IOException e) { e.printStackTrace(); } finally { client.close(); } } }
注意:
需要在 elasticsearch.yml 文件中配置 LDAP 领域,如之前示例所示。
将 ldap_user 和 ldap_password 替换为你的 LDAP 用户名和密码。
确保 Elasticsearch 节点可以连接到 LDAP 服务器。
添加 Elasticsearch Java High Level REST Client 的依赖到你的项目中。
9.2.5 身份验证流程图
9.2.6 最佳实践
使用强密码: 为所有用户设置强密码,并定期轮换密码。
启用多因素身份验证 (MFA): 如果可能,启用 MFA 以提高安全性。
限制用户权限: 只授予用户所需的最小权限。
监控身份验证日志: 定期监控身份验证日志,以便检测异常活动。
选择合适的领域类型: 根据你的安全需求选择合适的领域类型。 LDAP 或 Active Directory 通常是企业环境的良好选择。
避免使用 file 领域: file 领域安全性较低,不推荐用于生产环境。
定期审查配置: 定期审查身份验证配置,确保其仍然满足你的安全需求。
9.2.7 总结
身份验证是 Elasticsearch 安全性的基础。 通过配置合适的身份验证领域和遵循最佳实践,可以有效地保护你的 Elasticsearch 集群免受未经授权的访问。 本文详细介绍了 Elasticsearch 中的身份验证机制,并提供了相关的代码实践和配置示例,希望能够帮助你更好地理解和配置 Elasticsearch 的安全性。记住,安全性是一个持续的过程,需要不断地监控和改进。