10 May 2018, 00:00

Mise en place d'une réplication/failover AD/DNS/DHCP/DFS sur 2 Windows Server

Préambule

Je pars d’une situation où j’ai déjà un serveur Windows 2012R2 configuré en controleur de domaine, avec GPO et partage de fichiers. Je veux ajouter un 2e serveur sous Windows Server 2016, qui fasse office principalement de failover si un des 2 serveurs tombe en panne. Ceci pour les rôles de contrôleur de domaine, de serveur DHCP, serveur DNS, de serveur SMB et déploiement automatique de partages réseaux et d’imprimantes.

Le domaine est WINDOMAIN, le serveur actuel est WINDOMAIN\DC1.

Configurer le serveur secondaire

On commence par relier le serveur au réseau, on lui configure une adresse ip fixe, le hostname souhaité (ici DC2). on le connecte au domaine.

On peut ensuite installer le rôle AD DS, puis promouvoir le serveur en contrôleur de domaine.
La réplication de l’AD se fait automatiquement, avec toutes les GPO.

DNS

Intégration à l’AD

Normalement, le serveur DNS est installé et configuré en même temps que le serveur AD DS. Ceci permet aux enregistrements DNS d’être stockés dans l’AD directement, et donc d’être répliqués entre tous les controleurs de domaine. Cela se vérifie dans le gestionnaire DNS, avec un clic droit -> Propriétés sur une zone, on doit voir l’Etat “Intégré à AD”.
Ceci ne fonctionne que si les 2 serveurs DNS sont aussi des controleurs de domaine, ce qui est le cas ici. Si un serveur DNS n’est pas controleur, il faut passer par la création sur le second serveur d’une zone secondaire qui pointera vers le premier serveur).

Un peu plus d’infos chez Microsoft

Redirecteurs

Toujours dans le gestionnaire DNS, dans les propriétés de chaque serveur, il faut penser à aller vérifier les redirecteurs (serveur DNS utilisé si le serveur intégré ne sait pas résoudre, c’est-à-dire pour tout ce qui ne relève pas du domaine). Typiquement, on peut mettre l’IP de notre box, ou 8.8.8.8 par exemple. Il y’a aussi l’option de se rapatrier sur les serveurs DNS racines en cas d’indisponibilité des redirecteurs. On trouve la liste de ces serveurs dans l’onglet “Indications de racine”.

Distribution par DHCP

Enfin, il faut aller paramétrer les options du DHCP pour qu’il distribue les 2 serveurs DNS. Pour ceci, dans DC1 (actuellement le seul serveur DHCP), aller dans le gestionnaire DHCP, IPv4 -> Étendue -> Options d’étendue et ajouter l’IP du nouveau serveur dans les Serveurs DNS (006).

Note : si un des 2 serveurs venait à être en panne/hors-ligne durablement, penser à s’assurer que le serveur toujours en place est bien distribué en serveur primaire, ceci accélérera la résolution DNS.

DHCP

La première étape est d’avoir une étendue active sur un des 2 serveurs, dans cet exemple sur DC1. Si ce n’est pas le cas, on peut en créer une dans le gestionnaire DHCP -> Nouvelle étendue. L’installation est complètement guidée.
Penser à spécifier les options telles que serveurs DNS, passerelle par défaut.

Sur DC2, installer le rôle Serveur DHCP. Ne pas configurer d’étendue maintenant, elle va être automatiquement répliquée depuis DC1.
Aller sur DC1 dans le gestionnaire DHCP, IPv4 -> Clic-droit sur “Étendue” -> Configurer un basculement
Suivre les étapes en ajoutant l’IP du serveur secondaire (DC2).

Au cours de la création du basculement, les options du serveur DHCP de DC1 seront répliquées sur DC2 (étendue, route par défaut, serveur DNS etc°. Toutefois ces options ne seront par la suite plus synchronisées automatiquement. Pour les synchroniser, on peut lancer sur le serveur “source”, qui possède les informations à jour, la commande Powershell suivante :

Invoke-DhcpServerv4FailoverReplication

qui va répliquer l’ensemble de ses paramèters sur tous les serveurs partenaires.
Il y’a aussi un script planifié qui permet de faire ceci automatiquement, disponible sur cette page avec l’archive zip mirroré sur mon memo.

Si on souhaite supprimer la relation de basculement, il faut savoir que si on procède à la déconfiguration du basculement sur DC1, cela supprimera automatiquement l’étendue sur DC2 (et vice-versa).

Partage de fichiers

Afin d’assurer l’accès aux partages réseaux même si un des 2 serveurs (hébergeant directement les données) tombe, nous allons passer par la réplication DFS. Celle-ci va nous permettre une synchronisation instantanée et permanente de l’état des dossiers de travail, tout en y accédant de manière transparente par le réseau, via un espace de nom DFS.

Dans mon cas, je pars d’un dossier de travail déjà existant, sur DC1, avec le chemin D:\Travail\. Celui-ci est paramétré avec des droits d’accès spécifiques, et le partage réseau est déployé automatiquement via GPO avec le chemin \\DC1\Travail\.

Configuration de la réplication DFS (DFSR)

Il faut commencer par installer le rôle Services de fichiers et de stockage -> Services de fichiers et iSCSI -> Espaces de noms DFS et Réplication DFS sur DC1 ET sur DC2.

On lance le Gestionnaire de système de fichiers distribué DFS.
Réplication -> Nouveau groupe de réplication.... J’ai laissé le choix par défaut, groupe de réplication multi-usages.
On donne un nom au groupe de réplication, dans mon cas “Travail”.
On ajoute DC1 et DC2 dans la liste des serveurs.
Pour une réplication dans les 2 sens, quel que soit le serveur sur lequel les données sont modifiées, on choisit “Maille pleine”. J’ai laissé les options de bande passante par défaut, puisq’on est ici en réseau local.

On prend bien garde à choisir le serveur qui contient actuellement les données en tant que Membre principal. Il s’agit ici de DC1, car DC2 ne contient actuellement aucune donnée. Ainsi, au cours de la synchro initiale, toutes les données présentes actuellement sur DC1 seront répliquées sur le ou les autres serveurs. une fois la synchro initiale terminée, cela ira dans les 2 sens.

On choisit ensuite le dossier local où sont stockées les données sur DC1. C’est D:\Travail comme indiqué au-dessus.
Note : Microsoft eux-même déconseillent de répliquer directement une lettre de lecteur, bien que ce soit censé fonctionner. J’ai personnellement eu des soucis lorsque j’ai essayé. Il faut ensuite la réplication sur chaque serveur membre. On coche la case Activé, et on définit un chemin local sur le membre en question. Il n’est pas obligatoire que tous les membres aient le même chemin d’accès local.

On valide, et la réplication commencera sous peu. Les données seront ainsi sur les 2 serveurs. Toutefois, le partage réseau déployé chez les clients ne fait toujours appel qu’au serveur DC1.

Par défaut, lorsque le service DFSR s’arrête, par exemple lorsqu’un serveur reboote, le système lui laisse 30 secondes pour s’éteindre proprement. S’il sépasse ce délai, alors la fermeture sera forcée, de façon brutale.
Or il arrive régulièrement que le service aie besoin de plus de temps que ça pour s’éteindre (dans le cas d’une grosse base de fichiers). Pour éviter ce problème, on peut, sur chaque serveur, accéder à la clé de registre

`HKLM\SYSTEM\CurrentControlSet\Control`

et régler la valeur WaitToKillServiceTimeout sur le nombre de millisecondes que l’on souhaite accorder à l’extinction (de chaque service). Par exemple, 600000 pour laisser 10 minutes. À noter que cette valeur ne peut excéder 1h, sans quoi elle est réinitialisée à la valeur par défaut de 30 secondes. Source

DFSR - Problème de synchronisation

Il peut arriver que certains dossiers ou fichiers ne soient pas répliqués correctement. Plusieurs raisons peuvent expliquer ceci, des problèmes de taille de la Staging Area étant régulièrement évoqués. (cf comment définir une taille de staging)

Une autre raison possible est que les éléments en question soient chiffrés. DFSR ne synchronise pas les fichiers chiffrés.
Le script suivant, strippé de cette page (script bien plus complet et détaillé), permet de lister les fichiers chiffrés dans le fichier $logFile, puis de les déchiffrer

$logFile = "C:\Users\Administrateur\Desktop\EncryptedFiles.log"
$path = "X:\path\to\data"

$encryptedfiles +=  Get-ChildItem $path -File -Recurse -Force -ErrorAction SilentlyContinue |
	                Where-Object { $_.Attributes -match "Encrypted" } |
	                Select-Object -ExpandProperty FullName
	                
foreach ($file in $encryptedfiles){
	Add-Content $logFile "$file"
	(Get-Item -Force -LiteralPath $file).Decrypt()
	}

$encryptedfolders += Get-ChildItem $path -Directory -Recurse -Force -ErrorAction SilentlyContinue |
	                 Where-Object { $_.Attributes -match "Encrypted" } |
	                 Select-Object -ExpandProperty FullName

foreach ($folder in $encryptedfolders){
	Add-Content $logFile "$folder"
 	cipher.exe /d /i $folder
}

juste avant la dernière accolade pour ajouter le déchiffrement automatique.

Une autre raison possible est que DFSR, par design, ne synchronise pas les dossiers/fichiers avec l’attribut “temporaire”. Source : https://blogs.technet.microsoft.com/askds/2008/11/11/dfsr-does-not-replicate-temporary-files/
Or, il peut arriver, sur de gros volumes de données, que des dossiers légitimes contiennent, par erreur (humaine ?), cet attribut. Rien n’indique graphiquement sa présence, et l’utilitaire attrib.exe non plus. Il faut utiliser fsutil pour le consulter.

fsutil usn readdata X:\path\to\folder\

qui retournera quelque chose du genre

Major Version : 0x2
Minor Version : 0x0
FileRef# : 0x0021000000002350
Parent FileRef# : 0x0003000000005f5e
Usn : 0x000000004d431000
Time Stamp : 0x0000000000000000 12:00:00 AM 1/1/1601
Reason : 0x0
Source Info : 0x0
Security Id : 0x5fb
<b>File Attributes : 0x120</b>
File Name Length : 0x10
File Name Offset : 0x3c
FileName : test.txt

On y voit que, dans les attributs du fichier, le masque 0x100 est présent. Selon la table donnée dans le lien ci-dessus, il correspond à l’attribut TEMPORARY.

Pour le supprimer récursivement, on passe par Powershell :

Get-childitem X:\PATH -recurse | ForEach-Object -process {if (($_.attributes -band 0x100) -eq 0x100) {$_.attributes = ($_.attributes -band 0xFEFF)}}

Configuration de l’espace de nom DFS (DFSN)

Généralités

L’idée est de pouvoir centraliser les partages réseaux en y accédant via le nom de domaine. Par exemple, au lieu de déployer \\DC1\Travail, on va déployer le partage \\WINDOMAIN\Travail, et ce sera un des serveurs hébergeant l’espace de nom Travail qui va répondre.

Cette techno est complètement dissociable de la réplication, bien qu’elles soient souvent utilisées ensemble. On peut décider de partager sous des chemins unifiés des ressources venant de serveurs différents (par exemple \\DC1\Travail et \\DC2\Direction, même si uniques sur leurs serveurs respectifs, peuvent être accessibles sous \\WINDOMAIN\Travail et \\WINDOMAIN\Direction). On peut aussi utiliser la réplication sans espace de noms, juste pour dupliquer les données d’un site à l’autre par exemple.

Si 2 serveurs hébergent le même espace de nom, mais sans réplication des dossiers, le contenu affiché sera alternativement le contenu de l’un ou l’autre. Par exemple, si \\DC1\Travail et \\DC2\Travail sont tous les 2 référencés par l’espace de nom \\WINDOMAIN\Travail mais que les 2 dossiers ne sont pas répliqués et ont des contenus différents, on ne sait jamais quel sera le contenu affiché par \\WINDOMAIN\Travail, ce sera celui qui répond le plus vite.

Mise en place

On ouvre le gestionnaire DFS.
Espace de noms (clic-droit) -> Nouvel espace de noms. On choisit DC1 comme premier serveur. On nomme notre espace de nom, ici Travail ; Dans Modifier les paramètres, on peut choisir l’emplacement des données locales. On choisit ici D:\Travail, comme défini précédemment, et on choisit les droits d’accès Admin : Full ; Users : RW (les vrais droits d’accès sont gérés par le NTFS).
On choisit l’option “Espace de noms de domaine”, puis on valide la création.

Le serveur DC1 est maintenant prêt à répondre lorsqu’on appelle \WINDOMAIN\Travail. On veut maintenant que DC2 puisse répondre aussi. Pour ceci, dans le gestionnaire DFS, sous Espaces de noms, clic-droit sur \WINDOMAIN\Travail -> Ajouter un serveur d’espaces de noms. Comme ci-dessus, on rentre le nom du serveur, on choit l’emplacement local des données, on met les droits sur le partage et on valide.

Et voilà : les 2 serveurs sont désormais capables de répondre lorsque l’on interroge le partage directement auprès du domaine, et grace à la combinaison avec la réplication, la continuité en cas de chute d’un serveur est quasi-transparente (à un caffouilage d’explorer près, sur les postes clients).

Note : il est possible, directement sous l’espace de noms DFS? de “Publier” des dossiers, qui seront créés puis partagés automatiquement, et référencés dans le gestionnaire. Il n’est pas du tout obligatoire de les utiliser si l’on souhaite créer des sous-dossiers et les partager, et le faire manuellement permet une plus grande souplesse (chemin du partage réseau notamment).

18 Dec 2017, 00:00

Notes en vrac sur Azure AD Connect et Office 365

Mise en cohérence des domaines

Dans mon cas, l’AD avait été pis en place il y’a longtemps, le domaine local était du genre domain.oldcompany.com, mais les utilsateurs utilisaient aujourd’hui des adresses mail du genre user@newcompany.fr, et l’abonnement O365 avait pour domaine initial unusedcompany.onmicrosoft.com.

Dans ces conditions, la synchro de l’AD vers Azure donnait des identifiants du type nomprenom@unusedcompany.onmicrosoft.com, ce qui rend tout plus pénible, par exemple la connexion à OWA qui ne marche pas avec d’éventuels alias, mais qu’avec cet identifiant.

Comme le domaine initial ne peut être changé, il faut ajouter et vérifier le domaine newcompany.fr dans la gestion des domaines sur le portail O365, connecté en admin de l’abonnement. Pour le vérifier, il faudra aller mettre une preuve TXT dans la zone DNS.
Il faut ensuite ajouter un nouveau suffixe UPN au domaine (Outils d’administration -> Domaines et approbations Active Directory -> Propriétés -> Suffixes UPN), on ajoutera ici newcompany.fr car c’est l’adresse couramment utilisée par l’entreprise. Il faut ensuite modifier les suffixes UPN des utilisateurs dans les Utilisateurs et Ordinateurs AD, pour les passer de p.nom@domaine.oldcompany.fr à p.nom@newcompany.fr. Il est possible de le faire en PowerSehll, par exemple avec ce script

Ainsi, les utilisateurs auront un seul couple adresse/password pour se connecter à tout (Session sur le domaine, OWA, Portail O365 pour télécharger les logiciels etc).

Préparer l’AD local pour la synchro

Pour synchroniser un Active Directory local avec les services Azure Active Directory, il faut commencer par préparer l’AD local (notamment étendre le schéma AD sur un serveur Windows 2012). Cette page de Microsoft détaille beaucoup plus la précédure.

Il faut récupérer une installation d’Exchange 2013, par exemple sur cette page de chez Microsoft. On la décompresse, on lance cmd puis la commande suivante :
Setup.exe /PrepareSchema /IAcceptExchangeServerLicenseTerms

Une fois que le schéma est préparé, on peut identifier les incohérences dans l’annuaire avant de synchroniser avec O365. Pour ça, on utilise l’outil IdFix (DL). Dans le cas où une offre dediée à O365 a été souscrite, il faut aller dans les paramétres et choisir “Dedicated” au lieu de “Multi-tenants”. On clique sur Query, on le laisse chercher, on vérifie puis acccepte les modifications, on fait Apply et on voit ce que ça donne. Si tout va bien, on peut passer à la synchro avec Azure. Si il y’a des problèmes (par exemple attributs non-existants), revérifier que l’AD a bien été préparé tel qu’indiqué sur le tuto de Microsoft.

Mise en oeuvre Azure AD Connect

Télécharger AAD Connect. La dernière version à prendre en charge Windows Server 2012 R2 est la 1.6.16.

Synchronisation du hachage de mot de passe.
Utilisé l’UPN (userPrincipalName) comme nom d’utilisateur AAD.

Powershell

Pour charger le module :
Import-Module ADSync
ou si ça ne fonctionne pas :
Import-Module -Name "C:\Program Files\Microsoft Azure AD Sync\Bin\ADSync" -Verbose

Une fois installé et configuré, il est possible de synchroniser manuellement avec la commande PowerShell :
start-adsyncsynccycle -policytype delta

Vérification de la synchro

Les utilsateurs et groupes doivent apparaître dans le centre d’admin Office.
On peut aussi vérifier explicitement ici :
https://admin.microsoft.com/#/dirsyncmanagement

07 Oct 2014, 00:00

Sauvegarder via Rsync un backup Time Machine

Lorsqu’on sauvegarde avec Time Machine sur un disque réseau (fonctionnement différent du disque local), les données sont stockées au format .sparsebundle, une image disque qui s’étend à volonté, et qui contient un plusieurs anciennes versions des fichiers. Bien qu’elle apparaisse en tant que fichier sous OSX, une image qu’on peut monter dans le Finder pour en lire/écrire le contenu, c’est en réalité un dossier, qui contient quelques petits fichiers descriptifs, et surtout un gros dossiers, bands, qui contient lui-même toutes les données de l’image, découpé en fichiers de 8,4 Mo. Seule une petite partie de ces fichiers est mise à jour lors d’une sauvegarde Time Machine, et seule cette petite partie sera synchronisée via Rsync (environ 300 Mo. Il va de soi qu’avoir une connexion avec un bon upload, dans le cas d’une sauvegarde réellement distante, est un gros plus.

L’idée du script qui va suivre est de, régulièrement :

  • déclencher une sauvegarde Time Machine
  • monter le volume de sauvegarde (volume réseau, appelé “Time Capsule” ici, bien que ce puisse être n’importe quel volume proprement configuré) sur un point de montage précis
  • synchroniser le point de montage via rsync, avec un serveur ssh (par définition n’importe où dans le monde)

Les prérequis sont :

  • avoir configuré, via GUI ou autre, Time Machine, et être sûr que le setup fonctionne correctement
  • avoir configuré la redirection de ports sur le routeur devant le serveur ssh
  • avoir une configuré une authentification ssh sur le serveur via clé, sans demande de mot de passe, pour pouvoir l’automatiser
  • savoir identifier la time capsule sur le réseau, y accéder via hostname et connaître un couple user/password valide pour la lecture des données
  • avoir désactivé la planification de Time Machine. Le script s’occupe de lancer la sauvegarde, et une MAJ du contenu du sparsebundle pendant la synchronisation distante via rsync pourrait créer une incohérence dans les données.
  • avoir une système de fichiers de destination (sur le serveur ssh) qui supporte les liens durs (hard-link). Typiquement ext4. Bien qu’on stocke du HFS+, il n’est pas nécessaire que cette destination sot en HFS+, car le .sparsebundle contient un système de fichier virtuel, qui s’occupe de conserver toutes les permissions/ACL/attributs étendus nécessaires.

Voici le script proprement dit, très inspiré de cet article, avec un bon paquet de code copié/collé. Cependant, je choisis de simplement conserver les x dernières versions de la sauvegarde. En effet, Time Machine s’occupe déjà de faire un historique régulier (journalier, mensuel, annuel etc), le but de cette sauvegarde est simplement de la déporter sur un site externe, tout en pouvant retrouver une ancienne version en cas de corruption des données Time Machine, et en conservant la facilté de restauration. Ainsi, avec le paramètre daystokeep=90, nous disposons de 3 mois d’historique du contenu de la Time Capsule.

#!/bin/sh

### VARS
  # local
identifier=`hostname`
# the following folder will store lock and log files
filesPath="/path/to/folder with spaces/"  # must contain the trailing /
logfile="${filesPath}${identifier}.log"
lockfile="${filesPath}${identifier}.lck"


  # TimeCapsule (source)
  # should match the Time Machine settings (via TM GUI)
  # name is the Zeroconf name provided in the "Time Capsule" tab within the Airport Utility, finishing by .local
  # for the actual Time Capsule, username seems to be indifferent, but you need the correct password
  # for any AFP share server, username have to be correct
tc_name="Time-Capsule.local"  # it never contains spaces
tc_share="Server Backups"
tc_user="timemachine"
  # if password contains a @ sign, replace it with %40. Spaces are OK.
tc_pw="password %40 TimeCapsule"
tc_mount_point="/Volumes/TC/"  # must contain the trailing /
  # this var could be retrieved from the hostname, but is not for the moment
tc_file_name="iMac de User.sparsebundle"


  # Remote disk (destination)
ssh_user='backupuser'
ssh_server='storage.mydomain.com'
ssh_port=1111
ssh_connect="${ssh_user}@${ssh_server} -p $ssh_port "
target="/path/to/folder/" # must contain the trailing /

###  END OF VARS



# Date for this backup.
date=`date '+%Y-%m-%d_%Hh%Mm'`
# Process ID for this backup
mypid=${$}

### Log beginning of the backup
echo "\n" >> "${logfile}"
if [ ! -d "$filesPath" ]
  then mkdir "$filesPath"
  echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] -- $filesPath was just created" >> "${logfile}"
fi

echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] -- backup started" >> "${logfile}"




###  Check if process is already running to avoid multiples backups at the same time
###  which could corrupt data
if [ -f "${lockfile}" ]
then
  # Lockfile already exists, check if it belongs to a running process
  read -r lockpid < "${lockfile}" #Read the first line which contains a PID
  if [ -z "`ps -p ${lockpid} | grep ${lockpid}`" ]
  then
	# The process doesn't exist anymore. Should there be an incomple folder, it will be removed at the end of the script.
	echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Lockfile for ghost process (PID: ${lockpid}) found, continuing backup." >> "${logfile}"
  else
	echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Lockfile '${lockfile}' for running process (PID: ${lockpid}) found, backup stopped." >> "${logfile}"
	exit 73 # can't create (user) output file
  fi
fi
# The lockfile doesn't exist or belongs to a ghost process, make or update it containing the current PID.
echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] -- Création du fichier lock" >> "${logfile}"
echo ${mypid} > "${lockfile}"


### Launch the Time Machine Backup
# On OSX 10.6, the command `/System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd-helper` is a "BACKUP NOW" command
#On 10.7 and later, Apple introduced the `tmutil` command which would allow to do the same
echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Time Machine backup launched" >> "${logfile}"
/System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd-helper

## The backupd-helper command quits before the save is really finished
## so we check the existence of the process 'backupd'
while [ `/bin/ps -arxo state,comm | /usr/bin/grep backupd | wc -l` -ne 0 ];
do
	echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Time Machine backup still working. Waiting 180 seconds" >> "${logfile}"
	sleep 180
done
echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Time Machine backup succeed !" >> "${logfile}"



### Check if the ssh connection can be made, a ssh keypair without keyphrase must exist.
ssh -q -q -o 'BatchMode=yes' -o 'ConnectTimeout 10' ${ssh_connect} exit &> /dev/null

if [ $? != 0 ]
then
  echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] SSH connection ${ssh_connect} failed." >> "${logfile}"

  # Remove lockfile
  rm -f "${lockfile}"

  exit 69 # service unavailable
fi
echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] SSH connection ${ssh_connect} succeed." >> "${logfile}"


### check if target exists
if ssh ${ssh_connect} "[ ! -d '${target}' ]"
then
  echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Target '${target}' does not exist, backup stopped." >> "${logfile}"

  # Remove lockfile
  rm -f "${lockfile}"

  exit 66 # cannot open input
fi



### Mount the TC volume on the Filesystem
# if mountpoint doesn't exists, we create it
[ -d "$tc_mount_point" ] || mkdir "$tc_mount_point"

# mount the network disc
/sbin/mount_afp "afp://${tc_user}:${tc_pw}@${tc_name}/${tc_share}" "${tc_mount_point}"

# wait for the network disk to be actually mounted
sleep 30

### Make the actual backup of the backup

# check folder for rsync logs
if [ ! -d "${filesPath}"rsync_logs ]
then
    mkdir "${filesPath}"rsync_logs
fi

  echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Rsync started." >> "${logfile}"

/usr/local/bin/rsync3 \
	-e "ssh -p $ssh_port" \
	--bwlimit=75 \
	--archive \
	--compress \
	--human-readable \
	--delete \
	"${tc_mount_point}${tc_file_name}" \
	"${ssh_user}@${ssh_server}:'${target}latest'" | tee -a "${filesPath}"rsync_logs/`date '+%Y-%m-%d_%Hh%Mm%S '

  echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Rsync finished." >> "${logfile}"



### Create "history" folder if it doesn't exists
if ssh ${ssh_connect} "[ ! -d '${target}history/' ]"
then
  ssh ${ssh_connect} "mkdir '${target}history'"
fi


### archive current backup
ssh ${ssh_connect} "cp -al '${target}latest' '${target}history/${date}'"

### Remove backups older than specified days
ssh ${ssh_connect} "$target/historyClean.sh"  # this file have to be created on the backup's destination. It is detailed at the end.

### Unmount the TC Volume
/sbin/umount "${tc_mount_point}"

echo `date '+%Y/%m/%d %H:%M:%S '` "[${mypid}] Remote backup successfully finished ! " >> "${logfile}"
# Remove lockfile, this must always be done at the latest moment possible to avoid conflicting processes.
rm -f "${lockfile}"

Et voilà le script historyCleaning, qui doit être mis directement sur la machine (Unix-like) qui contient les sauvegardes du backup Time Machine (par exemple un NAS Synology).

## VARS
target="/path/to/folder/"  # path to the backup's backup. Must match the one in the main script and contain the trailing slash
tc_file_name="iMac de User.sparsebundle"  # must match the one in the main script
daystokeep=200
## END OF VARS

## We search for backups older than daystokeep ; modification time is only on the hostname.sparsebundle folder, so we search it and then we truncate the path
find "$target"history/*/* -maxdepth 0 -type d -mtime +$daystokeep | sed "s#/$tc_file_name##" > $target/dirsToRemove.txt


## We delete each folder
for j in `cat "$target"dirsToRemove.txt`
do
	# it is advised to check if everything is ok
	echo $j
	# if ok, uncomment this line
	#rm -R $j
done

20 Apr 2014, 00:00

Boucle pour appliquer un script à tous les utilisateurs d'un domaine

Si l’on souhaite appliquer un script à tous les utilisateurs d’un domaine, il faut commencer par générer la liste de tous ces utilisateurs. Ceci peut se faire via la commande powershell

dsquery user -o samid -limit 250 > C:\path\to\domainUsers.txt

qui va lister tous les utilisateurs du domaine, sous la forme SAM ID (nom raccourci), entourés de guillemets. L’otion -limit est facultative, mais par défaut dsquery ne liste que les 100 premières entrées (soit -limit 100).

Puis on éxecute le script suivant

@echo off

REM on parcourt le fichier domainUsers.txt et on passe chaque ligne en argument
for /f "delims=" %%i in ('type C:\path\to\domainUsers.txt') do (C:\path\to\myScript.bat %%i)

Il faudra penser, dans le script, lorsque l’on souhaite récupérer le paramètre, à utiliser %~1 et non %1, ce qui permet de prendre la valeur sans les guillemets.

20 Apr 2014, 00:00

Création d'un répertoire qui contiendra des dossiers privés d'utilisateurs d'un poste ou domaine

Le but de la manipulation est que des utilisateurs désignés d’un poste ou d’un domaine aient chacun un dossier qui leur est privé (accessible uniquement à eux-seuls, en dehors bien sur des administrateurs). Ces dossiers seront également accessibles par le réseau, avec les mêmes limitations. Ces dossiers seront tous situés dans un même dossier racine, qui ne sera même pas navigable par de simples utilisateurs pour éviter qu’ils ne voient les noms des autres utilisateurs ou encore ceux qui ont un dossier personnel.

Commencer par créer le dossier partagé en question. Dans mon exemple ce sera "C:\Dossiers Perso\". Editer les permissions, désactiver l’héritage et conserver les autorisations en tant qu’autorisations explicites. Puis supprimer toutes les permissions relatives aux Utilisateurs, Utilsateurs authentifiés ou Utilisateurs du domaine (ne laisser que des droits aux Administrateurs, en somme).

Aller dans l’onglet de partage du dossier, aller dans le partage avancé, partager le dossier avec le nom que vous souhaitez, et dans les autorisations, donner le controle total à tout le monde. Le faire dans l’onglet de partage simple donnera les mêmes autorisations ACL sur le dossier (ce que nous ne voulons pas), mais dans l’onglet avancé non. Le partage est donc en lecture/écriture à tout le monde, mais en réalité, les ACL du dossier refuseront l’accès.

Puis exécuter le script suivant, en prenant soin de modifier les chemins : (NOTE : il est conseillé de créer un document vierge, de l’enregistrer au format CP850 (ou OEM850 sous Notepad++) puis d’y coller le contenu ; ceci reglera les problèmes d’accès, notamment pour Invité) @echo off REM on supprime l’affichage des commandes

REM on définit le chemin du dossier racine
REM Ne pas mettre de guillemets meme s'il y'a des espaces
REM ils sont ajoutés dans le suite du script. Ne pas mettre l'antislash final
set privateFolderPath=F:\Dossiers Perso

REM Si il y a un argument à la commande on le récupère (sans guillemets, d'ou le %~1) au lieu de %1, sinon on le demande
if not "%~1"=="" (set user=%~1) else (set /p user="Nom de l'utilisateur dont il faut creer le dossier perso ? ")

REM on zappe l'utilisateur invité
REM le nom bizarre vient de la différence d'encodage : CP850 par défaut pour le batch
if %user% == Invité (
	echo On zappe l'utilisateur Invité
	goto :eof
)

REM on teste l'existence de l'utilisateur avec des espaces autour
REM pour être sûr que ce n'est pas juste un bout du nom qui a été trouvé
REM rajouter le commutateur /domain après Net User pour vérifier sur tout le domaine
net user | findstr /i /C:" %user% "
if errorlevel 1 (
	REM s'il est en début de ligne, il n'y a pas d'espace devant. On vérifie
	net user | findstr /i /B /C:"%user% " > NUL
	if errorlevel 1 (
	    echo Cet utilisateur n'existe pas
	    goto :eof
	)
)

REM S'il n'y a ni dossier ni fichier sur la destination
if not exist "%privateFolderPath%\%user%" (
	REM on crée le dossier
	mkdir "%privateFolderPath%\%user%"
) else (
	REM si il n'y a pas de fichier "." dedans, c'est que c'est un fichier
	if not exist "%privateFolderPath%\%user%\*.*" (
	    echo Attention, "%privateFolderPath%\%user%" est un fichier !
	    pause
	    goto :eof
	)
)

REM On met l'utilisateur en propriétaire et on lui donne le controle total
REM l'utilisation de (OI) et (CI) équivaut à choisir en graphique
REM que les droits s'appliquent à "ce dossier, les sous-dossiers et les fichiers"
icacls "%privateFolderPath%\%user%" /setowner %user% /Q /T
icacls "%privateFolderPath%\%user%" /grant %user%:(OI)F /Q
icacls "%privateFolderPath%\%user%" /grant %user%:(CI)F /Q

Et voilà ! Le dossier de l’utilisateur est créé, il en est propriétaire, et il a (au même titre que les Administrateurs, par l’héritage) le contrôle total dessus. Et aucun utilisateur sans privilège ne peut naviguer son dossier (ni même le dossier "C:\Dossiers Perso" directement). Il peut y accéder en allant directement à "C:\Dossiers Perso\user" ou encore à \\IP_OU_NOM_SERVEUR\Dossiers Perso\user .

Si on souhaite appliquer ce script à tous les utilisateurs d’un domaine, se référer à ce post.

20 Apr 2014, 00:00

Partage réseau propre à chaque utilisateur avec montage automatique sous Server 2012

Le but de la manoeuvre est de monter automatiquement, au démarrage d’une session, un lecteur réseau propre à l’utilisateur actuel. Dans le contexte, cet article fait suite à celui permettant de créer un dossier personnel privé aux utilisateurs d’un domaine.

Je pars du principe que chaque utilisateur a son dossier privé, créé sous le partage \\IP_SERVEUR\Perso$\%username%
Ce post est (très) inspiré de ce post.

Créer, sur un dossier de votre choix, le script suivant avec l’extension .vbs (après l’avoir adapté à vos besoins) : Option Explicit

Dim objNetwork, WshNetworkName
Set objNetwork = CreateObject("WScript.Network")
Set WSHNetworkName = CreateObject("Shell.Application" )

Dim strUser, strHomeFolder, strHomeUserPath, strHomeUserDriveLetter
strHomeUserPath = "\\IP_NOM_SERVEUR\Perso$\"
strHomeUserDriveLetter = "Q:"

'récup du login
strUser = objNetwork.UserName
'chemin réseau complet du répertoire perso de l'utilisateur
strHomeFolder = strHomeUserPath & strUser

Dim CheckDrive, AlreadyConnected, intDrive
Set CheckDrive = objNetwork.EnumNetworkDrives()
On Error Resume Next
AlreadyConnected = False
For intDrive = 0 To CheckDrive.Count - 1

'Si un lecteur réseau est déjà mappé sur la lettre que l'on souhaite utiliser
	If CheckDrive.Item(intDrive) = strHomeUserDriveLetter Then AlreadyConnected = True
	If AlreadyConnected = True then
		objNetwork.RemoveNetworkDrive strHomeUserDriveLetter, True, True
		'objNetwork.RemoveNetworkDrive , True, True
		End if
	Next
	objNetwork.MapNetworkDrive strHomeUserDriveLetter, strHomeFolder
	WshNetworkName.NameSpace(strHomeUserDriveLetter).Self.Name = "Dossier Perso"
	WScript.Quit

Aller dans les stratégies de groupe (gpedit.msc pour le poste local, gpmc.msc pour les stratégies d’un domaine), aller sous Configuration Utilisateur |->Stratégies |->Paramètres Windows |->Scripts Cliquer sur Ajouter. Dans la boite de dialogue, cliquer sur “Afficher les fichiers”, ce qui nous amène directement à l’emplacement partagé prévu pour les scripts d’ouverture de session, qui ressemble à \\domain.com\SYSVOL\Petri.local\Policies\{E4A62379-8423-4654-8DB6-01FB8F58582D}\User\Scripts\Logon

Bien que nous puissions utiliser n’importe quel répertoire partagé, celui-ci est prévu pour, et le chemin réseau sera repris automatiquement par tous les clients. Coller le script ci-dessus sous n’importe quel nom dans ce répertoire, avec l’extension .vbs, par exemple mountPersonalFolder.vbs . Puis dans la boite de dialogue précédente, cliquer sur “Ajouter” et sélectionner le fichier.

Et voilà. Il sera automatiquement transmis chez les clients lorsque ceux-ci actualiseront leurs GPO.

14 Apr 2014, 00:00

Serveur OpenVPN en monde ponté (bridged) sous Debian Wheezy

Nous allons voir ici la création d’un serveur OpenVpn en mode ponté, c’est-à-dire qu’à chaque client du VPN sera attribué une adresse du réseau local côté serveur. C’est le routeur en charge du DHCP côté serveur qui distribuera les adresses aux clients VPN. La carte réseau physique (eth0) et la carte réseau virtuelle (tap0) seront donc bridgées ensemble sous l’interface br0. Nous allons aussi faire en sorte de gérer la révocation des certificats. La base est une installation sans graphique de Debian Wheezy.

Ce tuto est en très grande partie de celui de Mattotop sur le forum debian-fr.org. J’ai fait quelques petites modifications, mais je ne serai certainement pas arrivé à grand-chose sans lui.

Comme le paquet openssl est requis, et que tout le monde parle de Heartbleed en ce moment, on en profite pour vérifier que’on a bien la ligne deb http://security.debian.org/ wheezy/updates main contrib non-free dans notre sources.list :)

Commencer par installer les paquets nécessaires : aptitude install bridge-utils openvpn openssl rcconf

On se positionne dans le répertoire de configuration d’OpenVPN : cd /etc/openvpn

On y copie le dossier easy-rsa contenant tous les scripts de gestion du serveur et des clients :

cp -R /usr/share/doc/openvpn/examples/easy-rsa/2.0/ ./easy-rsa

(note : sous Jessie, il faut installer le paquet easy-rsa, et la conf se trouve directement à /usr/share/easy-rsa)

On rentre dans le dossier easy-rsa :

cd easy-rsa

Puis on édite le fichier vars, qui contient les valeurs communes pour la génération des certificats. Ce sont principalement les informations des dernières lignes à adapter selon nos besoins :

nano ./vars

Puis on “source” ce fichier, pour exporter toutes les valeurs dans nos variables d’environnement. Il faudra faire cette opération chaque fois que nous voudrons agir sur les certificats, par exemple pour générer de nouveaux certificats ou en révoquer.

. ./vars

Le script nous avertir que si on lance la commande ./clean-all, il va (ré)initialiser le répertoire keys, qui contiendra toutes nos clés. Ça tombe bien, c’est une install neuve, nous souhaitons le faire :

./clean-all

Nous préparaons ensuite les clés et paramètres Diffie-Hellman :

./build-dh
./build-ca
./build-key-server monServeurVpn

Sur la phase de création de la clé du serveur, tout comme pour la phase de création des certificats des clients, il n’est pas obligatoire de mettre un mot de passe. Il faut par contre que chaque CommonName soit unique, et il faut valider les 2 demandes de signature à la fin, en tapant “y”.

Nous allons générer puis révoquer un kit quelconque, ce qui permettra d’initialiser le fichier crl.pem. Ce fichier est indispensable pour que le serveur vérifie la liste des certificats révoqués. Sans ce dernier, un certificat révoqué permettra quand même de se connecter sans souci.

./build-key dummy
./revoke-full dummy

Nous avons maintenant le fichier ./keys/crl.pem qui est initialisé. Note : si nous souhaitons voir le contenu de ce fichier, nous puvons lancer la commande suivante :

openssl crl -text -noout -in keys/crl.pem

Nous créons maintenant un kit pour notre premier client, que l’on conservera :

./build-key client1

Nous passons ensuite à la configuration du serveur. le fichier est à mettre dans le répertoire /etc/openvpn pour être lancé par le service openvpn.

nano /etc/openvpn/monServeurVpn.conf

On y colle ceci :

port 1194
proto udp
dev tap0
ca		/etc/openvpn/easy-rsa/keys/ca.crt
cert	/etc/openvpn/easy-rsa/keys/monServeurVpn.crt
key		/etc/openvpn/easy-rsa/keys/monServeurVpn.key  # This file should be kept secret
dh		/etc/openvpn/easy-rsa/keys/dh1024.pem
server-bridge
keepalive 10 120
comp-lzo
persist-key
persist-tun
status 	/etc/openvpn/openvpn-status.log
#log-append	/etc/openvpn/openvpn.log
verb 3
crl-verify /etc/openvpn/easy-rsa/keys/crl.pem

(ce fichier est épuré au maximum ; vous pouvez récupérer ma version commentée et vous pouvez bien sûr lire les commentaires de l’exemple fourni par Debian ici : /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz )

Le fait que la ligne log-append soit commentée est volontaire : ainsi, nous avons directement la sortie affichée sur le terminal. A ce stade, nous pouvons normalement lancer le serveur.

cd /etc/openvpn
openvpn ./monServeurVpn.conf

doit démarrer OpenVpn et finir sur le message “Initialization Sequence Completed”. Il n’est pas fonctionnel pour autant, car nous n’avons pas configuré le réseau et le pont. Coupons le serveur qu’on vient de lancer avec Ctrl-C.

Il faut déjà désactiver le lancement du service openvpn au démarrage de la machine, car le réseau devra être complètement initialisé auparavant, et le lancement se fera via les scripts d’interface. Passer par la commande

rcconf

et décocher openvpn.

On édite ensuite le fichier /etc/network/interfaces, dans lequel on définit le bridge

cp /etc/network/interfaces /etc/network/interfaces.bak
nano /etc/network/interfaces

qui devra contenir ceci :

auto lo
	iface lo inet loopback

auto br0
	iface br0 inet manual
	bridge-ports eth0
	post-up /etc/openvpn/scripts/ovup && service openvpn start
	pre-down service openvpn stop
	post-down /etc/openvpn/scripts/ovdown

On choisit l’option “manual” car lorsque l’interface se lance, on ne va pas la configurer tout de suite. Ce sera fait lors des scripts dans le post-up.

Le but des scripts mentionnés ci-dessus est de déclencher la configuration de tap0 et le lancement du serveur lors de la mise en route de l’interface br0. Créons maintenant les scripts en question :

mkdir /etc/openvpn/scripts
cd /etc/openvpn/scripts
nano ovup

qui contiendra :

#!/bin/sh
openvpn --mktun --dev tap0
brctl addif br0 tap0
ifconfig eth0 promisc up
ifconfig tap0 promisc up
ifconfig br0 hw ether 1c:6f:65:ff:ff:ff  ## si on veut forcer le pont à avoir une adresse mac précise. Normalement elle prend celle de l'interface physique, mais il m'est arrivé qu'elle prenne celle de l'interface tap0, ce qui perturbe mon dhcp basé sur des baux fixes
ifconfig br0 192.168.0.1 netmask 255.255.255.0 broadcast 192.168.0.255

Ce script crée le device tap0, l’ajoute au pont br0 (qui contient déjà eth0), passe eth0 et tap0 en mode Promisc, nécessaire pour que le bridge fonctionne, et configure l’IP de br0. Encore une fois, si on souhaite être en dhcp avec bail fixe, on peut remplace la dernière ligne par dhclient -v br0

nano ovdown

qui contiendra

#!/bin/sh
openvpn --rmtun --dev tap0

On rend ces scripts executables :

chmod +x /etc/openvpn/scripts/ov*

Et normalement, un

service networking restart

devrait tout faire : démarrer le bridge, le configurer, et lancer le vpn. Si la commande se finit par “done.”, c’est que toutes les étapes se sont bien déroulées, et le serveur est prêt à l’emploi :)

Voici des exemples de fichier de conf client fonctionnels, après avoir adapté l’IP du serveur et les chemins du kit de connexion, pour Linux et pour Windows

12 Apr 2014, 00:00

Autoriser le Bureau à distance sous Windows Serveur 2012

Avant toute chose, ceci ne traite pas du tout de la configuration du gestionnaire de licence des services Bureau à distance de windows server, ni de leur aspect légal, mais purement de l’aspect technique.

Si l’on souhaite autoriser un utilisateur non-administrateur à se connecter au Bureau à distance sur un Windows Server 2012, il faut procéder à 3 étapes complémentaires :

  • Tout d’abord, vérifier dans les Paramètres système avancés (clic droit sur le Poste de travail, puis Propriétés, puis sélectionner Paramètres système avancés sur le côté), dans l’onglet Utilisation à distance, que les connections à distances sont autorisées sur cet ordinateur. Si ce n’est pas le cas, les activer.

  • Cliquer sur le bouton Sélectionner des utilisateurs, et ajouter le/les utilisateurs/groupes qui auront le droit de se connecter. Ceci a pour effet de placer l’utilisateur/groupe dans le groupe “Utilisateurs du Bureau à distance”. Ceci est visible dans le profil concerné, dans la gestion des utilisateurs et ordinateurs AD. Utiliser le menu “Séléctionnez des utilisateurs” et le composant Utilisateurs et Ordinateurs Active Directory revient exactement au même. Tout ajout/suppression dans l’un sera effectif dans l’autre.

  • Ces personnes désormais ont le droit d’utiliser le protocole RDP, mais n’ont pas le droit d’ouvrir une session sur la machine pour autant. Pour remédier à ceci, il faut aller dans les stratégies locales du serveur, avec la commande gpedit.msc

Puis aller dans : Paramètres ordinateur |-Paramètres Windows |-Paramètres de sécurité |-Stratégies locales |-Attribution de droits utilisateurs

Et remplir la valeur “Autoriser l’ouverture de session par les services Bureau à distance” en conséquence.

Attention. Si on modifie ce paramètres dans les GPO du domaine entier, il sera appliqué à toutes les machines, et surtout le paramètre local par défaut (Administrateurs) sera remplacé par le nouveau paramètre de domaine. Il faut penser à rajouter le groupe Administrateurs si on souhaite qu’ils conservent un accès à distance.

10 Apr 2014, 00:00

Désactiver redirection des imprimantes par défaut du client lors d'une connexion RDP

Sous Windows 7 Pro ou Windows Server 2008 (et probablement Server 2003), lorsqu’un client se connecte en RDP, ses imprimantes locales sont redirigées sur sa session sur le serveur, et celle par défaut est mise par défaut sur la session distante.

Pour désactiver ces 2 comportements qui peuvent être gênants, il faut utiliser l’éditeur de stratégies de groupe (sur le serveur).

Lancer l’éditeur avec la commande

gpedit.msc

Puis aller dans

Modèles d'administration
|-Composants Windows
  |-Services Terminal Server
    |- Redirection de données client/serveur
      |- Ne pas autoriser la redirection de l'imprimante client  -> Activé

10 Apr 2014, 00:00

Elever automatiquement tous les utilisateurs d'un domaine au niveau d'administrateurs de leurs machines

Il peut être souhaitable, pour différentes raisons, comme par exemple satisfaire la demande d’un client, que les utilisateurs simples d’un domaine, soient admins sur leurs machines, pour la gérer comme ils l’entendent, au niveau de l’installation de logiciels et autres. Ceci se paramètre via les Groupes Restreints.

Sous Windows Server 2012, il faut executer (sur le controleur de domaine)

gpmc.msc

puis descendre dans le domaine à gérer, aller dans les paramètres de la Default Domain Policy, faire un clic-droit puis Modifier, pour ouvrir l’Editeur de gestion des stratégies de groupes.

Puis on va dans

Config ordinateur
|-Stratégies
  |-Paramètres Windows
    |-Paramètres de sécurité
      |-Groupes restreints

On fait un clic-droit -> ajouter un groupe, puis on spécifie le Groupe de sécurité dont les utilisateurs seront élevés en tant qu’Admin locaux. Par exemple Utilisateurs du domaine pour tout le monde, ou encore un groupe Admin Locaux que l’on aura pris le soin de créer auparavant.

Puis dans la fenètre des proprietés de ce groupe restreint qui apparaît, dans le cadre “ce groupe est membre de”, on fait Ajouter, puis on sélectionne le groupe Administrateurs.

On force l’application de la GPO sur un client avec la commande

gpupdate /force

puis on déconnect et reconnecte une session sur un utilisateur faisant partie du groupe sus-spécifié, et il sera désormais admin de sa propre machine.

Source : honteusement pompé (une fois de plus) de http://www.frickelsoft.net/blog/?p=13