IIS - Internet Information Services
Configuration et administration du serveur web IIS : sites, app pools, bindings, et certificats.
Architecture
ARCHITECTURE IIS
══════════════════════════════════════════════════════════
┌─────────────────────────────────┐
│ HTTP.sys │
│ (Kernel-mode driver) │
│ Port 80/443 listener │
└──────────────┬──────────────────┘
│
┌──────────────▼──────────────────┐
│ W3SVC (World Wide Web │
│ Publishing Service) │
└──────────────┬──────────────────┘
│
┌──────────────────────────┼──────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ App Pool 1 │ │ App Pool 2 │ │ App Pool 3 │
│ (w3wp.exe) │ │ (w3wp.exe) │ │ (w3wp.exe) │
├───────────────┤ ├───────────────┤ ├───────────────┤
│ Site A │ │ Site B │ │ Site C │
│ Site B │ │ App 1 │ │ │
└───────────────┘ └───────────────┘ └───────────────┘
Concepts clés :
• Site : Conteneur pour contenu web (host headers, ports)
• Application : Sous-ensemble d'un site avec son propre pool
• App Pool : Processus worker isolé (identité, recyclage)
• Virtual Directory : Mapping vers un dossier physique
Installation
Rôles et Fonctionnalités
# Installation basique (Web Server)
Install-WindowsFeature -Name Web-Server -IncludeManagementTools
# Installation complète pour ASP.NET
Install-WindowsFeature -Name Web-Server,Web-Asp-Net45,Web-Net-Ext45,`
Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Mgmt-Console,Web-Mgmt-Service
# Fonctionnalités courantes
$features = @(
"Web-Server",
"Web-WebServer",
"Web-Common-Http",
"Web-Static-Content",
"Web-Default-Doc",
"Web-Dir-Browsing",
"Web-Http-Errors",
"Web-App-Dev",
"Web-Asp-Net45",
"Web-Net-Ext45",
"Web-ISAPI-Ext",
"Web-ISAPI-Filter",
"Web-Health",
"Web-Http-Logging",
"Web-Log-Libraries",
"Web-Request-Monitor",
"Web-Security",
"Web-Filtering",
"Web-Basic-Auth",
"Web-Windows-Auth",
"Web-Performance",
"Web-Stat-Compression",
"Web-Dyn-Compression",
"Web-Mgmt-Tools",
"Web-Mgmt-Console",
"Web-Scripting-Tools"
)
Install-WindowsFeature -Name $features
# Vérifier l'installation
Get-WindowsFeature Web-* | Where-Object Installed | Select-Object Name
Module PowerShell
# Le module WebAdministration est inclus
Import-Module WebAdministration
# Accès via PSDrive
Get-PSDrive IIS
Set-Location IIS:\Sites
Get-ChildItem
# Module IISAdministration (moderne, recommandé)
Import-Module IISAdministration
Gestion des Sites
Créer un Site
# Créer le dossier
New-Item -Path "C:\inetpub\mysite" -ItemType Directory
# Créer le site
New-IISSite -Name "MySite" `
-PhysicalPath "C:\inetpub\mysite" `
-BindingInformation "*:80:mysite.corp.local"
# Ou avec New-Website (WebAdministration)
New-Website -Name "MySite" `
-PhysicalPath "C:\inetpub\mysite" `
-Port 80 `
-HostHeader "mysite.corp.local" `
-ApplicationPool "MySitePool"
Bindings
# Lister les bindings
Get-IISSiteBinding -Name "MySite"
# Ajouter un binding HTTP
New-IISSiteBinding -Name "MySite" `
-BindingInformation "*:80:www.mysite.com" `
-Protocol http
# Ajouter un binding HTTPS
$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object Subject -like "*mysite*"
New-IISSiteBinding -Name "MySite" `
-BindingInformation "*:443:mysite.corp.local" `
-Protocol https `
-CertificateThumbPrint $cert.Thumbprint `
-CertStoreLocation "Cert:\LocalMachine\My"
# Supprimer un binding
Remove-IISSiteBinding -Name "MySite" -BindingInformation "*:80:old.mysite.com"
# Modifier (via WebAdministration)
Set-WebBinding -Name "MySite" -BindingInformation "*:80:" -PropertyName Port -Value 8080
Gérer les Sites
# Lister les sites
Get-IISSite
Get-Website # WebAdministration
# Démarrer/Arrêter
Start-IISSite -Name "MySite"
Stop-IISSite -Name "MySite"
# Statut
Get-IISSite -Name "MySite" | Select-Object Name, State
# Supprimer
Remove-IISSite -Name "MySite" -Confirm:$false
Application Pools
Créer un App Pool
# Créer un pool
New-IISAppPool -Name "MySitePool"
# Configurer
$pool = Get-IISAppPool -Name "MySitePool"
$pool.ManagedRuntimeVersion = "v4.0"
$pool.ManagedPipelineMode = "Integrated" # ou "Classic"
$pool.Enable32BitAppOnWin64 = $false
$pool | Set-IISAppPool
# Configuration complète
$poolDefaults = @{
managedRuntimeVersion = "v4.0"
managedPipelineMode = "Integrated"
startMode = "AlwaysRunning"
processModel = @{
identityType = "ApplicationPoolIdentity" # ou "SpecificUser"
idleTimeout = "00:20:00"
loadUserProfile = $true
}
recycling = @{
periodicRestart = @{
time = "00:00:00" # Désactiver recyclage périodique
schedule = @(
@{ value = "03:00:00" } # Recycler à 3h du matin
)
}
}
}
Identité du Pool
# Types d'identité :
# - ApplicationPoolIdentity (défaut, recommandé)
# - NetworkService
# - LocalService
# - LocalSystem
# - SpecificUser
# Configurer un compte de service
$pool = Get-IISAppPool -Name "MySitePool"
$pool.ProcessModel.IdentityType = "SpecificUser"
$pool.ProcessModel.UserName = "CORP\svc_web"
$pool.ProcessModel.Password = "P@ssw0rd"
$pool | Set-IISAppPool
# Via WebAdministration
Set-ItemProperty "IIS:\AppPools\MySitePool" -Name processModel.identityType -Value 3
Set-ItemProperty "IIS:\AppPools\MySitePool" -Name processModel.userName -Value "CORP\svc_web"
Set-ItemProperty "IIS:\AppPools\MySitePool" -Name processModel.password -Value "P@ssw0rd"
Recyclage
# Configuration du recyclage
Set-ItemProperty "IIS:\AppPools\MySitePool" -Name recycling.periodicRestart.time -Value "00:00:00"
# Recycler à des heures spécifiques
Clear-ItemProperty "IIS:\AppPools\MySitePool" -Name recycling.periodicRestart.schedule
Add-WebConfiguration "/system.applicationHost/applicationPools/add[@name='MySitePool']/recycling/periodicRestart/schedule" -Value @{value="02:00:00"}
Add-WebConfiguration "/system.applicationHost/applicationPools/add[@name='MySitePool']/recycling/periodicRestart/schedule" -Value @{value="14:00:00"}
# Recycler sur mémoire
Set-ItemProperty "IIS:\AppPools\MySitePool" -Name recycling.periodicRestart.privateMemory -Value 1048576 # 1GB
# Recycler manuellement
Restart-WebAppPool -Name "MySitePool"
# Ou via IISAdministration
(Get-IISAppPool -Name "MySitePool").Recycle()
Applications et Virtual Directories
Applications
# Créer une application dans un site
New-WebApplication -Site "MySite" `
-Name "api" `
-PhysicalPath "C:\inetpub\mysite\api" `
-ApplicationPool "MySitePool"
# L'application sera accessible à : http://mysite.corp.local/api
# Lister les applications
Get-WebApplication -Site "MySite"
# Supprimer
Remove-WebApplication -Site "MySite" -Name "api"
Virtual Directories
# Créer un virtual directory
New-WebVirtualDirectory -Site "MySite" `
-Name "docs" `
-PhysicalPath "D:\SharedDocs"
# Accessible à : http://mysite.corp.local/docs
# Avec authentification pour UNC path
New-WebVirtualDirectory -Site "MySite" `
-Name "shared" `
-PhysicalPath "\\fileserver\share" `
-UserName "CORP\svc_iis" `
-Password "P@ssw0rd"
# Lister
Get-WebVirtualDirectory -Site "MySite"
Certificats SSL/TLS
Importer un Certificat
# Importer un PFX
$password = ConvertTo-SecureString "CertPassword" -AsPlainText -Force
Import-PfxCertificate -FilePath "C:\Certs\mysite.pfx" `
-CertStoreLocation Cert:\LocalMachine\My `
-Password $password
# Lister les certificats
Get-ChildItem Cert:\LocalMachine\My | Select-Object Thumbprint, Subject, NotAfter
# Créer un certificat auto-signé (dev/test)
New-SelfSignedCertificate -DnsName "mysite.corp.local","www.mysite.corp.local" `
-CertStoreLocation Cert:\LocalMachine\My `
-NotAfter (Get-Date).AddYears(2)
Configurer HTTPS
# Obtenir le thumbprint
$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object Subject -like "*mysite*"
# Ajouter binding HTTPS
New-IISSiteBinding -Name "MySite" `
-BindingInformation "*:443:mysite.corp.local" `
-Protocol https `
-CertificateThumbPrint $cert.Thumbprint `
-CertStoreLocation "Cert:\LocalMachine\My"
# Configurer SSL (exiger HTTPS)
Set-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/security/access" `
-Name "sslFlags" `
-Value "Ssl,SslNegotiateCert"
Redirection HTTP vers HTTPS
# Via URL Rewrite (nécessite le module)
# Installer : Web Platform Installer > URL Rewrite
# Ou via web.config
$webConfig = @"
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="HTTP to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
"@
$webConfig | Out-File "C:\inetpub\mysite\web.config" -Encoding UTF8
Authentification
Types d'Authentification
# Voir les authentifications configurées
Get-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/security/authentication/*" `
-Name "enabled"
# Activer/Désactiver l'authentification anonyme
Set-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/security/authentication/anonymousAuthentication" `
-Name "enabled" `
-Value $false
# Activer Windows Authentication
Set-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/security/authentication/windowsAuthentication" `
-Name "enabled" `
-Value $true
# Configurer les providers Windows Auth
Set-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/security/authentication/windowsAuthentication/providers" `
-Name "." `
-Value @{value="Negotiate";"NTLM"}
Basic Authentication
# Activer Basic Auth
Set-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/security/authentication/basicAuthentication" `
-Name "enabled" `
-Value $true
# ⚠️ Basic Auth transmet les credentials en Base64 (pas chiffré)
# → Toujours utiliser avec HTTPS
Logging et Monitoring
Configurer les Logs
# Emplacement des logs
Set-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.applicationHost/sites/site[@name='MySite']/logFile" `
-Name "directory" `
-Value "D:\Logs\IIS"
# Format de log (W3C recommandé)
Set-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.applicationHost/sites/site[@name='MySite']/logFile" `
-Name "logFormat" `
-Value "W3C"
# Rotation quotidienne
Set-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.applicationHost/sites/site[@name='MySite']/logFile" `
-Name "period" `
-Value "Daily"
# Champs à logger
Set-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.applicationHost/sites/site[@name='MySite']/logFile" `
-Name "logExtFileFlags" `
-Value "Date,Time,ClientIP,UserName,ServerIP,Method,UriStem,UriQuery,HttpStatus,TimeTaken,UserAgent"
Failed Request Tracing
# Activer le tracing
Set-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/tracing/traceFailedRequests" `
-Name "enabled" `
-Value $true
# Configurer les règles (tracer les erreurs 500)
Add-WebConfiguration -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/tracing/traceFailedRequests" `
-Value @{
path = "*"
provider = "WWW Server"
traceAllAfterTimeout = $true
}
Monitoring
# Statut des sites
Get-IISSite | Select-Object Name, State, Bindings
# Statut des pools
Get-IISAppPool | Select-Object Name, State, ManagedRuntimeVersion
# Worker processes
Get-Process w3wp | Select-Object Id, CPU, WorkingSet64, @{N='Pool';E={
(Get-WmiObject Win32_Process -Filter "ProcessId=$($_.Id)").CommandLine -replace '.*-ap "(.+?)".*','$1'
}}
# Requêtes en cours
Get-WebRequest | Select-Object url, timeElapsed, clientIP
Performances
Configuration Recommandée
# Compression dynamique
Set-WebConfigurationProperty -PSPath "MACHINE/WEBROOT/APPHOST" `
-Filter "system.webServer/urlCompression" `
-Name "doDynamicCompression" `
-Value $true
# Output caching
Add-WebConfiguration -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/caching/profiles" `
-Value @{
extension = ".aspx"
policy = "CacheUntilChange"
kernelCachePolicy = "CacheUntilChange"
}
# App Pool - Always Running (évite cold start)
Set-ItemProperty "IIS:\AppPools\MySitePool" -Name startMode -Value "AlwaysRunning"
Set-ItemProperty "IIS:\AppPools\MySitePool" -Name processModel.idleTimeout -Value "00:00:00"
# Application Initialization (préchauffe)
Set-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/applicationInitialization" `
-Name "doAppInitAfterRestart" `
-Value $true
Sécurité
Request Filtering
# Bloquer des extensions
Add-WebConfiguration -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/security/requestFiltering/fileExtensions" `
-Value @{fileExtension=".config"; allowed=$false}
# Limiter les verbes HTTP
Set-WebConfiguration -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/security/requestFiltering/verbs" `
-Value @{verb="TRACE"; allowed=$false}
# Limiter la taille des requêtes
Set-WebConfigurationProperty -PSPath "IIS:\Sites\MySite" `
-Filter "system.webServer/security/requestFiltering/requestLimits" `
-Name "maxAllowedContentLength" `
-Value 30000000 # 30MB
Headers de Sécurité
<!-- web.config -->
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
<add name="X-Frame-Options" value="SAMEORIGIN" />
<add name="X-XSS-Protection" value="1; mode=block" />
<add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains" />
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
Bonnes Pratiques
Checklist IIS:
Configuration:
- [ ] Un App Pool par application
- [ ] Identité ApplicationPoolIdentity
- [ ] Recycling à heure fixe (nuit)
- [ ] Logs sur partition séparée
Sécurité:
- [ ] HTTPS obligatoire
- [ ] Headers de sécurité
- [ ] Request filtering actif
- [ ] Authentification Windows si intranet
Performance:
- [ ] Compression activée
- [ ] Always Running pour apps critiques
- [ ] Application Initialization
- [ ] Output caching si applicable
Monitoring:
- [ ] Failed Request Tracing
- [ ] Logs W3C avec TimeTaken
- [ ] Alertes sur erreurs 500
Voir aussi :
- Certificate Services - Gestion PKI
- Windows Firewall - Règles pare-feu
- Performance Monitoring - Monitoring