Enabling Kerberos
Enabling Kerberos
Enabling Kerberos on the cluster may be done using the Enable Kerberos Wizard within the Ambari UI or using the REST API.
The Enable Kerberos Wizard
The Enable Kerberos Wizard, in the Ambari UI, provides an easy to use wizard interface that walks through the process of enabling Kerberos.
The REST API
It is possible to enable Kerberos using Ambari's REST API using the following API calls:
Notes:
- Change the authentication credentials as needed
curl ... -u username:password ...
- The examples below use
- username: admin
- password: admin
- Change the Ambari server host name and port as needed
curl ... http://HOST:PORT/api/v1/...
- The examples below use
- HOST: AMBARI_SERVER
- PORT: 8080
- Change the cluster name as needed
curl ... http://.../CLUSTER/...
- The examples below use
- CLUSTER: CLUSTER_NAME
- @./payload indicates the the payload data is stored in some file rather than declared inline
curl ... -d @./payload ...
- The examples below use
./payload
which should be replace with the actual file path - The contents of the payload file are indicated below the curl statement
Add the KERBEROS Service to cluster
curl -H "X-Requested-By:ambari" -u admin:admin -i -X POST http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME/services/KERBEROS
Add the KERBEROS_CLIENT component to the KERBEROS service
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
Create and set KERBEROS service configurations
curl -H "X-Requested-By:ambari" -u admin:admin -i -X PUT -d @./payload http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME
Example payload when using an MIT KDC:
[
{
"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"
}
}
}
}
]
Example payload when using an Active Directory:
[
{
"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\"}"
}
}
}
}
]
Example payload when using IPA:
[
{
"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"
}
}
}
}
]
Create the KERBEROS_CLIENT host components
Once for each host, replace 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
Install the KERBEROS service and components
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
Stop all services
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
Get the default Kerberos Descriptor
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
Get the customized Kerberos Descriptor (if previously set)
curl -H "X-Requested-By:ambari" -u admin:admin -i -X GET http://AMBARI_SERVER:8080/api/v1/clusters/CLUSTER_NAME/artifacts/kerberos_descriptor
Set the Kerberos Descriptor
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" : {
...
}
}
Note: The Kerberos Descriptor payload may be a complete Kerberos Descriptor or just the updates to overlay on top of the default Kerberos Descriptor.
Set the KDC administrator credentials
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"
}
}
Note: the principal and key (password) values should be updated to match the correct credentials for the KDC administrator account
Note: the type
value may be temporary
or persisted
; however the value may only be persisted
if Ambari's credential store has been previously setup.
Enable 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"
}
}
Start all services
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
Miscellaneous Technical Information
Password Generation
When enabling Kerberos using an Active Directory, Ambari must use an internal mechanism to build the keytab files. This is because keytab files cannot be requested remotely from an Active Directory. In order to create keytab files, Ambari needs to know the password for each relevant Kerberos identity. Therefore, Ambari sets or updates the identity's password as needed.
The password for each Ambari-managed account in an Active Directory is randomly generated and
stored only long enough in memory to set the account's password and generate the keytab file.
Passwords are generated using the following user-settable parameters:
- Password length (
kerberos-env/password_length
)- Default Value: 20
- Minimum number of lower-cased letters (
kerberos-env/password_min_lowercase_letters
)- Default Value: 1
- Character Set:
abcdefghijklmnopqrstuvwxyz
- Minimum number of upper-cased letters (
kerberos-env/password_min_uppercase_letters
)- Default Value: 1
- Character Set:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
- Minimum number of digits (
kerberos-env/password_min_digits
)- Default Value: 1
- Character Set:
1234567890
- Minimum number of punctuation characters (
kerberos-env/password_min_punctuation
)- Default Value: 1
- Character Set:
?.!$%^*()-_+=~
- Minimum number of whitespace characters (
kerberos-env/password_min_whitespace
)- Default Value: 0
- Character Set:
(space character)
The following algorithm is executed:
- Create an array to store password characters
- For each character class (upper-case letter, lower-case letter, digit, ...), randomly select the minimum number of characters from the relevant character set and store them in the array
- For the number of characters calculated as the difference between the expected password length and the number of characters already collected, randomly select a character from a randomly-selected character class and store it into the array
- For the number of characters expected in the password, randomly pull one from the array and append to the password result
- Return the generated password
To generate a random integer used to identify an index within a character set, a static instance of
the java.security.SecureRandom
class (http://docs.oracle.com/javase/7/docs/api/java/security/SecureRandom.html)
is used.