跳到主要内容
版本:3.0.0

启用 Kerberos

启用 Kerberos

可以使用 Ambari UI 中的 启用 Kerberos 向导 或 REST API 为集群启用 Kerberos。

启用 Kerberos 向导

Ambari UI 中的 启用 Kerberos 向导 提供易于使用的向导界面,引导用户完成启用 Kerberos 的过程。

REST API

可以使用 Ambari REST API 通过以下 API 调用启用 Kerberos:

注意:

  • 根据需要修改身份验证凭据
    • curl ... -u username:password ...
    • 以下示例使用
      • username: admin
      • password: admin
  • 根据需要修改 Ambari Server 主机名和端口
    • curl ... http://HOST:PORT/api/v1/...
    • 以下示例使用
      • HOST: AMBARI_SERVER
      • PORT: 8080
  • 根据需要修改集群名称
    • curl ... http://.../CLUSTER/...
    • 以下示例使用
      • CLUSTER: CLUSTER_NAME
  • @./payload 表示 payload 数据存储在文件中,而不是内联声明
    • curl ... -d @./payload ...
    • 以下示例使用 ./payload,应将其替换为实际文件路径
    • payload 文件的内容列在 curl 语句下方

将 KERBEROS 服务添加到集群

curl -H "X-Requested-By:ambari" -u admin:admin -i -X POST http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME/services/KERBEROS

将 KERBEROS_CLIENT 组件添加到 KERBEROS 服务

curl -H "X-Requested-By:ambari" -u admin:admin -i -X POST http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME/services/KERBEROS/components/KERBEROS_CLIENT

创建并设置 KERBEROS 服务配置

curl -H "X-Requested-By:ambari" -u admin:admin -i -X PUT -d @./payload http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME

使用 MIT KDC 时的 payload 示例:

[
{
"Clusters": {
"desired_config": {
"type": "krb5-conf",
"tag": "version1",
"properties": {
"domains":"",
"manage_krb5_conf": "true",
"conf_dir":"/etc",
"content" : "[libdefaults]\n renew_lifetime = 7d\n forwardable = true\n default_realm = {{realm}}\n ticket_lifetime = 24h\n dns_lookup_realm = false\n dns_lookup_kdc = false\n default_ccache_name = /tmp/krb5cc_%{uid}\n #default_tgs_enctypes = {{encryption_types}}\n #default_tkt_enctypes = {{encryption_types}}\n{% if domains %}\n[domain_realm]\n{%- for domain in domains.split(',') %}\n {{domain|trim()}} = {{realm}}\n{%- endfor %}\n{% endif %}\n[logging]\n default = FILE:/var/log/krb5kdc.log\n admin_server = FILE:/var/log/kadmind.log\n kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n {{realm}} = {\n{%- if master_kdc %}\n master_kdc = {{master_kdc|trim()}}\n{%- endif -%}\n{%- if kdc_hosts > 0 -%}\n{%- set kdc_host_list = kdc_hosts.split(',') -%}\n{%- if kdc_host_list and kdc_host_list|length > 0 %}\n admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n{%- if kdc_host_list -%}\n{%- if master_kdc and (master_kdc not in kdc_host_list) %}\n kdc = {{master_kdc|trim()}}\n{%- endif -%}\n{% for kdc_host in kdc_host_list %}\n kdc = {{kdc_host|trim()}}\n{%- endfor -%}\n{% endif %}\n{%- endif %}\n{%- endif %}\n }\n\n{# Append additional realm declarations below #}"
}
}
}
},
{
"Clusters": {
"desired_config": {
"type": "kerberos-env",
"tag": "version1",
"properties": {
"kdc_type": "mit-kdc",
"manage_identities": "true",
"create_ambari_principal": "true",
"manage_auth_to_local": "true",
"install_packages": "true",
"encryption_types": "aes des3-cbc-sha1 rc4 des-cbc-md5",
"realm" : "EXAMPLE.COM",
"kdc_hosts" : "FQDN.KDC.SERVER",
"master_kdc" : "FQDN.MASTER.KDC.SERVER",
"admin_server_host" : "FQDN.ADMIN.KDC.SERVER",
"executable_search_paths" : "/usr/bin, /usr/kerberos/bin, /usr/sbin, /usr/lib/mit/bin, /usr/lib/mit/sbin",
"service_check_principal_name" : "${cluster_name}-${short_date}",
"case_insensitive_username_rules" : "false"
}
}
}
}
]

使用 Active Directory 时的 payload 示例:

[
{
"Clusters": {
"desired_config": {
"type": "krb5-conf",
"tag": "version1",
"properties": {
"domains":"",
"manage_krb5_conf": "true",
"conf_dir":"/etc",
"content" : "[libdefaults]\n renew_lifetime = 7d\n forwardable = true\n default_realm = {{realm}}\n ticket_lifetime = 24h\n dns_lookup_realm = false\n dns_lookup_kdc = false\n default_ccache_name = /tmp/krb5cc_%{uid}\n #default_tgs_enctypes = {{encryption_types}}\n #default_tkt_enctypes = {{encryption_types}}\n{% if domains %}\n[domain_realm]\n{%- for domain in domains.split(',') %}\n {{domain|trim()}} = {{realm}}\n{%- endfor %}\n{% endif %}\n[logging]\n default = FILE:/var/log/krb5kdc.log\n admin_server = FILE:/var/log/kadmind.log\n kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n {{realm}} = {\n{%- if master_kdc %}\n master_kdc = {{master_kdc|trim()}}\n{%- endif -%}\n{%- if kdc_hosts > 0 -%}\n{%- set kdc_host_list = kdc_hosts.split(',') -%}\n{%- if kdc_host_list and kdc_host_list|length > 0 %}\n admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n{%- if kdc_host_list -%}\n{%- if master_kdc and (master_kdc not in kdc_host_list) %}\n kdc = {{master_kdc|trim()}}\n{%- endif -%}\n{% for kdc_host in kdc_host_list %}\n kdc = {{kdc_host|trim()}}\n{%- endfor -%}\n{% endif %}\n{%- endif %}\n{%- endif %}\n }\n\n{# Append additional realm declarations below #}"
}
}
}
},
{
"Clusters": {
"desired_config": {
"type": "kerberos-env",
"tag": "version1",
"properties": {
"kdc_type": "active-directory",
"manage_identities": "true",
"create_ambari_principal": "true",
"manage_auth_to_local": "true",
"install_packages": "true",
"encryption_types": "aes des3-cbc-sha1 rc4 des-cbc-md5",
"realm" : "EXAMPLE.COM",
"kdc_hosts" : "FQDN.AD.SERVER",
"master_kdc" : "FQDN.MASTER.AD.SERVER",
"admin_server_host" : "FQDN.AD.SERVER",
"ldap_url" : "LDAPS://AD_HOST:PORT",
"container_dn" : "OU=....,....",
"executable_search_paths" : "/usr/bin, /usr/kerberos/bin, /usr/sbin, /usr/lib/mit/bin, /usr/lib/mit/sbin",
"password_length": "20",
"password_min_lowercase_letters": "1",
"password_min_uppercase_letters": "1",
"password_min_digits": "1",
"password_min_punctuation": "1",
"password_min_whitespace": "0",
"service_check_principal_name" : "${cluster_name}-${short_date}",
"case_insensitive_username_rules" : "false",
"create_attributes_template" : "{\n \"objectClass\": [\"top\", \"person\", \"organizationalPerson\", \"user\"],\n \"cn\": \"$principal_name\",\n #if( $is_service )\n \"servicePrincipalName\": \"$principal_name\",\n #end\n \"userPrincipalName\": \"$normalized_principal\",\n \"unicodePwd\": \"$password\",\n \"accountExpires\": \"0\",\n \"userAccountControl\": \"66048\"}"
}
}
}
}
]

使用 IPA 时的 payload 示例:

[
{
"Clusters": {
"desired_config": {
"type": "krb5-conf",
"tag": "version1",
"properties": {
"domains":"",
"manage_krb5_conf": "true",
"conf_dir":"/etc",
"content" : "[libdefaults]\n renew_lifetime = 7d\n forwardable = true\n default_realm = {{realm}}\n ticket_lifetime = 24h\n dns_lookup_realm = false\n dns_lookup_kdc = false\n default_ccache_name = /tmp/krb5cc_%{uid}\n #default_tgs_enctypes = {{encryption_types}}\n #default_tkt_enctypes = {{encryption_types}}\n{% if domains %}\n[domain_realm]\n{%- for domain in domains.split(',') %}\n {{domain|trim()}} = {{realm}}\n{%- endfor %}\n{% endif %}\n[logging]\n default = FILE:/var/log/krb5kdc.log\n admin_server = FILE:/var/log/kadmind.log\n kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n {{realm}} = {\n{%- if master_kdc %}\n master_kdc = {{master_kdc|trim()}}\n{%- endif -%}\n{%- if kdc_hosts > 0 -%}\n{%- set kdc_host_list = kdc_hosts.split(',') -%}\n{%- if kdc_host_list and kdc_host_list|length > 0 %}\n admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n{%- if kdc_host_list -%}\n{%- if master_kdc and (master_kdc not in kdc_host_list) %}\n kdc = {{master_kdc|trim()}}\n{%- endif -%}\n{% for kdc_host in kdc_host_list %}\n kdc = {{kdc_host|trim()}}\n{%- endfor -%}\n{% endif %}\n{%- endif %}\n{%- endif %}\n }\n\n{# Append additional realm declarations below #}"
}
}
}
},
{
"Clusters": {
"desired_config": {
"type": "kerberos-env",
"tag": "version1",
"properties": {
"kdc_type": "ipa",
"manage_identities": "true",
"create_ambari_principal": "true",
"manage_auth_to_local": "true",
"install_packages": "true",
"encryption_types": "aes des3-cbc-sha1 rc4 des-cbc-md5",
"realm" : "EXAMPLE.COM",
"kdc_hosts" : "FQDN.KDC.SERVER",
"master_kdc" : "FQDN.MASTER.KDC.SERVER",
"admin_server_host" : "FQDN.ADMIN.KDC.SERVER",
"executable_search_paths" : "/usr/bin, /usr/kerberos/bin, /usr/sbin, /usr/lib/mit/bin, /usr/lib/mit/sbin",
"service_check_principal_name" : "${cluster_name}-${short_date}",
"case_insensitive_username_rules" : "false"
}
}
}
}
]

创建 KERBEROS_CLIENT 主机组件

对每台主机执行一次,将 HOST_NAME 替换为实际值

curl -H "X-Requested-By:ambari" -u admin:admin -i -X POST -d '{"host_components" : [{"HostRoles" : {"component_name":"KERBEROS_CLIENT"}}]}' http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME/hosts?Hosts/host_name=HOST_NAME

安装 KERBEROS 服务和组件

curl -H "X-Requested-By:ambari" -u admin:admin -i -X PUT -d '{"ServiceInfo": {"state" : "INSTALLED"}}' http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME/services/KERBEROS

停止所有服务

curl -H "X-Requested-By:ambari" -u admin:admin -i -X PUT -d '{"RequestInfo":{"context":"Stop Service"},"Body":{"ServiceInfo":{"state":"INSTALLED"}}}' http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME/services

获取默认 Kerberos 描述符

curl -H "X-Requested-By:ambari" -u admin:admin -i -X GET http://AMBARI_SERVER:8080/api/v1/stacks/STACK_NAME/versions/STACK_VERSION/artifacts/kerberos_descriptor

获取自定义 Kerberos 描述符(如果之前已设置)

curl -H "X-Requested-By:ambari" -u admin:admin -i -X GET http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME/artifacts/kerberos_descriptor

设置 Kerberos 描述符

curl -H "X-Requested-By:ambari" -u admin:admin -i -X POST -d @./payload http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME/artifacts/kerberos_descriptor

Payload:

{
"artifact_data" : {
...
}
}

注意: Kerberos 描述符 payload 可以是完整的 Kerberos 描述符,也可以只是叠加到默认 Kerberos 描述符上的更新内容。

设置 KDC 管理员凭据

curl -H "X-Requested-By:ambari" -u admin:admin -i -X POST -d @./payload http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME/credentials/kdc.admin.credential

Payload:

{
"Credential" : {
"principal" : "admin/admin@EXAMPLE.COM",
"key" : "h4d00p&!",
"type" : "temporary"
}
}

注意: 应更新 principalkey(密码)值,使其与 KDC 管理员账号的正确凭据匹配。

注意: type 值可以是 temporarypersisted;但是,只有在之前已设置 Ambari 凭据存储时,该值才能为 persisted

启用 Kerberos

curl -H "X-Requested-By:ambari" -u admin:admin -i -X PUT -d @./payload http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME

Payload

{
"Clusters": {
"security_type" : "KERBEROS"
}
}

启动所有服务

curl -H "X-Requested-By:ambari" -u admin:admin -i -X PUT -d '{"ServiceInfo": {"state" : "STARTED"}}' http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME/services

其他技术信息

密码生成

使用 Active Directory 启用 Kerberos 时,Ambari 必须使用内部机制构建 keytab 文件。这是因为无法从 Active Directory 远程请求 keytab 文件。为了创建 keytab 文件,Ambari 需要知道每个相关 Kerberos 身份的密码。因此,Ambari 会根据需要设置或更新身份密码。

Active Directory 中每个由 Ambari 管理的账号的密码都是随机生成的,并且仅在内存中保存到设置账号密码和生成 keytab 文件所需的时间。密码使用以下可由用户设置的参数生成:

  • Password length (kerberos-env/password_length)
    • 默认值:20
  • Minimum number of lower-cased letters (kerberos-env/password_min_lowercase_letters)
    • 默认值:1
    • 字符集:abcdefghijklmnopqrstuvwxyz
  • Minimum number of upper-cased letters (kerberos-env/password_min_uppercase_letters)
    • 默认值:1
    • 字符集:ABCDEFGHIJKLMNOPQRSTUVWXYZ
  • Minimum number of digits (kerberos-env/password_min_digits)
    • 默认值:1
    • 字符集:1234567890
  • Minimum number of punctuation characters (kerberos-env/password_min_punctuation)
    • 默认值:1
    • 字符集:?.!$%^*()-_+=~
  • Minimum number of whitespace characters (kerberos-env/password_min_whitespace)
    • 默认值:0
    • 字符集:(space character)

执行以下算法:

  1. 创建一个用于存储密码字符的数组
  2. 对每个字符类别(大写字母、小写字母、数字……),从相应字符集中随机选择所需的最少数量,并存入数组
  3. 对于预期密码长度与已收集字符数之差,从随机选择的字符类别中随机选择字符,并存入数组,直到达到该数量
  4. 按预期密码长度从数组中随机取出字符,并追加到密码结果
  5. 返回生成的密码

使用 java.security.SecureRandom 类的静态实例(http://docs.oracle.com/javase/7/docs/api/java/security/SecureRandom.html)生成用于标识字符集内索引的随机整数。