3. Préparer le déploiement des services

Cette partie comprend deux étapes partagées entre les services LDAP et NFSv4.

  • Définir un plan de nommage distinct pour les identités LDAP et NFSv4 (noms DNS, principaux Kerberos, fichiers keytab), conforme au principe de moindre privilège.

  • Mettre en place une autorité de certification commune aux deux services, pour sécuriser au niveau transport les échanges LDAP (StartTLS/ldaps://) et NFSv4 (xprtsec=tls:mtls).

3.1. Planifier les noms de services

Pour mutualiser les services tout en respectant le principe de moindre privilège, vous devez définir des noms spécifiques.

Q180.

Pourquoi utiliser des noms de service distincts NFSv4 et LDAP sur le même système ?

Il est essentiel d'émettre des identités distinctes pour les deux fonctions de sécurité, qu'elles soient portées par un service ou par la machine elle-même :

  • Trois principals Kerberos distincts :

    • nfs/nfs-srvr.lab.local@LAB.LOCAL, pour le service NFSv4

    • ldap/ldap-srvr.lab.local@LAB.LOCAL, pour le service LDAP

    • host/clnt.lab.local@LAB.LOCAL, pour la machine cliente elle-même, indépendamment de tout service (Q : Q192)

  • Si deux certificats X509 distincts sont signés par la même autorité, la maquette peut être transposée à un déploiement multi-hôtes ultérieurement.

Q181.

Comment assurer une résolution locale des noms d'hôtes pour le client et le serveur ?

Consultez les pages de manuel de la table de recherche statique des noms d'hôtes : man hosts.

Créez un script qui ajoute les enregistrements du client et du serveur dans le fichier /etc/hosts, tout en évitant les doublons.

Copiez l'exemple de code ci-dessous dans le fichier update-hosts.sh.

[Attention] Attention

Éditez le script pour utiliser vos adresses IPv4 et IPv6.

#!/usr/bin/env bash

set -euo pipefail

DOMAIN="lab.local"
HOSTS_FILE="/etc/hosts"

CLIENT_IPS=(
  "172.28.VVV.XXX"
  "2001:db8:VVVV::baad:caff:fefe:XXXX"
)
CLIENT_NAME="clnt"

SERVER_IPS=(
  "172.28.VVV.YYY"
  "2001:db8:VVVV::baad:caff:fefe:YYYY"
)
SERVER_NAME="srvr"
SERVER_ALIASES="ldap-srvr.${DOMAIN} nfs-srvr.${DOMAIN}"

if [[ ${EUID} -ne 0 ]]; then
  echo "This script must be run as root." >&2
  exit 1
fi

escape_sed_bre() {
  sed 's/[][\\.^$*]/\\&/g'
}

update_host_entry() {
  local ip="$1"
  local name="$2"
  local extra_aliases="${3-}"
  local escaped_ip
  escaped_ip=$(printf '%s\n' "${ip}" | escape_sed_bre)
  sed -i "/^${escaped_ip}[[:space:]]/d" "${HOSTS_FILE}"
  if [[ -n ${extra_aliases} ]]; then
    echo "${ip} ${name}.${DOMAIN} ${name} ${extra_aliases}" >>"${HOSTS_FILE}"
  else
    echo "${ip} ${name}.${DOMAIN} ${name}" >>"${HOSTS_FILE}"
  fi
}

for ip in "${CLIENT_IPS[@]}"; do
  update_host_entry "${ip}" "${CLIENT_NAME}"
done

for ip in "${SERVER_IPS[@]}"; do
  update_host_entry "${ip}" "${SERVER_NAME}" "${SERVER_ALIASES}"
done

Lancez le script sur le client et sur le serveur.

sudo bash update-hosts.sh

Testez la résolution locale des noms depuis le client.

host ldap-srvr.lab.local
ldap-srvr.lab.local is an alias for srvr.lab.local.
srvr.lab.local has address 172.28.VVV.YYY
srvr.lab.local has IPv6 address 2001:db8:VVVV::baad:caff:fefe:YYYY
host nfs-srvr.lab.local
nfs-srvr.lab.local is an alias for srvr.lab.local.
srvr.lab.local has address 172.28.VVV.XXX
srvr.lab.local has IPv6 address 2001:db8:VVVV::baad:caff:fefe:XXXX
for ip in 172.28.VVV.XXX 2001:db8:VVVV::baad:caff:fefe:XXXX; do
  host $ip
done
5.VVV.28.172.in-addr.arpa domain name pointer srvr.lab.local.
XXX.VVV.28.172.in-addr.arpa domain name pointer srvr.
XXX.VVV.28.172.in-addr.arpa domain name pointer nfs-srvr.lab.local.
XXX.VVV.28.172.in-addr.arpa domain name pointer ldap-srvr.lab.local.
XXXX.0.0.0.e.f.e.f.f.f.a.c.d.a.a.b.0.0.0.0.5.6.0.0.8.b.d.0.1.0.0.2.ip6.arpa domain name pointer srvr.lab.local.
XXXX.0.0.0.e.f.e.f.f.f.a.c.d.a.a.b.0.0.0.0.5.6.0.0.8.b.d.0.1.0.0.2.ip6.arpa domain name pointer srvr.
XXXX.0.0.0.e.f.e.f.f.f.a.c.d.a.a.b.0.0.0.0.5.6.0.0.8.b.d.0.1.0.0.2.ip6.arpa domain name pointer nfs-srvr.lab.local.
XXXX.0.0.0.e.f.e.f.f.f.a.c.d.a.a.b.0.0.0.0.5.6.0.0.8.b.d.0.1.0.0.2.ip6.arpa domain name pointer ldap-srvr.lab.local.

Q182.

Quelles sont les conséquences de l'utilisation de deux noms de service pour résoudre deux principaux Kerberos vers la même adresse IP ?

Le démon slapd n'expose pas le même keytab que le démon nfs-kernel-server.

Chaque service charge son principal depuis son fichier keytab (par défaut : /etc/krb5.keytab pour NFS et /etc/ldap/ldap.keytab pour LDAP). Les deux services peuvent ainsi cohabiter sur le même hôte sans partager leurs clés cryptographiques, ce qui respecte le principe de moindre privilège.

3.2. Définir les objets gérés par l'autorité de certification

Pour mutualiser la gestion des certificats, vous devez définir une CA commune aux deux services.

Q183.

L'autorité de certification OpenSSL générée pour le service NFS peut-elle être réutilisée pour le service LDAP ?

C’est précisément l'un des objectifs de la mutualisation. Une seule clé privée d'autorité (labCA.key) signe successivement deux paires (certificat, clé) : l'une pour nfs-srvr.lab.local, l'autre pour ldap-srvr.lab.local. Les clients (NFS et LDAP) n'ont alors qu'un seul fichier, labCA.crt, à installer en trust anchor dans /usr/local/share/ca-certificates/ puis à régénérer via update-ca-certificates.

Q184.

Comment répartir les certificats et les clés privées associées sur le serveur et le client ?

Proposez un tableau respectant la règle selon laquelle chaque extrémité de la session TLS détient sa propre clé privée, tandis que les certificats publics (y compris celui de l'autorité) sont partagés.

Tableau 3. Répartition des certificats et des clés privées pour les services LDAP et NFS mutualisés

Fichier Serveur : srvr.lab.local Client : clnt.lab.local
Autorité de certification commune
labCA.crt
Racine de confiance commune
Démon slapd : /etc/ldap/certs/labCA.crt (olcTLSCACertificateFile)
Démon tlshd : /etc/ssl/certs/labCA.crt
Racine de confiance commune
Démon nslcd : /etc/ssl/certs/labCA.crt (tls_cacertfile)
Démon tlshd : /etc/ssl/certs/labCA.crt
Magasin système : /usr/local/share/ca-certificates/labCA.crt
Certificats et clés du service LDAP (algorithme Ed25519 — handshake OpenSSL espace utilisateur via slapd / nslcd)
ldap-srvr.crt /etc/ldap/certs/ldap-srvr.crt (olcTLSCertificateFile) /etc/ssl/certs/ldap-srvr.crt (vérification du serveur par nslcd)
ldap-srvr.key /etc/ldap/certs/ldap-srvr.key (olcTLSCertificateKeyFile - propriétaire openldap, mode 400)
ldap-clnt.crt (non requis côté serveur) /etc/ssl/certs/ldap-clnt.crt (tls_cert dans nslcd.conf)
ldap-clnt.key /etc/ssl/private/ldap-clnt.key (tls_key dans nslcd.conf : propriétaire nslcd, mode 400)
Certificats et clés du service NFS (algorithme RSA 4096 — chiffrement kTLS noyau via tlshd)
nfs-srvr.crt /etc/ssl/certs/nfs-srvr.crt (x509.certificate dans /etc/tlshd/config) /etc/ssl/certs/nfs-srvr.crt (vérification du serveur NFS par tlshd)
nfs-srvr.key /etc/ssl/private/nfs-srvr.key (x509.private_key dans /etc/tlshd/config/ : propriétaire root, mode 400)
nfs-clnt.crt (non requis côté serveur) /etc/ssl/certs/nfs-clnt.crt (x509.certificate dans /etc/tlshd/config)
nfs-clnt.key /etc/ssl/private/nfs-clnt.key (x509.private_key dans /etc/tlshd/config : propriétaire root, mode 400)

3.3. Installer les paquets TLS et générer les certificats

Le tableau de la section précédente définit la répartition cible des certificats et des clés. Il reste à installer le seul paquet manquant pour le chiffrement de transport et à produire l'ensemble des clés et certificats depuis l'autorité commune labCA.

  • Le service LDAP n'a besoin d'aucun paquet supplémentaire : le chiffrement TLS est directement porté par les bibliothèques OpenSSL liées à slapd (serveur) et à nslcd (client), qui seront installés dans les parties suivantes de l'énoncé.

  • Seul NFSv4 a besoin d'un paquet dédié à la prise en charge TLS au niveau noyau (kTLS).

Q185.

Quels paquets faut-il installer sur le serveur et sur le client pour utiliser le chiffrement TLS avec NFSv4 ?

Comment utiliser les chemins /etc/ssl/certs/ et /etc/ssl/private/ définis dans le tableau ci-dessus pour compléter le fichier /etc/tlshd/config ?

Recherchez le paquet dans le catalogue.

apt search tls.*nfs
ktls-utils/testing 1.4.0-1 amd64
TLS handshake support for NFS and other in-kernel TLS users

Installez le paquet sur le client et le serveur.

sudo apt install ktls-utils

L'installation du paquet crée automatiquement le dossier /etc/tlshd/ avec un exemple de fichier de configuration config commenté.

ls -l /etc/tlshd/
cat /etc/tlshd/config

Complétez le contenu de ce fichier de configuration sur le client et le serveur avec les définitions données dans le tableau de préparation.

  • Serveur NFS :

    sudo sed -i '/^\[authenticate\.server\]/,$ {
      s|^#x509\.truststore=.*|x509.truststore=/etc/ssl/certs/labCA.crt|
      s|^#x509\.certificate=.*|x509.certificate=/etc/ssl/certs/nfs-srvr.crt|
      s|^#x509\.private_key=.*|x509.private_key=/etc/ssl/private/nfs-srvr.key|
    }' /etc/tlshd/config
  • Client NFS :

    sudo sed -i '/^\[authenticate\.client\]/,/^\[authenticate\.server\]/ {
      s|^#x509\.truststore=.*|x509.truststore=/etc/ssl/certs/labCA.crt|
      s|^#x509\.certificate=.*|x509.certificate=/etc/ssl/certs/nfs-clnt.crt|
      s|^#x509\.private_key=.*|x509.private_key=/etc/ssl/private/nfs-clnt.key|
    }' /etc/tlshd/config

Q186.

Comment générer, à partir de l'autorité de certification commune labCA, l'ensemble des clés et des certificats des services LDAP (Ed25519) et NFS (RSA 4096) répertoriés dans le tableau de préparation ?

Reprenez et regroupez les traitements des questions « Comment générer les certificats et les clés privées du serveur et du client NFS ? » et « Comment générer les certificats et la clé privée du serveur et du client LDAP ? », qui figurent dans les deux supports précédents. Les fonctions gen_key() et issue_cert() restent identiques dans les deux scripts d'origine. Seule la liste des certificats à émettre et leur algorithme diffèrent.

[Note] Note

L'autorité labCA est générée en RSA 4096 : l'algorithme de la CA est indépendant de celui des certificats qu'elle signe, et RSA reste le choix le plus compatible pour la racine de confiance partagée entre le handshake OpenSSL de l'espace utilisateur (slapd/nslcd) et le handshake kTLS du noyau (tlshd).

Codez un script qui rassemble tous les traitements et stocke les clés et les certificats dans le répertoire dédié $HOME/certs.

Si le code du script qui suit est enregistré sur le serveur dans le fichier generate-lab-certs.sh, on lance le traitement en tant qu'utilisateur normal.

bash generate-lab-certs.sh
#!/usr/bin/env bash
set -euo pipefail

LAB_CA="labCA"
LDAP_SERVER="ldap-srvr"
LDAP_CLIENT="ldap-clnt"
NFS_SERVER="nfs-srvr"
NFS_CLIENT="nfs-clnt"
DOMAIN="lab.local"
CERT_DIR="${HOME}/certs"
CA_REQ_CONF="ca_req.conf"

mkdir -p "${CERT_DIR}"
chmod 700 "${CERT_DIR}"
cd "${CERT_DIR}"

gen_key() {
        local name="$1"
        local algo="$2"
        case "${algo}" in
        ed25519) openssl genpkey -algorithm ed25519 -out "${name}.key" ;;
        rsa) openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:4096 -out "${name}.key" ;;
        *)
                echo "Unsupported algorithm: ${algo}" >&2
                exit 1
                ;;
        esac
}

issue_cert() {
        local ca_name="$1"
        local cert_name="$2"
        local usage="$3"
        local algo="$4"
        local ext

        gen_key "${cert_name}" "${algo}"
        openssl req -new -key "${cert_name}.key" -out "${cert_name}.csr" -subj "/CN=${cert_name}.${DOMAIN}"

        if [[ ${usage} == "server" ]]; then
                ext="extendedKeyUsage=serverAuth\nsubjectAltName=DNS:${cert_name}.${DOMAIN},DNS:${cert_name}"
        else
                ext="extendedKeyUsage=clientAuth"
        fi

        openssl x509 -req -in "${cert_name}.csr" -CA "${ca_name}.crt" -CAkey "${ca_name}.key" -CAcreateserial \
                -out "${cert_name}.crt" -days 730 -extensions v3 -extfile <(printf '%b\n' "[v3]" \
                        "basicConstraints=CA:FALSE" "keyUsage=critical,digitalSignature" \
                        "subjectKeyIdentifier=hash" "authorityKeyIdentifier=keyid,issuer" "${ext}")
}

# 1. Common CA for the lab (RSA 4096)
gen_key "${LAB_CA}" rsa
cat >"${CA_REQ_CONF}" <<'EOF'
[req]
distinguished_name=req
[v3_ca]
basicConstraints=critical,CA:TRUE
keyUsage=critical,keyCertSign,cRLSign
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
EOF
openssl req -x509 -new -nodes -key "${LAB_CA}.key" -days 3650 -subj "/CN=LAB-CA" -out "${LAB_CA}.crt" \
        -extensions v3_ca -config "${CA_REQ_CONF}"

# 2. LDAP certificates and keys (Ed25519 - slapd / nslcd)
issue_cert "${LAB_CA}" "${LDAP_SERVER}" server ed25519
issue_cert "${LAB_CA}" "${LDAP_CLIENT}" client ed25519

# 3. NFS certificates and keys (RSA 4096 - kTLS kernel via tlshd)
issue_cert "${LAB_CA}" "${NFS_SERVER}" server rsa
issue_cert "${LAB_CA}" "${NFS_CLIENT}" client rsa

rm -f -- ./*.csr ./*.srl "${CA_REQ_CONF}"

echo "Certificates and keys generated in ${CERT_DIR}"
echo "Transfer to the client: ${LAB_CA}.crt"
echo "  LDAP: ${LDAP_SERVER}.crt  ${LDAP_CLIENT}.key  ${LDAP_CLIENT}.crt"
echo "  NFS:  ${NFS_SERVER}.crt   ${NFS_CLIENT}.key   ${NFS_CLIENT}.crt"

Affichez la liste des fichiers générés pour confirmer que tous les éléments donnés dans le tableau préparatoire sont bien présents.

ls -1 certs/
labCA.crt
labCA.key
ldap-clnt.crt
ldap-clnt.key
ldap-srvr.crt
ldap-srvr.key
nfs-clnt.crt
nfs-clnt.key
nfs-srvr.crt
nfs-srvr.key

Q187.

Comment déposer ou transférer les certificats et les clés dans les répertoires choisis pour le serveur et le client ?

Reprenez et regroupez les traitements des questions des supports précédents. Sur le serveur, les fichiers produits à la question précédente sont copiés directement depuis le dossier $HOME/certs/. Sur le client, ils doivent d'abord être transférés, puis copiés dans les répertoires système.

Placer les certificats et les clés côté serveur

Côté serveur, le démon slapd perd ses privilèges root au démarrage et prend l'identité système openldap, qui doit posséder la clé privée LDAP. Ce changement de propriétaire de la clé privée impose une installation préalable du paquet slapd pour que l'identité openldap existe avant le transfert.

Les fichiers NFS suivent la convention /etc/ssl/ retenue pour tlshd. Les dossiers de dépôt sont déjà présents.

Commencez par installer le paquet slapd sans aucune configuration.

cat << SCRIPT_EOF >slapd-install.sh
#!/usr/bin/env bash

set -euo pipefail

# Non-interactive installation of slapd
export DEBIAN_FRONTEND=noninteractive

# Silent empty configuration of slapd
debconf-set-selections <<'EOF'
slapd slapd/no_configuration boolean true
EOF

# Install slapd and ldap-utils
apt update -qq
apt install -y --no-install-recommends slapd ldap-utils
SCRIPT_EOF

sudo bash slapd-install.sh

Vérifiez que l'identité système openldap est bien ajoutée suite à l'installation du paquet.

grep openldap /etc/passwd
openldap:x:982:982:OpenLDAP Server Account:/var/lib/ldap:/usr/sbin/nologin

Une fois cette vérification faite, lancez le script de transfert suivant :

cat << 'EOF' >deploy-lab-certs-srvr.sh
#!/usr/bin/env bash
set -euo pipefail

LAB_CA="labCA"
LDAP_SERVER="ldap-srvr"
NFS_SERVER="nfs-srvr"
SRC_DIR="${HOME}/certs"
LDAP_DIR="/etc/ldap/certs"
SSL_CERTS_DIR="/etc/ssl/certs"
SSL_PRIVATE_DIR="/etc/ssl/private"

# 1. Dedicated directory for slapd certificates (does not exist by default)
sudo mkdir -p "${LDAP_DIR}"

# 2. Transfer LDAP files (CA + certificate + server key)
sudo install -o openldap -g openldap -m 0444 "${SRC_DIR}/${LAB_CA}.crt" "${LDAP_DIR}/"
sudo install -o openldap -g openldap -m 0444 "${SRC_DIR}/${LDAP_SERVER}.crt" "${LDAP_DIR}/"
sudo install -o openldap -g openldap -m 0400 "${SRC_DIR}/${LDAP_SERVER}.key" "${LDAP_DIR}/"

# 3. Transfer NFS files: public certificates in system zone, key in private zone
sudo install -o root -g root -m 0644 "${SRC_DIR}/${LAB_CA}.crt" "${SSL_CERTS_DIR}/"
sudo install -o root -g root -m 0644 "${SRC_DIR}/${NFS_SERVER}.crt" "${SSL_CERTS_DIR}/"
sudo install -o root -g root -m 0400 "${SRC_DIR}/${NFS_SERVER}.key" "${SSL_PRIVATE_DIR}/"

echo "Certificates and keys deployed on the server."
EOF

bash deploy-lab-certs-srvr.sh

Ensuite, transférez le dossier $HOME/certs sur le client via scp, puis appliquez une politique similaire, adaptée aux démons nslcd et tlshd côté client.

scp -r $HOME/certs/ clnt:~

Placer les certificats et les clés côté client

Connectez-vous au client pour effectuer les opérations de dépôt de la clé et du certificat. Sur le client, il est nécessaire d'affecter la propriété de la clé privée à un compte système particulier. Dans ce cas, le compte du démon nslcd est désigné comme propriétaire exclusif de la clé LDAP.

Il est donc nécessaire d'installer au préalable les paquets LDAP du client. Comme indiqué dans le support de travaux pratiques LDAP, installez le paquet libnss-ldapd en mode non-interactif sans aucune configuration.

sudo DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \
  nslcd libnss-ldapd libpam-ldapd nslcd-utils

Vérifiez la présence du compte système.

grep nslcd /etc/passwd
nslcd:x:101:101:nslcd name service LDAP connection daemon:/run/nslcd:/usr/sbin/nologin

Une fois la présence du compte système confirmée, lancez le script de placement des clés et des certificats.

cat << 'EOF' >deploy-lab-certs-clnt.sh
#!/usr/bin/env bash
set -euo pipefail

LAB_CA="labCA"
LDAP_SERVER="ldap-srvr"
LDAP_CLIENT="ldap-clnt"
NFS_SERVER="nfs-srvr"
NFS_CLIENT="nfs-clnt"
SRC_DIR="${HOME}/certs"
SSL_CERTS_DIR="/etc/ssl/certs"
SSL_PRIVATE_DIR="/etc/ssl/private"

# 1. Public certificates: shared CA + server certificates (verification) + client certificates
for cert in "${LAB_CA}.crt" "${LDAP_SERVER}.crt" "${LDAP_CLIENT}.crt" "${NFS_SERVER}.crt" "${NFS_CLIENT}.crt"; do
        sudo install -o root -g root -m 0644 "${SRC_DIR}/${cert}" "${SSL_CERTS_DIR}/"
done

# 2. LDAP private key: owner nslcd (client resolution daemon)
sudo install -o nslcd -g nslcd -m 0400 "${SRC_DIR}/${LDAP_CLIENT}.key" "${SSL_PRIVATE_DIR}/"

# 3. NFS private key: owner root (tlshd runs as root)
sudo install -o root -g root -m 0400 "${SRC_DIR}/${NFS_CLIENT}.key" "${SSL_PRIVATE_DIR}/"

# 4. System trust store: labCA becomes a recognized authority for all TLS clients
sudo install -o root -g root -m 0644 "${SRC_DIR}/${LAB_CA}.crt" /usr/local/share/ca-certificates/
sudo update-ca-certificates

# 5. Clean up temporary directory
rm -rf "${SRC_DIR}"

echo "Certificates and keys deployed on the client"
EOF

bash deploy-lab-certs-clnt.sh

3.4. Installer et initialiser le service Kerberos

Les questions Q : Q180 et Q : Q182 ont déjà fixé le plan de nommage des identités Kerberos : un royaume unique LAB.LOCAL partagé par les deux services, mais trois principaux et autant de fichiers keytab distincts. Comme pour l'autorité de certification, il reste à déployer la ressource commune, à savoir le centre de distribution de clés (KDC), puis à en extraire les deux jeux de clés propres à chaque service.

  • Le KDC n'est installé et initialisé qu'une seule fois, sur le serveur qui cumule déjà les rôles slapd et nfs-kernel-server.

  • Chaque service reçoit son propre principal et son propre keytab, conformément au principe de moindre privilège déjà retenu pour la répartition des certificats.

Q188.

Comment installer et initialiser le centre de distribution de clés (KDC) Kerberos sur le serveur ?

Installez les paquets krb5-kdc et krb5-admin-server en fournissant les définitions du royaume déjà retenues, puis initialisez la base du royaume en mode non-interactif.

cat << 'SCRIPT_EOF' >bootstrap-kdc.sh
#!/usr/bin/env bash
set -euo pipefail

echo "1. Loading variables and secrets"
readonly DOMAIN="lab.local"
readonly REALM="${DOMAIN^^}"
readonly KDCSERVER="srvr.${DOMAIN}"
readonly ADMINPASSFILE="${HOME}/.kdc_master_pass"

if [[ ! -f "${ADMINPASSFILE}" ]]; then
    # 18 bytes of randomness naturally outputs exactly 24 base64 characters
    openssl rand -base64 18 > "${ADMINPASSFILE}"
    chmod 400 "${ADMINPASSFILE}"
    echo "Master password generated in ${ADMINPASSFILE}"
fi

readonly KDCMASTERPWD="$(cat "${ADMINPASSFILE}")"

echo "2. Pre-configure Debconf for silent installation"
sudo debconf-set-selections <<EOF
krb5-config krb5-config/default_realm string ${REALM}
krb5-config krb5-config/kerberos_servers string ${KDCSERVER}
krb5-config krb5-config/admin_server string ${KDCSERVER}
krb5-config krb5-config/add_servers boolean true
EOF

echo "3. Installing Kerberos packages"
sudo DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \
    krb5-kdc krb5-admin-server

echo "4. Deploying system configuration /etc/krb5.conf"
sudo tee /etc/krb5.conf >/dev/null <<EOF
[libdefaults]
    default_realm = ${REALM}
    kdc_timesync = 1
    ccache_type = 4
    forwardable = true
    proxiable = true
    rdns = false
    dns_canonicalize_hostname = false
    allow_weak_crypto = false
    default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96
    default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96
    permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96

[realms]
    ${REALM} = {
        kdc = ${KDCSERVER}
        admin_server = ${KDCSERVER}
        default_domain = ${DOMAIN}
    }

[domain_realm]
    .${DOMAIN} = ${REALM}
    ${DOMAIN} = ${REALM}
EOF

echo "5. Initializing cryptographic database"
if sudo test ! -f /var/lib/krb5kdc/principal; then
    sudo kdb5_util create -s -r "${REALM}" -P "${KDCMASTERPWD}"
else
    echo "  Database already exists, skipping initialization."
fi

echo "6. Create minimal ACL and restart services"
echo "*/admin@${REALM} *" | sudo tee /etc/krb5kdc/kadm5.acl >/dev/null
sudo systemctl enable --now krb5-kdc krb5-admin-server

echo ""
echo "Success — Kerberos KDC is installed and configured."
echo "  Active realm  : ${REALM}"
echo "  Master server : ${KDCSERVER}"
echo "  Master password stored in : ${ADMINPASSFILE}"
SCRIPT_EOF
sudo bash bootstrap-kdc.sh

Vérifiez que les deux services du KDC sont bien actifs.

systemctl status krb5-kdc krb5-admin-server --no-pager

Copiez le fichier de configuration Kerberos /etc/krb5.conf du serveur sur le client.

cat /etc/krb5.conf | ssh clnt "sudo tee /etc/krb5.conf > /dev/null"

Q189.

Comment créer les deux principaux de service nécessaires aux services LDAP et NFS ?

Reprenez les deux identités définies à la question Q : Q180 et créez-les avec une clé aléatoire plutôt qu'un mot de passe, puisque ces deux comptes ne servent qu'à générer des fichiers keytab.

sudo kadmin.local -q "addprinc -randkey ldap/ldap-srvr.lab.local@LAB.LOCAL"
sudo kadmin.local -q "addprinc -randkey nfs/nfs-srvr.lab.local@LAB.LOCAL"

Contrôlez la liste des principaux du royaume.

sudo kadmin.local -q "listprincs"
Authenticating as principal root/admin@LAB.LOCAL with password.

K/M@LAB.LOCAL
kadmin/admin@LAB.LOCAL
kadmin/changepw@LAB.LOCAL
krbtgt/LAB.LOCAL@LAB.LOCAL
ldap/ldap-srvr.lab.local@LAB.LOCAL
nfs/nfs-srvr.lab.local@LAB.LOCAL

Q190.

Comment extraire et répartir les clés dans les fichiers keytab dédiés à chaque service ?

Chaque extraction (ktadd) retire la clé du principal de la base du KDC et l'inscrit dans le fichier indiqué. Placez chaque keytab dans le répertoire attendu par le service concerné, avec un propriétaire et un mode restrictifs, comme pour les clés privées TLS.

cat << 'EOF' >deploy-lab-keytabs.sh
#!/usr/bin/env bash
set -euo pipefail

LDAP_KEYTAB="/etc/ldap/ldap.keytab"
NFS_KEYTAB="/etc/krb5.keytab"

# Create a secure temporary directory for initial keytab generation
TMP_DIR=$(mktemp -d)
trap 'sudo rm -rf "${TMP_DIR}"' EXIT

# 1. LDAP service key: owner openldap (slapd daemon)
sudo kadmin.local -q "ktadd -k ${TMP_DIR}/ldap.keytab ldap/ldap-srvr.lab.local@LAB.LOCAL"
sudo install -o openldap -g openldap -m 400 "${TMP_DIR}/ldap.keytab" "${LDAP_KEYTAB}"

# 2. NFS service key: default system keytab, read by nfs-kernel-server and idmapd
sudo kadmin.local -q "ktadd -k ${TMP_DIR}/nfs.keytab nfs/nfs-srvr.lab.local@LAB.LOCAL"
sudo install -o root -g root -m 600 "${TMP_DIR}/nfs.keytab" "${NFS_KEYTAB}"

echo "Keytabs deployed on the server."
EOF
bash deploy-lab-keytabs.sh

Vérifiez le contenu de chaque keytab : chacun ne doit exposer que le principal qui lui est propre.

sudo klist -kt /etc/ldap/ldap.keytab
sudo klist -kt /etc/krb5.keytab
Keytab name: FILE:/etc/ldap/ldap.keytab
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   2 02/09/2026 10:36:16 ldap/ldap-srvr.lab.local@LAB.LOCAL
   2 02/09/2026 10:36:16 ldap/ldap-srvr.lab.local@LAB.LOCAL
Keytab name: FILE:/etc/krb5.keytab
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   2 02/09/2026 10:36:16 nfs/nfs-srvr.lab.local@LAB.LOCAL
   2 02/09/2026 10:36:16 nfs/nfs-srvr.lab.local@LAB.LOCAL

Q191.

Quels paquets faut-il installer sur le client pour utiliser l'authentification Kerberos ?

À la différence de l'installation « sans configuration » retenue pour nslcd, le client Kerberos a besoin de connaître le royaume et ses serveurs dès l'installation. Entrez les mêmes valeurs que sur le serveur.

cat << 'SCRIPT_EOF' > krb5-client-install.sh
#!/usr/bin/env bash

set -euo pipefail

readonly DOMAIN="lab.local"
readonly REALM="${DOMAIN^^}"
readonly KDCSERVER="srvr.${DOMAIN}"

echo "=== 1. Pre seed Kerberos configuration ==="
sudo debconf-set-selections <<EOF
krb5-config krb5-config/default_realm string ${REALM}
krb5-config krb5-config/kerberos_servers string ${KDCSERVER}
krb5-config krb5-config/admin_server string ${KDCSERVER}
krb5-config krb5-config/add_servers boolean true
EOF

echo "=== 2. Install Kerberos client packages ==="
sudo apt update -qq
sudo DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \
    krb5-user \
    libpam-krb5 \
    libsasl2-modules-gssapi-mit
SCRIPT_EOF
bash krb5-client-install.sh
[Note] Note

Aucun principal utilisateur n'a encore été créé à ce stade : cette étape reste à la charge des sections suivantes, lors de l'implantation des comptes dans l'annuaire LDAP. Cette opération permettra ensuite de valider l'authentification GSSAPI de slapd (Section 4, « Déployer l'annuaire LDAP ») et le montage sec=krb5p du partage NFSv4 (Section 5, « Déployer l'exportation NFSv4 »).

Q192.

Comment déployer un principal Kerberos dédié à la machine cliente ?

Les principaux dont le nom commence par ldap/... et nfs/..., et qui ont été créés précédemment, authentifient les services du serveur. Cependant, le client a lui aussi besoin d'informations d'identification propres à la machine : le démon rpc.gssd s'en sert pour établir un contexte de sécurité RPCSEC_GSS en dehors de toute session utilisateur (renouvellement de ticket en arrière-plan, montages autofs déclenchés avant l'ouverture de session). Créez donc un principal host/clnt.lab.local@LAB.LOCAL dédié, extrayez-le dans un keytab, puis déployez ce dernier sur le client selon le même schéma que les certificats.

Sur le serveur, créez le principal et extrayez sa clé dans un keytab destiné au transfert.

cat << 'SCRIPT_EOF' >deploy-lab-host-principal.sh
#!/usr/bin/env bash
set -euo pipefail

readonly REALM="LAB.LOCAL"
readonly HOST_PRINCIPAL="host/clnt.lab.local@${REALM}"
readonly KEYTAB_DIR="${HOME}/keytabs"

echo "1. Creating the client host principal"
sudo kadmin.local -q "addprinc -randkey ${HOST_PRINCIPAL}"

echo "2. Extracting the key into a transferable keytab"
mkdir -p "${KEYTAB_DIR}"
sudo kadmin.local -q "ktadd -k ${KEYTAB_DIR}/clnt.keytab ${HOST_PRINCIPAL}"
sudo chown "${USER}" "${KEYTAB_DIR}/clnt.keytab"

echo "Keytab ready for transfer: ${KEYTAB_DIR}/clnt.keytab"
SCRIPT_EOF
bash deploy-lab-host-principal.sh

Transférez le keytab vers le client, comme pour le dossier $HOME/certs/.

scp ${HOME}/keytabs/clnt.keytab clnt:~

Sur le client, installez la clé dans l'emplacement système attendu par rpc.gssd, avec un propriétaire et un mode restrictifs.

cat << 'SCRIPT_EOF' >install-lab-host-keytab.sh
#!/usr/bin/env bash
set -euo pipefail
sudo install -o root -g root -m 600 "${HOME}/clnt.keytab" /etc/krb5.keytab
rm -f "${HOME}/clnt.keytab"
echo "Host keytab deployed on the client."
SCRIPT_EOF

bash install-lab-host-keytab.sh

Vérifiez le contenu du keytab, puis validez l'obtention d'un ticket avec les informations d'identification machine.

sudo klist -kt /etc/krb5.keytab
Keytab name: FILE:/etc/krb5.keytab
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   2 02/09/2026 15:17:44 host/clnt.lab.local@LAB.LOCAL
   2 02/09/2026 15:17:44 host/clnt.lab.local@LAB.LOCAL
sudo kinit -k -t /etc/krb5.keytab host/clnt.lab.local && \
sudo klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: host/clnt.lab.local@LAB.LOCAL

Valid starting       Expires              Service principal
02/09/2026 15:39:17  03/09/2026 01:39:17  krbtgt/LAB.LOCAL@LAB.LOCAL
        renew until 03/09/2026 15:39:17
[Note] Note

Ce principal host/ joue, pour Kerberos, le même rôle que le certificat client déployé à la question précédente pour TLS. Il constitue une identité propre à la machine, distincte des identités de service, et permet au client de prouver son appartenance au royaume indépendamment de tout compte utilisateur.