Active Directory 和 LDAP

Active Directory 和 LDAP 可用于身份验证和授权(分别是配置中的 authcauthz 部分)。身份验证检查用户是否输入了有效的凭据。授权检索用户的任何后端角色。

在大多数情况下,您会希望同时配置身份验证和授权。您也可以仅使用身份验证,并将从 LDAP 检索的用户直接映射到安全插件角色。

连接设置

要启用 LDAP 身份验证和授权,请将以下行添加到 config/udbsx-security/config.yml

内部用户数据库身份验证也应启用,因为 UDB-SX Dashboards 使用 kibanaserver 内部用户连接到 UDB-SX。

authc:
  internal_auth:
    order: 0
    description: "HTTP basic authentication using the internal user database"
    http_enabled: true
    transport_enabled: true
    http_authenticator:
      type: basic
      challenge: false
    authentication_backend:
      type: internal
  ldap:
    http_enabled: true
    transport_enabled: true
    order: 1
    http_authenticator:
      type: basic
      challenge: false
    authentication_backend:
      type: ldap
      config:
        ...
authz:
  ldap:
    http_enabled: true
    transport_enabled: true
    authorization_backend:
      type: ldap
      config:
      ...

身份验证和授权的连接设置是相同的,并添加到 config 部分。

主机名和端口

要配置 Active Directory 服务器的主机名和端口,请使用以下设置:

config:
  hosts:
    - primary.ldap.example.com:389
    - secondary.ldap.example.com:389

您可以在此处配置多个服务器。如果安全插件无法连接到第一个服务器,它会尝试按顺序连接到其余服务器。

超时设置

要配置到 Active Directory 服务器的连接和响应超时,请使用以下设置(值以毫秒为单位):

config:
  connect_timeout: 5000
  response_timeout: 0

如果您的服务器支持双因素身份验证(2FA),默认的超时设置可能导致登录错误。您可以增加 connect_timeout 以适应 2FA 过程。将 response_timeout 设置为 0(默认值)表示无限等待期。

绑定 DN 和密码

要配置安全插件在向服务器发出查询时使用的 bind_dnpassword,请使用以下设置:

config:
  bind_dn: cn=admin,dc=example,dc=com
  password: password

如果您的服务器支持匿名身份验证,bind_dnpassword 都可以设置为 null

TLS 设置

使用以下参数配置连接到服务器的 TLS:

config:
  enable_ssl: <true|false>
  enable_start_tls: <true|false>
  enable_ssl_client_auth: <true|false>
  verify_hostnames: <true|false>
名称 描述
enable_ssl 是否使用 LDAP over SSL (LDAPS)。
enable_start_tls 是否使用 STARTTLS。不能与 LDAPS 结合使用。
enable_ssl_client_auth 是否向 LDAP 服务器发送客户端证书。
verify_hostnames 是否验证服务器 TLS 证书的主机名。

证书验证

默认情况下,安全插件根据 udbsx.yml 中配置的根 CA 验证 LDAP 服务器的 TLS 证书,根 CA 可以是 PEM 证书或信任库:

plugins.security.ssl.transport.pemtrustedcas_filepath: ...
plugins.security.ssl.transport.truststore_filepath: ...

如果您的服务器使用由不同 CA 签名的证书,请将此 CA 导入您的信任库,或在每个节点上将其添加到受信任的 CA 文件中。

您也可以使用单独的根 CA(PEM 格式)。

为 LDAP 配置单独的根 CA 时,请确保将该设置包含在 LDAP config: 设置的所有实例中,包括配置的 authcauthz 选项。

要配置单独的根 CA,请使用以下配置选项之一:

config:
  pemtrustedcas_filepath: /full/path/to/trusted_cas.pem
config:
  pemtrustedcas_content: |-
    -----BEGIN CERTIFICATE-----
    MIID/jCCAuagAwIBAgIBATANBgkqhkiG9w0BAQUFADCBjzETMBEGCgmSJomT8ixk
    ARkWA2NvbTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUxGTAXBgNVBAoMEEV4YW1w
    bGUgQ29tIEluYy4xITAfBgNVBAsMGEV4YW1wbGUgQ29tIEluYy4gUm9vdCBDQTEh
    ...
    -----END CERTIFICATE-----
名称 描述
pemtrustedcas_filepath 包含您的 Active Directory/LDAP 服务器根 CA 的 PEM 文件的绝对路径。
pemtrustedcas_content 您的 Active Directory/LDAP 服务器的根 CA 内容。当 pemtrustedcas_filepath 已设置时不能使用。

客户端身份验证

如果使用 TLS 客户端身份验证,安全插件会发送节点的 PEM 证书,该证书在 udbsx.yml 中配置。设置以下配置选项之一:

config:
  pemkey_filepath: /full/path/to/private.key.pem
  pemkey_password: private_key_password
  pemcert_filepath: /full/path/to/certificate.pem

config:
  pemkey_content: |-
    -----BEGIN PRIVATE KEY-----
    MIID2jCCAsKgAwIBAgIBBTANBgkqhkiG9w0BAQUFADCBltETMBEGCgmSJomT8ixk
    ARkWA2NvbTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUxGTAXBgNVBAoMEEV4YW1w
    bGUgQ29tIEluYy4xJDAiBgNVBAsMG0V4YW1wbGUgQ29tIEluYy4gU2lnbmluZyBD
    ...
    -----END PRIVATE KEY-----
  pemkey_password: private_key_password
  pemcert_content: |-
    -----BEGIN CERTIFICATE-----
    MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHRZwzwGlP2FvL
    oEzNeDu2XnOF+ram7rWPT6fxI+JJr3SDz1mSzixTeHq82P5A7RLdMULfQFMfQPfr
    WXgB4qfisuDSt+CPocZRfUqqhGlMG2l8LgJMr58tn0AHvauvNTeiGlyXy0ShxHbD
    ...
    -----END CERTIFICATE-----
名称 描述
pemkey_filepath 包含证书私钥的文件的绝对路径。
pemkey_content 证书私钥的内容。当 pemkey_filepath 已设置时不能使用。
pemkey_password 私钥的密码(如果有)。
pemcert_filepath 客户端证书的绝对路径。
pemcert_content 客户端证书的内容。当 pemcert_filepath 已设置时不能使用。

启用的密码套件和协议

您可以限制 LDAP 连接允许的密码套件和 TLS 协议。例如,您可以仅允许强密码套件并将 TLS 版本限制为最新版本:

ldap:
  http_enabled: true
  transport_enabled: true
  ...
  authentication_backend:
    type: ldap
    config:
      enabled_ssl_ciphers:
        - "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"
        - "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"
      enabled_ssl_protocols:
        - "TLSv1.1"
        - "TLSv1.2"
名称 描述
enabled_ssl_ciphers 数组,启用的 TLS 密码套件。仅支持 Java 格式。
enabled_ssl_protocols 数组,启用的 TLS 协议。仅支持 Java 格式。

使用 Active Directory 和 LDAP 进行身份验证

要使用 Active Directory/LDAP 进行身份验证,首先在 config/udbsx-security/config.ymlauthc 部分配置相应的身份验证域:

authc:
  ldap:
    http_enabled: true
    transport_enabled: true
    order: 1
    http_authenticator:
      type: basic
      challenge: true
    authentication_backend:
      type: ldap
      config:
        ...

接下来,将您的 Active Directory/LDAP 服务器的连接设置添加到身份验证域的 config 部分:

config:
  enable_ssl: true
  enable_start_tls: false
  enable_ssl_client_auth: false
  verify_hostnames: true
  hosts:
    - ldap.example.com:8389
  bind_dn: cn=admin,dc=example,dc=com
  password: passw0rd

身份验证的工作原理是针对 LDAP 树的用户子树发出包含用户名的 LDAP 查询。

安全插件首先获取配置的 LDAP 查询,并将占位符 {0} 替换为用户凭据中的用户名。

usersearch: '(sAMAccountName={0})'

然后它针对配置的 userbase 下的整个子树执行此查询:

userbase: 'ou=people,dc=example,dc=com'

如果查询成功,安全插件会从 LDAP 条目中检索用户名。您可以指定安全插件应使用 LDAP 条目的哪个属性作为用户名:

username_attribute: uid

如果未设置此键或为 null,则使用 LDAP 条目的专有名称(DN)。

配置摘要

名称 描述
userbase 指定目录中存储用户信息的子树。
usersearch 安全插件在尝试对用户进行身份验证时执行的实际 LDAP 查询。变量 {0} 被替换为用户名。
username_attribute 安全插件使用目录条目的此属性来查找用户名。如果设置为 null,则使用 DN(默认)。

完整的身份验证示例

ldap:
  http_enabled: true
  transport_enabled: true
  order: 1
  http_authenticator:
    type: basic
    challenge: true
  authentication_backend:
    type: ldap
    config:
      enable_ssl: true
      enable_start_tls: false
      enable_ssl_client_auth: false
      verify_hostnames: true
      hosts:
        - ldap.example.com:636
      bind_dn: cn=admin,dc=example,dc=com
      password: password
      userbase: 'ou=people,dc=example,dc=com'
      usersearch: '(sAMAccountName={0})'
      username_attribute: uid

使用 Active Directory 和 LDAP 进行授权

要使用 Active Directory/LDAP 进行授权,首先在 config.ymlauthz 部分配置相应的授权域:

authz:
  ldap:
    http_enabled: true
    transport_enabled: true
    authorization_backend:
      type: ldap
      config:
      ...

授权是从 LDAP 服务器为已通过身份验证的用户检索后端角色的过程。这通常是您用于身份验证的相同服务器,但您也可以使用不同的服务器。唯一要求是用于获取角色的用户确实存在于 LDAP 服务器上。

由于安全插件始终检查用户是否存在于 LDAP 服务器中,因此您还必须在 authz 部分配置 userbaseusersearchusername_attribute

授权的工作方式与身份验证类似。安全插件针对 LDAP 树的角色子树发出包含用户名的 LDAP 查询。

作为替代方案,安全插件还可以获取定义为用户子树中用户条目直接属性的角色。

方法 1:查询角色子树

安全插件首先获取用于获取角色的 LDAP 查询(“rolesearch”),并替换查询中找到的任何变量。例如,对于标准的 Active Directory 安装,您将使用以下角色搜索:

rolesearch: '(member={0})'

您可以使用以下变量:

  • {0} 被替换为用户的 DN。

  • {1} 被替换为用户名,由 username_attribute 设置定义。

  • {2} 被替换为已通过身份验证用户的目录条目中的任意属性值。

变量 {2} 引用用户目录条目中的属性。您应该使用的属性由 userroleattribute 设置指定:

userroleattribute: myattribute

然后,安全插件针对配置的角色子树发出替换后的查询。搜索 rolebase 下的整个子树:

rolebase: 'ou=groups,dc=example,dc=com'

如果使用嵌套角色(属于其他角色成员的角色),可以配置安全插件来解析它们:

resolve_nested_roles: false

获取所有角色后,安全插件从角色条目的可配置属性中提取最终角色名称:

rolename: cn

如果未设置此选项,则使用角色条目的 DN。您现在可以使用此角色名称将其映射到一个或多个安全插件角色,如 roles_mapping.yml 中所定义。

方法 2:使用用户属性作为角色名称

如果角色存储为用户子树中用户条目的直接属性,则只需配置属性名称:

userrolename: roles

您可以配置多个属性名称:

userrolename: roles, otherroles

此方法可以与查询角色子树结合使用。安全插件从用户的角色属性中获取角色,然后执行角色搜索。

如果您不使用或没有角色子树,可以完全禁用角色搜索:

rolesearch_enabled: false

控制 LDAP 用户属性

默认情况下,安全插件读取所有 LDAP 用户属性,并使它们可用于索引名称变量替换和 DLS 查询变量替换。如果您的 LDAP 条目具有大量属性,您可能希望控制哪些属性应被提供。属性越少,性能越好。

请注意,此设置在 config.yml 文件中的身份验证 authc 部分进行。

名称 描述
custom_attr_allowlist 字符串数组。指定应提供给变量替换的 LDAP 属性。
custom_attr_maxval_len 整数。指定每个属性的最大允许长度。所有超过此值的属性都将被丢弃。值为 0 将完全禁用自定义属性。默认值为 36。

示例:

authc:
  ldap:
    http_enabled: true
    transport_enabled: true
    authentication_backend:
      type: ldap
      config:
        custom_attr_allowlist:
          - attribute1
          - attribute2
        custom_attr_maxval_len: 36
      ...

从角色查找中排除某些用户

如果您使用多种身份验证方法,从 LDAP 角色查找中排除某些用户是有意义的。

考虑典型的 UDB-SX Dashboards 设置的以下场景:所有 UDB-SX Dashboards 用户都存储在 LDAP/Active Directory 服务器中。

但是,您还有一个 UDB-SX Dashboards 服务器用户。UDB-SX Dashboards 使用此用户来管理存储的对象并执行监视和维护任务。您不希望将此用户添加到 Active Directory 安装中,而是希望将其存储在安全插件内部用户数据库中。

在这种情况下,将 UDB-SX Dashboards 服务器用户从 LDAP 授权中排除是有意义的,因为我们已经知道没有对应的条目。您可以使用 skip_users 配置设置来定义应跳过的用户。支持通配符和正则表达式:

skip_users:
  - kibanaserver
  - 'cn=Jane Doe,ou*people,o=TEST'
  - '/\S*/'

###(高级)从嵌套角色查找中排除角色

如果您的 LDAP 安装中的用户拥有大量角色,并且您还需要解析嵌套角色,您可能会遇到性能问题。

然而,在大多数情况下,并非所有用户角色都与 UDB-SX 和 UDB-SX Dashboards 相关。您可能只需要几个角色。在这种情况下,您可以使用嵌套角色过滤器功能来定义从用户角色列表中过滤掉的角色列表。支持通配符和正则表达式。

这仅在 resolve_nested_rolestrue 时有效:

nested_role_filter:
  - 'cn=Jane Doe,ou*people,o=TEST'
  - ...

配置摘要

名称 描述
rolebase 指定目录中存储角色/组信息的子树。
rolesearch 安全插件在尝试确定用户角色时执行的实际 LDAP 查询。您可以在此处使用三个变量(见下文)。
userroleattribute 用户条目中用于 {2} 变量替换的属性。
userrolename 如果用户的角色/组不存储在组子树中,而是作为用户目录条目的属性存储,请在此处定义此属性名称。
rolename 应被用作角色名称的角色条目属性。
resolve_nested_roles 布尔值。是否解析嵌套角色。默认值为 false
max_nested_depth 整数。当 resolve_nested_rolestrue 时,这定义了要遍历的嵌套角色的最大深度。设置较小的值可以减少从 LDAP 检索的数据量并提高身份验证速度,但代价是无法发现深度嵌套的角色。默认值为 30
skip_users 检索角色时应跳过的用户数组。支持通配符和正则表达式。
exclude_roles 检索角色时应排除的角色数组。支持通配符。
nested_role_filter 在解析嵌套角色之前应过滤的角色 DN 数组。支持通配符和正则表达式。
rolesearch_enabled 布尔值。启用或禁用角色搜索。默认值为 true
custom_attr_allowlist 字符串数组。指定应提供给变量替换的 LDAP 属性。
custom_attr_maxval_len 整数。指定每个属性的最大允许长度。所有超过此值的属性都将被丢弃。值为 0 将完全禁用自定义属性。默认值为 36。
custom_return_attributes 字符串数组。指定要从 LDAP 服务器请求哪些属性。

完整的授权示例

authz:
  ldap:
    http_enabled: true
    transport_enabled: true
    authorization_backend:
      type: ldap
      config:
        enable_ssl: true
        enable_start_tls: false
        enable_ssl_client_auth: false
        verify_hostnames: true
        hosts:
          - ldap.example.com:636
        bind_dn: cn=admin,dc=example,dc=com
        password: password
        userbase: 'ou=people,dc=example,dc=com'
        usersearch: '(uid={0})'
        username_attribute: uid
        rolebase: 'ou=groups,dc=example,dc=com'
        rolesearch: '(member={0})'
        userroleattribute: null
        userrolename: none
        rolename: cn
        resolve_nested_roles: true
        skip_users:
          - kibanaserver
          - 'cn=Jane Doe,ou*people,o=TEST'
          - '/\S*/'

配置多个用户和角色基础

要在 authc 和/或 authz 部分配置多个用户基础,请使用以下语法:

        ...
        bind_dn: cn=admin,dc=example,dc=com
        password: password
        users:
          primary-userbase:
             base: 'ou=people,dc=example,dc=com'
             search: '(uid={0})'
          secondary-userbase:
             base: 'cn=users,dc=example,dc=com'
             search: '(uid={0})'
        username_attribute: uid
        ...

类似地,在 authz 部分使用以下设置配置多个角色基础:

        ...
        username_attribute: uid
        roles:
          primary-rolebase:
            base: 'ou=groups,dc=example,dc=com'
            search: '(uniqueMember={0})'
          secondary-rolebase:
            base: 'ou=othergroups,dc=example,dc=com'
            search: '(member={0})'
        userroleattribute: null
        ...

完整的身份验证和授权,包含多个用户和角色基础的示例:

authc:
  ...
  ldap:
    http_enabled: true
    transport_enabled: true
    order: 1
    http_authenticator:
      type: basic
      challenge: true
    authentication_backend:
      type: ldap
      config:
        enable_ssl: true
        enable_start_tls: false
        enable_ssl_client_auth: false
        verify_hostnames: true
        hosts:
          - ldap.example.com:636
        bind_dn: cn=admin,dc=example,dc=com
        password: password
        users:
          primary-userbase:
             base: 'ou=people,dc=example,dc=com'
             search: '(uid={0})'
          secondary-userbase:
             base: 'cn=users,dc=example,dc=com'
             search: '(uid={0})'
        username_attribute: uid
authz:
  ldap:
    http_enabled: true
    transport_enabled: true
    authorization_backend:
      type: ldap
      config:
        enable_ssl: true
        enable_start_tls: false
        enable_ssl_client_auth: false
        verify_hostnames: true
        hosts:
          - ldap.example.com:636
        bind_dn: cn=admin,dc=example,dc=com
        password: password
        users:
          primary-userbase:
             base: 'ou=people,dc=example,dc=com'
             search: '(uid={0})'
          secondary-userbase:
             base: 'cn=users,dc=example,dc=com'
             search: '(uid={0})'
        username_attribute: uid
        roles:
          primary-rolebase:
            base: 'ou=groups,dc=example,dc=com'
            search: '(uniqueMember={0})'
          secondary-rolebase:
            base: 'ou=othergroups,dc=example,dc=com'
            search: '(member={0})'
        userroleattribute: null
        userrolename: none
        rolename: cn
        resolve_nested_roles: true