Crashs fréquents de WSUS 4.0

Depuis quelques jours, un serveur WSUS plantait au bout de quelques minutes de fonctionnement, sans dysfonctionnement notable côté système. Les logs de WSUS ne donnaient rien de particulier : toutes les requêtes y étaient journalisées, jusqu'au plantage sans code d'erreur particulier. Il suffisait d'un iisreset pour redonner l'accès au service, mais hors de question de créer un tâche planifiée pour effectuer un iisreset toutes les 5 minutes pour palier au dysfonctionnement.

Message d'erreur apparaissant sur la console WSUS peu de temps après le redémarrage du service.

J'avais cependant dans le journal d'événements Windows, deux entrées récurrentes, avec pour code d'erreur 5013 et 5138, et source "WAS". Ces erreurs indiquent qu'une application utilisée dans le pool applicatif WsusPool n'a pas communiqué et ne s'est pas terminée dans le temps imparti.

J'ai procédé à quelques changements de variables concernant le pool applicatif WsusPool :

  • Queue Length : passage à 25000 au lieu de 5000 (il s'agit du nombre maximal de requêtes HTTP qui peuvent être en attente) ;
  • Augmentation de la Virtual Memory Limit à 5 Go (pour 8 installés physiquement sur le serveur) ;
  • Passage du "Service Unavailable" Response Type de HttpLevel vers TcpLevel : ceci permet d'éviter de renvoyer une erreur HTTP 503 Service Unavailable lorsque le serveur ne peut traiter la requête. Le serveur va à la place remettre en file d'attente la requête HTTP.

J'ai procédé ensuite à un redémarrage complet du serveur, WSUS fonctionne désormais depuis plus de 2 heures consécutives et aucun dysfonctionnement n'est à déplorer.

Access Denied en chaîne sur un FTP porté par IIS

J'ai mis en place un serveur FTP porté par un serveur IIS installé sur un Windows Server 2016. Ce serveur FTP autorise un compte de service sans droits particuliers à écrire sur un répertoire virtuel configuré dans IIS.

Ce compte de service est bien renseigné pour avoir les droits sur le répertoire dans lequel il est censé écrire, et ses droits Read, Write sont bien portés à la fois sur la racine FTP ftproot et sur le répertoire virtuel. Cependant, à la connexion et ce peu importe le client FTP, j'obtenais un simple Access Denied après la transaction d'authentification et l'acceptation du certificat SSL. Après avoir essayé avec mon compte d'administration ayant exactement les mêmes privilèges sur la machine, cela fonctionnait. Le problème est donc lié au compte en lui-même.

Un petit tour dans le fichier de configuration de IIS disponible dans C:\Windows\System32\inetsrv\config\applicationHost.config (comme expliqué dans cet article) me donne rien de plus : les balises sont bien renseignées et le compte en question a bien les droits de connexion.


J'essaye alors d'ajouter le compte en tant qu'administrateur local pour voir si cela fait la différence, et c'est alors qu'un détail me saute aux yeux : dans la fenêtre du groupe des administrateurs locaux, le compte apparaît avec son appellation pré-Windows 2000. Sur cet exemple, le compte testcomptedeserviceftp@mondomaine.com est renseigné avec son nom pré-Windows 2000 MONDOMAINE\testcomptedeservicef :


On peut vérifier dans l'ActiveDirectory les deux noms de connexion :

La console ActiveDirectory Users and Computers permet de vérifier les deux logins d'un utilisateur.

Dans IIS, en remplaçant le nom de connexion usuel par le nom pré-Windows 2000, j'ai pu me connecter.

Il est donc nécessaire d'attribuer les privilèges en utilisant les noms pré-Windows 2000.

En effet, si le nom de mon compte d'administration n'était pas tronqué car identique qu'il soit pré-Windows 2000 ou non, ce n'était pas le cas pour mon compte de service (identifiant trop long). Je tentais donc de me connecter avec un compte inconnu de IIS ; j'ai donc appris aujourd'hui que ce dernier gère les privilèges FTP avec les noms de connexion pré-Windows 2000, ce qui m'a pris une petite heure à réaliser.

550 Cannot create a file when that file already exists sur un FTP porté par IIS

J'ai rencontré une erreur 550 ce jour en tentant d'accéder à un répertoire situé à la racine d'un serveur FTP porté par IIS sur 2008 R2 (IIS 7).

Après vérifications dans le IIS Manager, je n'ai rien trouvé de particulier au niveau des autorisations, le compte que j'utilisais avait bien les droits en lecture et en écriture ; les autorisations NTFS sur le répertoire physique étaient également valides. De plus, ce répertoire n'est qu'une variante de deux autres répertoires identiques, créés en même temps, gérés par les mêmes comptes et accédés par les mêmes applications. Il n'y a donc aucune raison d'avoir une différence de configuration.

J'ai donc été vérifier le fichier de configuration des sites IIS dans C:\Windows\System32\inetsrv\config\applicationHost.config. A la toute fin de ce fichier, la première entrée concerne la racine du FTP, la deuxième concerne spécifiquement le répertoire auquel je n'ai pas accès.

En supprimant cette seconde balise <location> et en redémarrant mon site FTP, tout est revenu dans l'ordre.

Il n'y avait aucune raison d'avoir cette balise pour un seul des 3 répertoires ; par ailleurs ajouter une balise <add accessType="Allow" users="MonUser" permissions="Read, Write" /> n'avait rien changé.

Powershell : recyclage de pool WSUS à distance

J'avais déjà abordé la question de la consommation de RAM de WSUS à travers son pool applicatif IIS nommé WsusPool dans cet article ; j'ai décidé d'en faire un script Powershell afin de déclencher un recyclage du pool à distance.

Ce script va requêter le serveur via WinRM pour obtenir les informations concernant l'usage de la mémoire vive physique, et sur confirmation, déclencher à distance un recyclage du pool WsusPool.

function recycle{
Write-Host "Trying to start recycling in 5 seconds. Script will automatically end when recycling has successfully been initiated."
Start-Sleep 5
Invoke-Command -ComputerName $iishost -ScriptBlock { Restart-WebAppPool WsusPool }
}

Write-Host "WSUS IIS Application Pool Recycler"
Write-Host "=================================="
Write-Host ""
$iishost = Read-Host "Server to recycle the pool for ?"
$hostdetails = Get-Ciminstance Win32_operatingsystem -ComputerName $iishost
$hostramtotal = $hostdetails.TotalVisibleMemorySize
$hostramused = $hostdetails.TotalVisibleMemorySize - $hostdetails.FreePhysicalMemory
$hostramperc = [math]::Round(($hostramused/$hostramtotal)*100,0)
$hostramtotal = [math]::Round($hostdetails.TotalVisibleMemorySize/1048576,0)
Write-Host "% RAM used: $hostramperc"
Write-Host "Server $iishost has $hostramtotal GB total memory."
$confirm = Read-Host "Please confirm you wish to recycle the WsusPool IIS Application Pool on $iishost (yes)"
if ($confirm -eq "yes") { recycle }
else { Write-Host "Bye." ; break }

Au final, il est possible d'utiliser ce script pour n'importe quel pool car la commande Restart-WebAppPool est liée à IIS et pas spécialement à WSUS.