Windows Server 2016 : corriger l’erreur FTP « User cannot log in, home directory inaccessible » (IIS, AD, Kerberos)

Sous Windows Server 2016 (IIS + FTP), vous constatez qu’après ~24 heures de fonctionnement tous les comptes sont rejetés par « User cannot log in, home directory inaccessible ». Ce guide opérationnel vous aide à diagnostiquer, corriger et éviter les redémarrages.

Sommaire

Contexte et symptômes

  • Environnement : Windows Server 2016 Datacenter, rôle IIS avec service Microsoft FTP.
  • Sécurité : accès réservé aux membres d’un groupe Active Directory spécifique, isolation FTP par attribut AD pointant vers le dossier personnel (ex. msIIS-FTPDir ou équivalent).
  • Symptôme : après ~24 h, tous les utilisateurs reçoivent « User cannot log in, home directory inaccessible ».
  • Constatations : redémarrer IIS ou le service FTP ne suffit pas ; seul un redémarrage complet rétablit l’accès, temporairement.
  • Objectif : identifier la cause racine et supprimer la nécessité de redémarrages.

Pourquoi le problème apparaît souvent après ~24 h

Dans les architectures où l’attribut d’isolation pointe vers un chemin UNC (partage SMB/DFS), l’accès au répertoire d’accueil repose sur une combinaison de Kerberos (tickets/TGT, délégation vers cifs/), de droits NTFS et de la connectivité SMB. Trois phénomènes récurrents expliquent une panne cyclique :

  1. Tickets Kerberos périmés ou mal renouvelés côté serveur : le service perd la capacité d’ouvrir le chemin UNC au nom de l’utilisateur (ou via un compte « Connect as »). Purger/renouveler les tickets corrige immédiatement… ce que fait implicitement un redémarrage.
  2. Token bloat (jeton d’accès trop volumineux) : de très nombreux groupes AD imbriqués gonflent le jeton – une fois une limite franchie, l’authentification ou l’autorisation échoue de manière sporadique, souvent lors d’un renouvellement de ticket.
  3. Dépendance à un partage réseau instable : déconnexion/expiration de session SMB, SPN/Délégation mal configurés, DFS/antivirus qui verrouille le chemin, ou quotas/ACL modifiés.

Le fait que « redémarrer IIS/FTP » n’aide pas, mais que le redémarrage du système règle la panne, pointe souvent vers caches Kerberos/LSASS et/ou la pile SMB plutôt que vers la configuration FTP elle‑même.

Axes de vérification prioritaires

Axe de vérificationDétails & actions conseillées
Configuration d’authentification / autorisationConfirmer que les règles <authorization> d’IIS ciblent uniquement le groupe AD voulu, sans entrées « All Users ». Vérifier que l’authentification active (Basic + TLS/SSL recommandé) correspond à la méthode d’isolation choisie.
Isolation FTP par attribut ADVérifier que l’attribut msIIS-FTPDir (ou équivalent) est renseigné pour chaque utilisateur et pointe vers un dossier existant. Si c’est un UNC, valider la disponibilité continue du partage (pas de timeouts Kerberos, pas de déconnexion DFS).
NTFS et partages réseauÉviter les lecteurs mappés : utiliser des chemins UNC directs. Tester l’accès avec icacls et via un runas /netonly sous l’identité d’un utilisateur réel. Vérifier les droits Share et NTFS (principe d’addition minimale).
Cache Kerberos / jetons de groupeAprès ~24 h, un token bloat ou un ticket expiré peut bloquer l’accès. Surveiller les Event ID 5719 (Netlogon), 4768/4769/4771/4772 (Kerberos) dans Système et Sécurité. Si le groupe AD autorisé agrège de très nombreux membres, réduire sa taille et/ou utiliser des groupes imbriqués.
Cycle et ressources du service FTPDans IIS Manager > FTP > Advanced Settings, vérifier les timeouts (ex. Control Channel Timeout, Data Channel Timeouts). Planifier un recycle contrôlé (arrêt/démarrage ftpsvc + purge tickets) hors‑production si une fuite de ressources est suspectée.
Mises à jour et correctifsInstaller les derniers CU/SSU pour Windows Server 2016. Plusieurs correctifs ont ciblé IIS/FTP, SMB et Kerberos au fil du temps. Harmoniser aussi le niveau de patch des contrôleurs de domaine.
Journaux étendus et diagnosticsActiver les journaux FTP détaillés et la trace ETW du service FTP. Utiliser ProcMon (filtre sur ftpsvc.exe), netsh trace ou Wireshark lors de la panne pour capturer la première erreur (ex. SMB ACCESS_DENIED, code 550).
Alternative sécuriséeSi l’empilement AD+FTP+UNC est trop fragile, envisager SFTP via OpenSSH (installable sur 2016) ou séparer authentification et stockage (ex. compte de service dédié pour l’accès UNC).

Diagnostic pas à pas (concret)

1. Valider l’autorisation IIS/FTP

# Lister les règles d'authz FTP (PowerShell)
appcmd list config "MonSiteFtp" -section:system.ftpServer/security/authorization

# Doit contenir uniquement "Allow" sur le groupe AD attendu, pas "All Users".

2. Prouver/révoquer un problème Kerberos sans redémarrer

Exécuter sur le serveur FTP :

# Afficher les tickets Kerberos du contexte Système (LSASS)
klist -li 0x3e7

# Purger les tickets machine (solution temporaire si l'accès revient)

klist -li 0x3e7 purge

# Vérifier le canal sécurisé au domaine

nltest /sc_verify: 

Si purger les tickets fait immédiatement disparaître l’erreur FTP, la cause racine se situe presque sûrement côté Kerberos/délégation (SPN manquant, délégation non configurée, ticket expiré non renouvelé, etc.).

3. Tester l’accès UNC « comme l’utilisateur »

# Ouvrir une session CMD sous l'identité de l'utilisateur AD (sans exposition du mot de passe)
runas /netonly /user:DOMAINE\jdupont cmd

# Dans cette console, tester le chemin du home directory

dir \FILESRV01\Homes\jdupont

# Vérifier les ACL NTFS et Share

icacls \FILESRV01\Homes\jdupont </code></pre>

<h3>4. Vérifier l’attribut d’isolation AD</h3>
<pre><code># Pour un utilisateur, vérifier le chemin configuré (ex. avec RSAT)
Get-ADUser jdupont -Properties * | Select-Object SamAccountName, msIIS-FTPDir

# Contrôler l’existence du répertoire, la casse et les droits

</code></pre>

<h3>5. Capturer l’erreur au moment précis</h3>
<ul>
  <li><strong>Journaux FTP</strong>&nbsp;: activer <em>Log File Rollover</em> quotidien et le <em>Log Extender</em> (statut&nbsp;530/550, <em>Win32-Status</em> si disponible).</li>
  <li><strong>Event Viewer</strong>&nbsp;: <em>Applications and Services Logs &gt; Microsoft &gt; Windows &gt; IIS-FTP</em>, <em>System</em>, <em>Security</em> (Kerberos/Netlogon).</li>
  <li><strong>Traçage</strong>&nbsp;:
    <pre><code>netsh trace start capture=yes scenario=FileSharing level=Verbose
rem ... reproduire l'échec FTP ...
netsh trace stop

6. Détecter un « token bloat »

# Compter les groupes de l'utilisateur
whoami /groups

# Côté AD (avec droits), afficher l'appartenance étendue

Get-ADUser jdupont -Properties memberOf |
Select-Object -ExpandProperty memberOf | Measure-Object 

Si le nombre de groupes est élevé (centaines) ou si l’utilisateur embarque de l’SIDHistory, la probabilité de jeton surdimensionné monte fortement. Réduire les appartenances directes et privilégier des groupes imbriqués (AGDLP), voire des groupes dynamiques ciblés.

7. Temps d’attente/ressources FTP

Dans les Advanced Settings du site FTP, vérifier :

  • Control Channel Timeout (secs) et Data Channel Timeouts.
  • Concurrent Connections et file de commandes (saturation = erreurs 421/426 plutôt que 530/550, mais utile à auditer).

Correctifs durables (ordre recommandé)

A. Stabiliser l’accès au stockage des répertoires d’accueil

Choisir l’un de ces modèles supportés :

  1. Local : stocker les home directories sur le serveur FTP (le plus simple, limites de capacité).
  2. UNC + compte de service : attribuer au site FTP des PhysicalPathCredentials (« Connect as ») avec un compte de service dédié (idéalement un gMSA). Donner à ce compte l’accès Share/NTFS aux répertoires. Évite la délégation Kerberos du client (double‑hop).
  3. UNC + délégation Kerberos : configurer la délégation contrainte sur le compte ordinateur du serveur FTP (« Trust this computer for delegation to specified services (Kerberos only) ») vers le(s) service(s) cifs/FILESRV hébergeant les homes. Vérifier/ajouter les SPN cifs/ adéquats sur le(s) serveur(s) de fichiers.

B. Réduire le risque de token bloat

  • Nettoyer les appartenances directes excessives ; privilégier l’imbrication (AGDLP).
  • Supprimer les SIDHistory obsolètes et les groupes universels non nécessaires.
  • Limiter la transposition de groupes via scripts d’audit réguliers.

C. Renouvellement/purge des tickets sans redémarrer

En attendant la correction définitive, une tâche planifiée nocturne peut prévenir la panne cyclique :

powershell.exe -NoProfile -Command "klist -li 0x3e7 purge; nltest /sc_verify:DOMAINE; Restart-Service ftpsvc -Force"

Cette séquence purge les tickets machine, vérifie le canal sécurisé et redémarre proprement le service FTP (sans redémarrer tout le serveur).

D. Harmoniser les correctifs

Mettre à jour Windows Server 2016 avec les derniers CU/SSU, et aligner le patch‑level des contrôleurs de domaine et des serveurs de fichiers. Plusieurs corrections cumulatives ont amorti des soucis SMB/Kerberos au fil du temps.

E. Paramétrage FTP/IIS

  • Activer FTPS (FTP‑SSL) pour chiffrer les identifiants (indépendant du bug mais impératif sécurité).
  • Consigner Win32-Status et Bytes Sent/Recv pour améliorer le diagnostic.
  • Limiter l’exposition (pare‑feu, Data Channel Port Range restreint, External IP si NAT).

Scripts prêts à l’emploi

1) Test automatique de connexion FTP (avec journal)

Param(
  [string]$Server = "ftp.exemple.local",
  [int]$Port = 21,
  [string]$User,
  [string]$Password,
  [switch]$UseSsl
)

$uri = "ftp://$Server:$Port/"
$log = "C:\Logs\ftp_health.log"
[System.Net.ServicePointManager]::Expect100Continue = $false

try {
$req = [System.Net.FtpWebRequest]::Create($uri)
$req.Method = [System.Net.WebRequestMethods+Ftp]::ListDirectory
$req.Credentials = New-Object System.Net.NetworkCredential($User, $Password)
$req.EnableSsl = $UseSsl.IsPresent
$req.ReadWriteTimeout = 15000
$req.Timeout = 15000
$res = $req.GetResponse()
($res.GetResponseStream()).Dispose()
$res.Close()
Add-Content $log "$(Get-Date -Format o) OK $Server SSL=$($req.EnableSsl)"
} catch {
Add-Content $log "$(Get-Date -Format o) ERROR $Server SSL=$UseSsl : $($_.Exception.Message)"
exit 2
} 

2) Vérifier droits UNC pour un utilisateur

Param(
  [string]$Path = "\\FILESRV01\Homes\jdupont",
  [string]$User = "DOMAINE\jdupont",
  [string]$Password
)

$cred = New-Object System.Management.Automation.PSCredential($User,(ConvertTo-SecureString $Password -AsPlainText -Force))
New-PSDrive -Name Z -PSProvider FileSystem -Root $Path -Credential $cred -ErrorAction Stop | Out-Null
try { Get-ChildItem Z:\ | Out-Null; "ACCÈS OK" }
finally { Remove-PSDrive Z -ErrorAction SilentlyContinue } 

3) Audit simple du volume de groupes

Param([string]$Sam="jdupont")
$u = Get-ADUser $Sam -Properties memberOf, SIDHistory
$groups = @($u.memberOf) + @($u.SIDHistory)
"{0} groupes référencés (y.c. SIDHistory)" -f $groups.Count

Journalisation & événements utiles

SourceÉvénements/indicateursInterprétation
Security4768/4769 : demande de ticket ; 4771/4772 : échec KerberosErreurs récurrentes → tickets expirés, SPN/délégation
System5719 Netlogon, 5722/5805Problème de canal sécurisé au domaine
Microsoft‑IIS‑FTPÉchecs d’authz, codes 530/550 avec Win32‑Status« Home directory inaccessible » typiquement 550 ou erreur d’accès SMB
SMBClient/SMBServerEvénements d’accès refusé, déconnexionsPartage distant indisponible, ACL/Share mal réglés

Bonnes pratiques pour éviter la récidive

  • Épingler une identité d’accès UNC stable (compte de service/gMSA) ou configurer KCD proprement.
  • Limiter la taille des groupes et documenter l’attribut AD utilisé pour l’isolation. Contrôler régulièrement l’existence des répertoires pointés.
  • Activer FTPS (TLS explicite) afin de protéger les identifiants. Isoler la plage de ports de données et ouvrir précisément le pare‑feu.
  • Automatiser un test de bout en bout (script ci‑dessus) avec alerte si échec.

Alternative : SFTP via OpenSSH

Si la maintenance d’un FTP isolé par AD et adossé à des partages UNC devient trop coûteuse, la bascule vers SFTP (OpenSSH) simplifie souvent l’empilement : un seul canal chiffré, ACL locales/NTFS claires, moins de variables (KCD/SPN). Sur Windows Server 2016, OpenSSH peut être installé (package binaire) et piloté par des groupes locaux/AD.

Résumé opérationnel

Symptôme/indiceTest rapideCorrectif recommandé
Erreur après ~24 h, reboot règleklist -li 0x3e7 puis purgeConfigurer KCD ou compte de service UNC ; tâche planifiée de purge en temporaire
Chemin UNC en ACCESS_DENIEDrunas /netonly, icaclsCorriger Share/NTFS, éviter lecteurs mappés, vérifier existence du dossier
Beaucoup de groupes ADwhoami /groups, Get-ADUser ... memberOfRéduire les appartenances, supprimer SIDHistory obsolètes
IIS autorise « All Users »Inspection <authorization>Limiter au groupe AD cible, revoir ordre/priorité des règles
FTP saturé/temps d’attenteJournaux FTP, timeouts, connexionsAjuster timeouts, recycle contrôlé, surveiller ressources

Conclusion

Dans la majorité des cas, l’erreur « User cannot log in, home directory inaccessible » qui survient périodiquement est le produit d’un chaînage AD → Kerberos → SMB fragile. En prouvant (et contournant) le problème avec klist, en stabilisant l’accès UNC (compte de service ou délégation contrainte) et en réduisant le volume d’appartenances AD, vous éliminez les pannes et les redémarrages forcés. Complétez par une journalisation riche, des correctifs à jour et – si pertinent – un passage à SFTP/OpenSSH pour simplifier l’architecture.


Annexes

Points complémentaires utiles

  • FTPS : activez‑le pour chiffrer les identifiants (n’influe pas sur la cause mais améliore grandement la sécurité).
  • Quota de groupe AD : un jeton Kerberos trop volumineux peut provoquer un refus d’accès. Limiter les appartenances directes et envisager des stratégies Claims‑Based si compatibles.
  • Surveillance nocturne : un script PowerShell peut tenter une connexion de santé et, en cas d’échec, purger les tickets Kerberos puis redémarrer uniquement ftpsvc en attendant la remédiation définitive.
Sommaire