Le script ci-dessous permet de déployer un agent sur une station Windows. La Communication entre l’agent et le serveur Zabbix est sécurisé au moyen d’une PSK généré dynamiquement au sein du script. L’agent est automatiquement enregistré sur Zabbix et sa configuration est mise à jour vers PSK après son inscription en utilisant l’API native de Zabbix.
Le script va chercher sur un serveur distant l’ensemble des fichiers utile au déploiement d’un agent Zabbix sous Windows, puis les copie dans C:\zabbix.
Dans le dossier C:\zabbix on va retrouver également la lib openssl pour générer les PSK, il est requis d’ajouter les deux DDL lors de la copie.
En vert les éléments indispensables pour openssl, le reste sont les composants classiques de l’agent Zabbix.
En fin de Script on modifie les ACL NTFS afin de sécuriser l’accès au répertoire contenant la PSK ainsi que l’agent Zabbix.
#$service = Get-WmiObject -Class Win32_Service -Filter "Name='Zabbix Agent'"
#$service.delete()
set-executionpolicy remotesigned
Import-Module NTFSSecurity
$Source = "\\srv-maindc\deploiement$\zabbix"
$Target = "C:"
$PersonnelPathRoot = "C:\zabbix"
#test afin de savoir si le service de l'agent zabbix est deja installé
If (get-service -Name "Zabbix Agent" -ErrorAction SilentlyContinue | Where-Object -Property Status -eq "Started")
{
Exit
}
Elseif (get-service -Name "Zabbix Agent" -ErrorAction SilentlyContinue | Where-Object -Property Status -eq "Stopped")
{
Start-Service "Zabbix Agent"
Exit
} else{
echo "Agent Zabbix non présent début d'installation"
Copy-Item -Recurse -Path $Source -Destination $Target -ErrorAction SilentlyContinue
Start-Sleep -s 2
if ( Test-Path "C:\zabbix" ) {
#Installation Zabbix en service
C:\zabbix\zabbix_agentd.exe --config C:\zabbix\zabbix_agentd.conf --install 2>&1 | out-null
Start-Sleep -s 2
#Je démarre le service pour que mon host s'enregistre du Zabbix(actif)
C:\zabbix\zabbix_agentd.exe --config C:\zabbix\zabbix_agentd.conf --start 2>&1 | out-null
#je coupe le service pour modifier la configuration
Start-Sleep -s 2
C:\zabbix\zabbix_agentd.exe --config C:\zabbix\zabbix_agentd.conf --stop 2>&1 | out-null
#Génère la clef PSK de l'host avec son nom machine.psk
$mypsk = C:\zabbix\openssl.exe rand -hex 32
echo $mypsk > "C:\zabbix\$env:computername.txt"
#suppression du utf BOM
$orcFile = "C:\zabbix\$env:computername.txt"
(Get-Content $orcFile) |
Foreach-Object {$_ -replace "\xEF\xBB\xBF", ""} |
Set-Content $orcFile
#(Get-Content -path "C:\zabbix\$env:computername.txt") | Set-Content -Encoding UTF8 -Path "C:\zabbix\$env:computername.txt"
#(Get-Content "C:\zabbix\$env:computername.txt") | Out-FileUtf8NoBom "C:\zabbix\$env:computername.txt"
} else {
Write-Host "Fail Copy check sources"
Exit
}
}
#A cette instant, le service Zabbix est installé avec une configuration sans chiffrement
#On doit à présent modifier le fichier de configuration afin que celui-ci soit chiffré en PSK, puis update le serveur.
#Liste des modifications :
# #TLSConnect=psk -> TLSConnect=psk
# #TLSAccept=psk -> TLSAccept=psk
# #TLSPSKIdentity=PSK 001 -> TLSPSKIdentity=PSK 001
# #TLSPSKFile=/etc/zabbix/zabbix_agentd.psk -> TLSPSKFile=/etc/zabbix/zabbix_agentd.psk
#Pour modifier avec le script le fichier de configuration, je dois generer un nombre aleatoire pour lid psk
$CurrentRandom = Get-Random -minimum 1 -maximum 99999
$FinalePSKId = "PSK $CurrentRandom"
(Get-Content C:\zabbix\zabbix_agentd.conf).replace('#TLSConnect=psk', 'TLSConnect=psk') | Set-Content C:\zabbix\zabbix_agentd.conf
(Get-Content C:\zabbix\zabbix_agentd.conf).replace('#TLSAccept=psk', 'TLSAccept=psk') | Set-Content C:\zabbix\zabbix_agentd.conf
(Get-Content C:\zabbix\zabbix_agentd.conf).replace('#TLSPSKIdentity=PSK 002', "TLSPSKIdentity=$FinalePSKId") | Set-Content C:\zabbix\zabbix_agentd.conf
(Get-Content C:\zabbix\zabbix_agentd.conf).replace('#TLSPSKFile=', "TLSPSKFile=C:\zabbix\$env:computername.txt") | Set-Content C:\zabbix\zabbix_agentd.conf
#A ce stade, lhost a la configuration requise, je dois à present update la configuration de lhost dans le CMS
#Je vais donc récupérer l'ID de l'host nouvellement enregistré
#Pour cela je dois recupérer la liste des hosts sur Zabbix, puis je compare dans la boucle l'host courant
if(!$credential){
$credential = Get-Credential
}
$baseurl = 'http://mondomaine.laintimes.com'
$params = @{
body = @{
"jsonrpc"= "2.0"
"method"= "user.login"
"params"= @{
"user"= $credential.UserName
"password"= $credential.GetNetworkCredential().Password
}
"id"= 1
"auth"= $null
} | ConvertTo-Json
uri = "$baseurl/api_jsonrpc.php"
headers = @{"Content-Type" = "application/json"}
method = "Post"
}
$result = Invoke-WebRequest @params
$params.body = @{
"jsonrpc"= "2.0"
"method"= "host.get"
"params"= @{
output = "extend"
selectFunctions = "extend"
selectLastEvent = "extend"
selectGroups = "extend"
selectHosts = "extend"
}
auth = ($result.Content | ConvertFrom-Json).result
id = 2
} | ConvertTo-Json
$result = Invoke-WebRequest @params
$result = $result.Content | ConvertFrom-Json
ForEach ($cluster in $result.result) {
$CurrentName = $cluster.name
$CurrentHostId = $cluster.hostid
#$env:computername
IF ($CurrentName.Equals($env:computername)){
Write-Host "$env:computername match Id : "$CurrentHostId
$FinaleHostId = $CurrentHostId
$FinaleHostname = $env:computername
}
}
$CurrentPsk = Get-Content "C:\zabbix\$env:computername.txt" -First 1
#A ce stade $FinaleHostId et $FinaleHostname sont renseigné, je peux faire un update
Write-Host "On va Update lhost : $FinaleHostname avec comme id : $FinaleHostId"
Write-Host "PSK : $CurrentPsk"
$params = @{
body = @{
"jsonrpc"= "2.0"
"method"= "user.login"
"params"= @{
"user"= $credential.UserName
"password"= $credential.GetNetworkCredential().Password
}
"id"= 1
"auth"= $null
} | ConvertTo-Json
uri = "$baseurl/api_jsonrpc.php"
headers = @{"Content-Type" = "application/json"}
method = "Post"
}
$result = Invoke-WebRequest @params
$params.body = @{
"jsonrpc"= "2.0"
"method"= "host.update"
"params"= @{
hostid = "$FinaleHostId"
tls_connect = "2"
tls_accept = "2"
tls_psk_identity = "$FinalePSKId"
tls_psk = "$CurrentPsk"
}
auth = ($result.Content | ConvertFrom-Json).result
id = 2
} | ConvertTo-Json
$result = Invoke-WebRequest @params
$result = $result.Content | ConvertFrom-Json
#La configuration est achevé, je modifie les droits sur le dossier des sources afin d'en verouiller lacc
# Desactiver l'heritage tout en copiant les autorisations NTFS héritées
Get-Item "$PersonnelPathRoot" | Disable-NTFSAccessInheritance
# Ajout des autorisations NTFS pour admins de domaine et compte système
Add-NTFSAccess –Path "$PersonnelPathRoot" –Account "Admins du domaine" –AccessRights FullControl
Add-NTFSAccess –Path "$PersonnelPathRoot" –Account "Système" –AccessRights FullControl
# Passe Admins du domaine en proprietaire
Set-NTFSOwner -Path "$PersonnelPathRoot" -Account "Admins du domaine"
# Supprimer des autorisations NTFS
Remove-NTFSAccess –Path "$PersonnelPathRoot" –Account "Utilisateurs" -AccessRights FullControl
#Remove-NTFSAccess –Path "$PersonnelPathRoot" –Account "Administrateurs" -AccessRights FullControl
Remove-NTFSAccess –Path "$PersonnelPathRoot" –Account "Utilisateurs authentifiés" -AccessRights FullControl
C:\zabbix\zabbix_agentd.exe --config C:\zabbix\zabbix_agentd.conf --stop 2>&1 | out-null
Start-Sleep -s 2
C:\zabbix\zabbix_agentd.exe --config C:\zabbix\zabbix_agentd.conf --start 2>&1 | out-null