Restriction du Windows Update Delivery Optimization par groupe ActiveDirectory

Le WUDO ou Windows Update Delivery Optimization est un composant Windows présent sous Windows 10 qui permet d'optimiser la bande passante réseau consommée lors de la distribution de mises à jour système via WSUS par exemple. En imaginant un réseau d'une dizaine de stations, une seule d'entre elles pourrait utiliser le WAN pour récupérer les mises à jour depuis un serveur WSUS situé en central et les autres utilisent le LAN pour les télécharger à partir de celle les ayant obtenues via le WAN afin d'éviter une saturation de ce dernier. Ce qui peut être un gain de bande passante peut avoir des effets de bord notables ; c'est pourquoi il est possible de contrôler finement le comportement du WUDO via GPO. Un moyen de mieux centrer son action est de passer par la création de groupes ActiveDirectory pour regrouper des stations ; c'est ce que je vais présenter dans cet article.

La problématique est la suivante : des stations du site fictif de Paris utilisent le WAN pour télécharger des mises à jour WSUS sur des stations à Londres. Afin d'éviter de saturer ce lien, on souhaite donc limiter le WUDO à récupérer des données depuis des stations d'un même site uniquement.

Voici la composition de cette maquette de test :

  • OU computers, comprenant 3 OU paris, bxl et london, comprenant les stations propres à chaque site.
  • OU wudo-grp, qui contiendra les groupes AD wudo_paris, wudo_bxl et wudo_ldn dans lesquels seront placées les stations de chaque site.

Il est nécessaire de créer une GPO par groupe AD, d'où l'importance de bien définir ses besoins et surtout, l'organisation qui va être adoptée pour bien séparer les flux de communication WUDO. Une séparation trop granulaire demandera beaucoup de travail d'administration et l'inverse n'aura probablement aucun effet de correction des effets de bord ! Cette GPO va prendre en paramètre unique le GUID du groupe, il faut donc le récupérer et surtout, le stocker quelque part pour toujours avoir une association facile entre GUID et GPO associée.

En Powershell, l'instruction suivante nous permettra de récuprer le GUID du groupe.

(Get-AdGroup wudo_paris).ObjectGuid.Guid

Bien entendu, une boucle foreach dans un script récupérant tous les groupes d'une OU permettra de tous les obtenir facilement.

Désormais, il faut s'occuper de la création des GPO. Les réglages qui nous intéressent sont dans Computer Configuration > Policies > Administrative Templates > Windows Components > Delivery Optimization.

La première option est le Download Mode, qu'il faut passer à 2. La description du paramètre explique bien les différentes options possibles. Il est important de noter que ce qui est désigné comme "LAN" ici n'est pas un LAN au sens physique du terme mais un réseau interne ActiveDirectory. Par exemple, si votre domaine s'appelle schmitouille.net, alors le LAN englobera toutes les stations dans schmitouille.net. Si vous avez des sous-domaines, alors le LAN considèrera les stations du sous-domaine, par exemple fr.schmitouille.net.

Ensuite, l'autre paramètre est Group ID. C'est ici que devra être renseigné le GUID du groupe correspondant. Ici, je vais placer le GUID du groupe wudo_bxl car c'est la GPO qui va régir le WUDO des stations du site fictif de Bruxelles.

Il ne me reste plus qu'à lier cette GPO sur l'OU contenant les stations, et non celle contenant les groupes. Toujours en restant dans le cadre du site de Bruxelles :

... et à répéter l'opération autant de fois que nécessaire. En fonction de l'architecture de l'ActiveDirectory, il peut être nécessaire d'appliquer un Security Filtering sur le groupe d'ordinateurs concerné afin d'être sûr que la GPO ne s'applique que sur les stations désirées.

Afin de faire en sorte que les paramètres soient pris en compte le plus rapidement possible, il est possible de forcer un gpupdate à distance via Powershell. Voici un snippet que j'ai réalisé permettant de passer sur toutes les stations désormais régies par ces politiques de groupe pour mettre à jour ces dernières (à noter qu'en fonction de la disponibilité des stations, des paramètres firewall ou des droits du compte l'exécutant, il peut y avoir des erreurs) :

$grouplist = Get-ADGroup -Filter 'Name -like "wudo_*"'
foreach ($group in $grouplist){
    $complist = Get-AdGroupMember $group
    foreach ($comp in $complist){
        Write-Host "Processing:"$comp.Name
        Invoke-GPUpdate -Computer $comp.Name -RandomDelayInMinutes 0
    }
}

Enfin, pour vérifier que la GPO est bien redescendue, il est possible d'utiliser la fonctionnalité Group Policy Result et d'avoir un rapport indiquant si oui ou non la GPO a bien été appliquée. Si oui, le WUDO de la station concernée ne pourra donc interroger que les membres du groupe AD dont le GUID correspond à la GPO appliquée.

Installation des drivers réseau pour une VM Windows Server 2016 sur hôte Proxmox VE 5

Voici ce qui m'est arrivé à la fin de l'installation d'un contrôleur de domaine de test sous 2016 en mode Core sur mon hyperviseur fonctionnant sous Proxmox VE 5. En cause, l'absence de drivers pour la carte réseau qui est de type virtIO.

sconfig m'indique bien que je n'ai pas de carte réseau active.

Il est donc nécessaire d'installer ces drivers. Le site de documentation de la distribution Fedora explique rapidement ce que sont ces drivers virtIO et pourquoi il est nécessaire de les installer à part. Dans le cas présent, l'installation va être très facile. Il suffit de télécharger l'ISO (dernière version stable ou le canal "développement"), la monter sur la VM et ensuite d'installer le pilote correspondant.

Il y a pléthore de pilotes sur cet ISO, celui qui nous intéresse est dans NetKVM\2k16\amd64. En partant du principe que l'ISO est monté sur le lecteur D:, cela nous donne ceci dans l'invite de commandes :

d:
cd NetKVM\2k16\amd64

Bien évidemment, on remplacera 2k16 par la version de Windows concernée. Il y a de multiples fichiers dans le répertoire, mais le pilote s'installe à partir du fichier inf. Il reste à appeler pnputil pour installer le driver :

pnputil -i -a netkvm.inf

Quelques secondes plus tard :

Comme indiqué dans la documentation de Fedora, le pilote n'est pas signé par Microsoft - qu'importe.

L'instruction se termine, il suffit alors d'appeler de nouveau sconfig et de se rendre dans les propriétés de la carte réseau pour voir qu'elle est désormais visible et configurable !

Quelques billes pour automatiser la préparation d'un serveur en Powershell

Je déploie régulièrement des VM à partir d'un template, seulement il reste pas mal d'opérations à faire à la main, comme le changement de nom, la configuration du réseau, l'installation de certaines applications et paramètres qui redescendent pas forcément par GPO.

Je vais donc présenter plusieurs instructions et snippets Powershell qui pourront fournir une bonne base pour la création d'un script complet pouvant être intégré dans un template et exécuté directement après le déploiement.

Tout d'abord, le changement du nom du serveur. On peut faire quelque chose de sympa comme ceci :

$hostname = $env:computername
Write-Host "Current Server name: $hostname"
$newhostname = Read-Host "New hostname"
Rename-Computer -NewName $newhostname
Write-Host "A reboot is required and will be performed in approx. 10 seconds. The script will automatically start after reboot to continue post-deployment operations."
shutdown -r -t 10

On affiche le nom actuel du serveur, puis un prompt permettant de saisir le nouveau nom de machine. Un reboot permettra de prendre en compte le changement.

Après le redémarrage, on peut passer à la configuration de la carte réseau. En fonction de la configuration de la machine, cela peut être délicat puisqu'il faut être sûr d'affecter l'IP à la bonne carte réseau ; pour cela, on va donc récupérer toutes les cartes réseaux branchées sur le système, puis faire un filtre par nom et qui fonctionnent en IPv4. Par exemple, si la carte réseau s'appelle Ethernet0 :

$ipv4 = Read-Host "IPV4 address"
$gateway = Read-Host "Gateway"
$dnsprim = Read-Host "Primary DNS"
$dnssec = Read-Host "Secondary DNS"

$networkcards = Get-NetIPInterface | Where-Object {$_.InterfaceAlias -eq "Ethernet0" -and $_.AddressFamily -eq "IPv4"}
$interfaceindex = $networkcards[0].ifIndex
New-NetIPAddress -InterfaceIndex $interfaceindex -IPAddress $ipv4 -PrefixLength 24 -DefaultGateway $gateway
Set-DnsClientServerAddress -InterfaceIndex $interfaceindex -ServerAddresses ($dnsprim,$dnssec)

Get-NetIPInterface avec son pipe nous permet de rechercher les interfaces ayant pour nom Ethernet0 et configurées en IPv4. On récupère donc la carte qui est retournée par l'instruction et son index (qui n'est naturellement pas 1, ce serait trop facile !), qui nous permet ensuite de pouvoir le passer en paramètre de l'instruction New-NetIPAddress qui va se charger de coller la configuration IP à la carte. Le masque de sous réseau ne s'exprime pas en 255.255.255.0 mais notation CIDR, soit 24. Des tables de conversion sont facilement accessibles grâce à n'importe quel moteur de recherche, vous pouvez utiliser celle-ci. Si l'instruction est bien passée, elle retournera alors plusieurs informations quant à l'interface.

Ensuite, maintenant que le réseau est configuré, on peut joindre la machine au domaine.



Add-Computer -DomainName "super-domaine.local"
if ($?){ Write-Host "A reboot is required and will be performed in approx. 10 seconds. The script will automatically start after reboot to continue post-deployment operations."
shutdown -r -t 10 }

Un prompt devrait apparaître pour demander un identifiant et un mot de passe d'un compte autorisé à ajouter des machines au domaine. Si la jonction se fait bien, alors le code dans la boucle if est exécuté et la machine redémarre après environ 10 secondes.

La machine mise sur le domaine, les divers paramètres poussés par GPO devraient redescendre (il faut bien évidemment pas oublier de déplacer l'objet Ordinateur qui s'est créé dans l'AD dans la bonne OU, sinon ça risque de ne pas bien marcher 😱). Cependant, d'autres opérations ou paramètres peuvent être modifiés par Powershell ; en voici quelques-uns.

Autorisation de l'exécution de scripts Powershell sans restriction :

Write-Host "Setting Powershell execution policy to Unrestricted..."
Set-ExecutionPolicy Unrestricted

Désactivation du pare-feu pour le domaine :

Set-NetFirewallProfile -Profile Domain -Enabled False 

Si on souhaite tout automatiser et placer dans un même script, il faut prévoir la phase de reboot suite au changement de nom de la machine et la jonction au domaine (bien que la commande Add-Computer tolère un renommage de la station dans l'instruction). Pour n'utiliser qu'un seul script, et faire en sorte qu'il reprenne exactement là où il s'était arrêté, on peut placer chaque étape dans une fonction, et placer en paramètre facultatif le numéro de l'étape sur laquelle le script démarre ; ensuite une tâche planifiée démarre le script à l'ouverture de session de l'administrateur local.

Déclaration du paramètre :

Param
([string]$step)

Ensuite, une fonction pour créer la tâche, qui elle-même va prendre un paramètre :

function createtask{
param($rebootstep)
$TaskDetails = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType ServiceAccount -RunLevel Highest
$TaskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "C:\post-deployment.ps1 -s $rebootstep"
$TaskSched = New-ScheduledTaskTrigger -AtLogOn
$TaskName = "PostDeployReboot"
Register-ScheduledTask -Action $TaskAction -Principal $TaskDetails -Trigger $TaskSched -TaskName $TaskName
}

Et on appelle cette fonction après le renommage de la machine par exemple :

Rename-Computer -NewName $newhostname
createtask(2)

Ainsi, au début du script, on peut placer cette instruction qui appellera la fonction setnetwork dans laquelle le code pour paramétrer la carte réseau sera placé :

if ($step -eq "2") { setnetwork }

La tâche planifiée exécutant le script avec le paramètre -s 2, le script démarrera directement sur cette étape.

Configuration d'OpenVPN pour accéder aux autres machines du réseau

Pour des raisons de sécurité, j'applique des filtres IP sur les principaux points d'entrée de mon cloud, avec un serveur ouvert vers l'extérieur qui sert de passerelle vers le réseau interne. Ayant installé OpenVPN pour d'autres usages, je me suis dit qu'il ne serait pas idiot de se servir d'OpenVPN pour accéder au réseau local et donc accéder aux machines de mon réseau cloud sur ma station personnelle, ce qui fait que peu importe mon emplacement, je suis toujours sur une IP acceptée par les différents services et accès de ma plateforme.

Pour ce faire, il suffit tout simplement d'aller dans les propriétés d'un utilisateur OpenVPN, et d'autoriser cet utilisateur à accéder à d'autres sous-réseaux :
Il reste donc à saisir par exemple 172.21.1.0/24 si les machines auxquelles on souhaite accéder sont sur ce sous-réseau.
Une fois la configuration appliquée, un simple ping permet de vérifier les machines du réseau local répondent, et on peut même s'y connecter directement, car étant sur le réseau local, nous ne sommes plus concernés par d'éventuelles règles NAT appliquées sur l'interface physique du serveur.
Ainsi, sur chacun de mes serveurs GNU/Linux, mon fichier /etc/hosts.allow est comme ceci :

sshd : 12.34.56.78 : allow
sshd : 12.34.56.79 : allow
sshd : ALL : deny

La machine est donc accessible uniquement via SSH par le serveur qui fait office de passerelle, soit par le VPN.

Dans le cadre d'un usage du bureau à distance sur une VM Windows, on peut filtrer grâce aux règles de pare-feu et aux étendues :

Je peux donc laisser plus sereinement ma VM Windows ouverte en TSE car elle rejettera systématiquement ce qui ne provient pas de mon réseau local.

Création d'un réseau interne grâce au NAT sur Proxmox VE 5

Il y a quelques semaines maintenant, j'ai repensé mon cloud personnel. Auparavant basé sur ESXi, j'ai changé de technologie pour revenir sur quelque chose de plus "léger" que je connaissais déjà : Proxmox. Cet hyperviseur basé sur Debian m'avait causé dans sa version 4 pas mal de maux de tête pour réussir à monter un réseau et donner accès à internet à mes VM sans qu'elles n'utilisent d'IP globales ; la version 5 ne fait pas vraiment mieux, c'est pourquoi je vais partager dans cet article les opérations nécessaires via l'interface de Proxmox et via la modification du fichier /etc/network/interfaces.

Sur l'hôte, dans les paramètres réseau, doivent apparaître juste après l'installation la carte physique de la machine et un bridge. Il est très important de ne pas y toucher sous peine de rendre la machine injoignable après le redémarrage ou la recharge de la configuration des cartes. L'interface web ne semblant pas traduire correctement les valeurs saisies en un fichier de configuration propre, on va donc passer par la modification en direct du fichier /etc/network/interfaces pour y créer un deuxième bridge qui sera notre réseau local.

En l'ouvrant avec nano en utilisateur root, il doit ressembler à ceci (je vais appeler dans cet exemple ma carte réseau eth0 et mon IP 26.10.19.91), en gras les paramètres qu'il faut absolument vérifier afin qu'ils soient sur cette valeur :

auto lo
iface lo inet loopback


iface eth0 inet manual


auto vmbr0
iface vmbr0 inet static
  address 26.10.19.91
  netmask 255.255.255.0
  gateway 26.10.19.1
  bridge_ports eth0
  bridge_stp off
  bridge_fd 0 


auto vmbr1
iface vmbr1 inet static
  address 192.168.2.1
  netmask 255.255.255.0
  bridge_ports none
  bridge_stp off
  bridge_fd 0

Le vmbr1 est le nouveau bridge sur lequel nous allons raccorder nos VM pour leur donner accès à internet et pouvoir faire du NAT afin de les joindre depuis l'extérieur sur la même IP que l'hôte et qu'elles puissent éventuellement communiquer entre elles.

Un redémarrage plus tard (relancer les interfaces réseaux n'est pas suffisant), le nouveau pont doit apparaître dans la section réseau de l'interface web :

Par la suite, en configurant le réseau sur les VM, on indiquera une adresse IP comprise entre 192.168.2.2 et 192.168.2.254 (si vous avez laissé le sous-réseau par défaut) et 192.168.2.1 en gateway. Concernant les serveurs DNS, il est possible d'utiliser des serveurs DNS externes ou internes ; parmi les DNS publics, on peut renseigner par exemple 1.1.1.1 qui est le DNS public CloudFlare, ou le réputé 8.8.8.8 de Google.

Maintenant que les machines peuvent avoir une IP définie, afin de les joindre via certaines applications, il ne reste plus qu'à faire le NAT dans iptables. Toujours en root, on autorise le routage des paquets venant sur l'interface vmbr0 (qui est liée à eth0, la carte physique liée à internet) vers notre sous-réseau fraîchement créé :

iptables -t nat -A POSTROUTING -s '192.168.2.0/24' -o vmbr0 -j MASQUERADE

Et enfin, si l'on souhaite ouvrir le port 80 sur 192.168.2.2 :


iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to 192.168.2.2:80

A noter que si l'on souhaite simplement retirer une règle, on remplace -A par -D. iptables ne sauvegardant pas de manière permanente les règles, elles sont perdues au redémarrage. Il est possible d'installer des applications permettant de faire des backup/restore des règles ou bien d'ajouter les règles au fichier /etc/network/interfaces en utilisant post-up pour les règles à exécuter une fois que l'interface est montée, et post-down pour celles a exécuter quand l'interface est désactivée. Par exemple :

post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to 192.168.2.2:80

post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to 192.168.2.2:80

Pour plus d'informations concernant iptables et ses possibilités, je vous renvoie à ce lien.