Configure Kerberos for SMB/CIFS shares on a multi-node AI Data Engine deployment
Scan SMB/CIFS shares from a multi-node AI Data Engine (AIDE) deployment by using Kerberos authentication, so that no password is stored in the data source. Every node uses the same Kerberos configuration, and AI Data Engine refreshes the Kerberos ticket automatically.
If you have a single-node deployment, refer to Configure Kerberos for SMB/CIFS shares on a single-node AI Data Engine deployment.
Before you begin
-
You have AI Data Engine administrator privileges.
-
You have root access to every node and to the admin host. The admin host is the host where you mount the NFS export and create the keytab. It can be one of the nodes.
-
You have
kubectlaccess with cluster-admin privileges to your Kubernetes cluster from the admin host. If you use a kubeconfig file, set theKUBECONFIGenvironment variable to its path.
-
You have reviewed the networking requirements and the Kerberos and Active Directory requirements, including time synchronization and DNS.
-
You have verified that every node can reach the NFS server on TCP port 2049, the KDC on port 88, the file server on port 445, and your DNS server on port 53.
-
You have verified that NTP is active on every node and that each clock is synchronized with your domain controllers. To check, run
timedatectl.
-
You have a scan service account in Active Directory with read access to the SMB/CIFS shares you want to scan. The account must support AES256 encryption.
-
You have the following information:
Item Description Example KDC IP address
IP address of the domain controller that acts as the Kerberos key distribution center (KDC)
10.0.1.50KDC FQDN
Fully qualified domain name (FQDN) of the same domain controller
dc.corp.example.comDomain
Active Directory domain, in lowercase
corp.example.comRealm
Kerberos realm, which is the domain in uppercase
CORP.EXAMPLE.COMScan user
Service account with read access to the share
svc-aideScan password
Password of the scan user. You enter it only when you create the keytab.
Not applicable
File server FQDN
FQDN of the file server that hosts the share. Don't use an IP address.
filer.corp.example.comShare name
Name of the SMB/CIFS share
sharename
Kerberos files that AI Data Engine uses
You create the following files on the NFS export that holds the AI Data Engine configuration. In the following table, <export> is the root of that export.
| File | Location on the export |
|---|---|
Kerberos configuration |
|
Keytab |
|
Principal file |
|
Ticket cache directory |
|
Install the required packages
Kerberos scanning of an SMB/CIFS share fails on any node that doesn't have cifs-utils. The SMB/CIFS mount runs inside AI Data Engine, but the operating system of the node calls a cifs-utils component to set up the Kerberos session. Installing the package only on the admin host isn't enough.
| Package | Admin host | Every node |
|---|---|---|
|
Required |
Not required |
|
Required |
Required |
The Kerberos client tools provide the ktutil, kinit, and klist commands that you use to create and test the keytab.
-
On the admin host, install the Kerberos client tools and
cifs-utils.-
On Ubuntu or Debian, run the following commands.
apt-get update -qq apt-get install -y krb5-user cifs-utils -
On RHEL, CentOS, or Rocky Linux, run the following command.
dnf -y install krb5-workstation cifs-utils
-
-
On every other node, install
cifs-utils.-
On Ubuntu or Debian, run the following commands.
apt-get update -qq apt-get install -y cifs-utils -
On RHEL, CentOS, or Rocky Linux, run the following command.
dnf -y install cifs-utils
-
-
On every node, verify the installation.
which cifs.upcall
Mount the NFS export on the admin host
Get access to the shared configuration export from the admin host so you can create the Kerberos files where every node reads them.
-
Set the namespace that AI Data Engine runs in, and verify that the configuration volume claim is bound. The default namespace is
aide.export NAMESPACE="<namespace>" kubectl -n "${NAMESPACE}" get pvc aide-config-pvcThe status must be
Bound. -
Get the NFS server and the export path of the configuration volume. You specified these values when you deployed AI Data Engine.
kubectl get pv aide-config-pv -o jsonpath='NFS server: {.spec.nfs.server}{"\n"}Export path: {.spec.nfs.path}{"\n"}' -
Mount the export. Replace
<nfs_server>and<export_path>with the values from the previous step. The commands use/mnt/aide-configas the mount point. You can use any empty directory.mkdir -p /mnt/aide-config mount -t nfs <nfs_server>:<export_path> /mnt/aide-config -
Create the Kerberos directories.
export AIDE_CONFIG_ROOT="/mnt/aide-config" mkdir -p "${AIDE_CONFIG_ROOT}/kerberos/kerberos_refresher" mkdir -p "${AIDE_CONFIG_ROOT}/kerberos/kerberos_ccache"
Create the Kerberos files
Give AI Data Engine the configuration and credentials it needs to get Kerberos tickets for the scan service account. Run the following steps on the admin host.
-
Set the variables that the following commands use. Replace each value in angle brackets with your value, and don't include the angle brackets. Enter the realm in uppercase and the domain in lowercase.
export KDC_IP="<kdc_ip>" export KDC_FQDN="<kdc_fqdn>" export AD_DOMAIN="<domain>" export REALM="<REALM>" export SCAN_USER="<scan_user>" export FILE_SERVER_FQDN="<file_server_fqdn>" export SHARE_NAME="<share_name>" export KRB5_CONF_SOURCE="${AIDE_CONFIG_ROOT}/kerberos/krb5.conf" export KRB5_KEYTAB="${AIDE_CONFIG_ROOT}/kerberos/kerberos_refresher/datasense.keytab" export KRB5_CREDS="${AIDE_CONFIG_ROOT}/kerberos/kerberos_refresher/kerberos_creds.env"-
Verify that the variables are set.
echo "NAMESPACE=[${NAMESPACE}] AIDE_CONFIG_ROOT=[${AIDE_CONFIG_ROOT}] KDC_IP=[${KDC_IP}] REALM=[${REALM}] SCAN_USER=[${SCAN_USER}]"The variables exist only in the current shell session. If you open a new shell, set them again.
-
-
Create the Kerberos configuration file on the NFS export. AI Data Engine reads this file from the export. Don't create it in
/etc/krb5.confon the nodes.tee "${KRB5_CONF_SOURCE}" >/dev/null <<EOF [libdefaults] default_realm = ${REALM} dns_lookup_realm = false dns_lookup_kdc = false rdns = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true [realms] ${REALM} = { kdc = ${KDC_IP}:88 admin_server = ${KDC_IP}:749 } [domain_realm] .${AD_DOMAIN} = ${REALM} ${AD_DOMAIN} = ${REALM} EOF chmod 644 "${KRB5_CONF_SOURCE}"The file uses the KDC IP address so that Kerberos authentication doesn't depend on DNS.
-
Create a keytab for the scan service account.
-
Run
ktutil. -
At the
ktutilprompt, enter the following command. Replace<scan_user>and<REALM>with your values. Thektutilprompt doesn't use the shell variables.addent -password -p <scan_user>@<REALM> -k 1 -e aes256-cts-hmac-sha1-96 -
When
ktutilprompts for a password, enter the password of the scan user. -
At the
ktutilprompt, enter the following commands.wkt /tmp/krb5.keytab quit
-
-
Test the keytab. The
KRB5_CONFIGvariable points the Kerberos tools at the file on the export.export KRB5_CONFIG="${KRB5_CONF_SOURCE}" klist -kt /tmp/krb5.keytab kinit -kt /tmp/krb5.keytab "${SCAN_USER}@${REALM}" klist kdestroyThe second
klistcommand must show a valid ticket for the scan user. A ticket confirms that the keytab and the connection to the KDC work. Ifkinitfails, refer to Troubleshoot Kerberos authentication. -
Install the keytab, and then delete the temporary copy.
install -m 640 -g 4321 /tmp/krb5.keytab "${KRB5_KEYTAB}" rm -f /tmp/krb5.keytab -
Make the ticket cache directory writable by the ticket refresher.
chown root:4321 "${AIDE_CONFIG_ROOT}/kerberos/kerberos_ccache" chmod 770 "${AIDE_CONFIG_ROOT}/kerberos/kerberos_ccache"The ticket refresher runs as a root user with group ID 4321. It must be able to read the keytab and the principal file, and it must be able to write to the ticket cache directory.
-
Create the principal file. The
KRB5_RENEW_INTERVAL_Hvalue is the ticket renewal interval in hours.tee "${KRB5_CREDS}" >/dev/null <<EOF KRB5_USER=${SCAN_USER} KRB5_REALM=${REALM} KRB5_RENEW_INTERVAL_H=3 EOF chmod 640 "${KRB5_CREDS}" chgrp 4321 "${KRB5_CREDS}" -
Verify that the files are in place.
ls -l "${KRB5_CONF_SOURCE}" "${KRB5_KEYTAB}" "${KRB5_CREDS}"
Verify name resolution
AI Data Engine resolves the file server and the KDC by using the DNS settings of each node. Verify name resolution first, and change the DNS settings only if a name doesn't resolve on a node.
-
On every node, verify that the file server and the KDC resolve by FQDN. Replace the values with your file server FQDN and KDC FQDN.
nslookup <file_server_fqdn> nslookup <kdc_fqdn> -
Check the result.
-
If both names resolve to the correct IP addresses on every node, continue to Start the first ticket refresh.
-
If a name doesn't resolve on any node, complete Fix name resolution, and then return to this procedure.
-
Start the first ticket refresh
AI Data Engine refreshes the Kerberos ticket for the scan service account every three hours. Start the first refresh so that you can scan shares immediately.
|
|
Don't add a kinit entry to the host crontab. AI Data Engine refreshes tickets automatically.
|
-
On the admin host, start a refresh job, wait for it to complete, and display its log.
JOB="kerberos-refresh-$(date +%s)" kubectl -n "${NAMESPACE}" create job "${JOB}" --from=cronjob/ds-krb5-ticket-refresher kubectl -n "${NAMESPACE}" wait --for=condition=complete "job/${JOB}" --timeout=120s kubectl -n "${NAMESPACE}" logs "job/${JOB}" -
Verify that the shared ticket cache exists and has a recent timestamp.
ls -l "${AIDE_CONFIG_ROOT}/kerberos/kerberos_ccache/krb5cc_shared"
The job log shows that a ticket was acquired for the scan user.
Verify the Kerberos configuration
Before you add the share, verify that AI Data Engine can use the Kerberos files and resolve names. Because the mount service can run on more than one node, repeat the checks for a pod on each node. If you opened a new shell, set the NAMESPACE, FILE_SERVER_FQDN, and SHARE_NAME variables again.
-
List the mount service pods and the nodes that they run on.
kubectl -n "${NAMESPACE}" get pods -l app.kubernetes.io/name=ds-mount-server -o wide -
For each pod, run the following commands. Replace
<pod_name>with the name of the pod.POD=<pod_name> kubectl -n "${NAMESPACE}" exec "${POD}" -- nslookup "${FILE_SERVER_FQDN}" kubectl -n "${NAMESPACE}" exec "${POD}" -- klist kubectl -n "${NAMESPACE}" exec "${POD}" -- cat /etc/krb5.conf -
(Optional) Test a mount of the share by using Kerberos.
kubectl -n "${NAMESPACE}" exec "${POD}" -- sh -c "mount -t cifs -o sec=krb5,multiuser //${FILE_SERVER_FQDN}/${SHARE_NAME} /mnt && ls -l /mnt && umount /mnt"
On every node, the file server resolves to the correct IP address, klist shows a ticket for the scan user, and /etc/krb5.conf shows the contents of the Kerberos configuration file.
Add an SMB/CIFS data source that uses Kerberos
Add the share as a data source and start scans so AI Data Engine can begin analyzing its data.
-
From the AI Data Engine UI, select Configuration.
-
On the Scanned systems tab, select Add system.
-
Select File shares group.
-
Enter a name for the group.
-
Enter the share path in the format
<file_server_fqdn>/<share_name>. Replace the placeholders with your values. Don't use an IP address. -
For the authentication method, select Kerberos. Leave the user name and password fields empty.
-
Review your selections and select Confirm.
-
Select Activate scans for the new system.
For more information about connecting data sources, refer to Connect a data source to AI Data Engine.
Fix name resolution
Complete this procedure only if the file server or the KDC doesn't resolve by FQDN on a node. It sets your Active Directory DNS server as the only name server on every node.
|
|
Make your Active Directory DNS server the only name server on every node. The cluster picks one of the listed name servers at random, so a name server that can't resolve Active Directory names causes intermittent failures. |
-
Verify that your Active Directory DNS server also resolves external names.
-
Run the following command. Replace
<external_fqdn>with a name outside your domain that AI Data Engine must reach. For example, use an endpoint listed in Outbound internet access.nslookup <external_fqdn> "${KDC_IP}" -
If the command fails, ask your Active Directory administrator to enable DNS forwarding, and then repeat this step.
-
-
On every node, back up
/etc/resolv.conf, and set your Active Directory DNS server as the only name server. If you open a new shell on a node, set theKDC_IPvariable again.export KDC_IP="<kdc_ip>" cp /etc/resolv.conf /etc/resolv.conf.bak ORIG_SEARCH=$(grep '^search' /etc/resolv.conf.bak | head -1 | cut -d' ' -f2-) printf 'search %s\nnameserver %s\n' "${ORIG_SEARCH}" "${KDC_IP}" > /etc/resolv.conf -
On every node, prevent the network manager from overwriting the DNS settings after a restart.
-
On RHEL with NetworkManager, run the following commands.
mkdir -p /etc/NetworkManager/conf.d printf '[main]\ndns=none\n' > /etc/NetworkManager/conf.d/90-dns-none.conf systemctl reload NetworkManager -
On Ubuntu with systemd-resolved, run the following commands. Replace
<domain>with your domain.export AD_DOMAIN="<domain>" mkdir -p /etc/systemd/resolved.conf.d printf '[Resolve]\nDNS=%s\nDomains=%s\n' "${KDC_IP}" "${AD_DOMAIN}" > /etc/systemd/resolved.conf.d/ad-dns.conf systemctl restart systemd-resolved
-
-
From the admin host, restart CoreDNS so that AI Data Engine uses the new DNS settings. You run this step once for the cluster. CoreDNS forwards queries for names outside the cluster to the name servers in the
/etc/resolv.conffile of the node, so it must restart to pick up the change.-
Find the CoreDNS deployment.
kubectl -n kube-system get deployments | grep -i coredns -
Restart the deployment. Replace
<coredns_deployment>with the name from the previous command.kubectl -n kube-system rollout restart deployment <coredns_deployment> kubectl -n kube-system rollout status deployment <coredns_deployment> --timeout=120s
-
-
Verify name resolution again. Refer to Verify name resolution.
Update the Kerberos configuration file
If you replace krb5.conf on the NFS export after setup, for example by copying a new file over it, AI Data Engine continues to use the previous file until you restart the affected services.
-
On the admin host, restart the mount service, and delete the previous ticket refresh jobs.
kubectl -n "${NAMESPACE}" rollout restart daemonset ds-mount-server kubectl -n "${NAMESPACE}" delete job -l app.kubernetes.io/name=ds-krb5-ticket-refresher --ignore-not-found -
Start a new ticket refresh. Refer to Start the first ticket refresh.
Troubleshoot Kerberos authentication
Find the cause of a Kerberos failure and restore scanning of your SMB/CIFS shares.
| Symptom | Possible cause | Resolution |
|---|---|---|
The error IP not allowed with Kerberos appears when you add a share. |
The share path uses an IP address. |
Enter the share path as an FQDN. |
|
The password or realm is incorrect, the realm isn't in uppercase, the scan account doesn't support AES256 encryption, the admin host or a node can't reach the KDC on port 88, or the clock on a node differs from the KDC by more than the allowed skew. |
Verify the password and realm, and confirm that the account supports AES256 encryption. Open port 88 to the KDC, and confirm that NTP is active on every node. Then create the keytab again. |
The ticket refresh job fails, or no ticket cache is created. |
The keytab, principal file, or |
Verify that the files exist in the locations listed in Kerberos files that AI Data Engine uses. Verify that the keytab and the principal file have mode 640 and group 4321. Verify that the ticket cache directory is owned by |
Names fail to resolve intermittently, or they resolve on a node but not within AI Data Engine. |
A node lists more than one name server and one of them can't resolve Active Directory names, or CoreDNS wasn't restarted after you changed |
Remove all name servers except your Active Directory DNS server on every node, and restart CoreDNS. Refer to Fix name resolution. |
External names don't resolve within AI Data Engine after you set your Active Directory DNS server. |
The Active Directory DNS server doesn't forward external queries. |
Verify that |
Kerberos scanning works from one node but fails from others. The error mount error(2) appears, and |
|
Install |
The error mount error(126) appears. |
AI Data Engine can't read |
Verify that |
Changes to |
The file was replaced after setup, and AI Data Engine still uses the previous file. |
Refer to Update the Kerberos configuration file. |
The |
The Kerberos client tools aren't installed on the admin host. |
Install the Kerberos client tools. Refer to Install the required packages. |
The |
The network manager overwrites the file. |
Prevent the network manager from overwriting the DNS settings. Refer to Fix name resolution. |
Remove the Kerberos configuration
If you no longer scan SMB/CIFS shares with Kerberos, remove the data source and the Kerberos files.
-
From the AI Data Engine UI, delete the SMB/CIFS data source that uses Kerberos.
-
On the admin host, with the NFS export mounted at
/mnt/aide-config, delete the Kerberos files.rm -f /mnt/aide-config/kerberos/kerberos_refresher/datasense.keytab rm -f /mnt/aide-config/kerberos/kerberos_refresher/kerberos_creds.env rm -f /mnt/aide-config/kerberos/krb5.conf rm -f /mnt/aide-config/kerberos/kerberos_ccache/krb5cc_shared umount /mnt/aide-config -
If you changed the DNS settings, restore the original settings.
-
On every node, restore the backup of
/etc/resolv.conf.cp /etc/resolv.conf.bak /etc/resolv.conf -
On RHEL nodes where you added a NetworkManager configuration, remove it.
rm -f /etc/NetworkManager/conf.d/90-dns-none.conf systemctl reload NetworkManager -
On Ubuntu nodes where you added a systemd-resolved configuration, remove it.
rm -f /etc/systemd/resolved.conf.d/ad-dns.conf systemctl restart systemd-resolved -
From the admin host, restart CoreDNS. Replace
<coredns_deployment>with the name of the CoreDNS deployment.kubectl -n kube-system rollout restart deployment <coredns_deployment>
-