Noch ein Backup Skript für Powershell

Started by wasmitedv, August 25, 2022, 09:46:52 AM

Previous topic - Next topic
August 25, 2022, 09:46:52 AM Last Edit: August 25, 2022, 10:04:37 AM by wasmitedv
Servus beinand',

beim Konsolidieren unserer Backups haben wir für unsere OPNsense Hosts vom Nextcloud Plugin auf os-api-backup umgestellt.

Ich darf mit euch mein Powershell Skript teilen, vielleicht hat jemand Gebrauch. Wer Verbesserungen weiß, bitte gerne Nachricht an mich.

--- schnipp ---

$OpnSenseCredentials = @{
    'os1.irgendwo.local' = @{
        UrlPort = '443'
        ApiKey = 'Viele Zeichen und Buchstaben'
        ApiSecret = 'Viele Zeichen und Buchstaben'
    }
'os2.irgendwo.local' = @{
        UrlPort = '443'
        ApiKey = 'Viele Zeichen und Buchstaben'
        ApiSecret = 'Viele Zeichen und Buchstaben'
    }
'os3.irgendwo.local' = @{
        UrlPort = '443'
        ApiKey = 'Viele Zeichen und Buchstaben'
        ApiSecret = 'Viele Zeichen und Buchstaben'
    }
'os4.irgendwo.local' = @{
        UrlPort = '443344'
        ApiKey = 'Viele Zeichen und Buchstaben'
        ApiSecret = 'Viele Zeichen und Buchstaben'
    }
'os5.irgendwo.local' = @{
        UrlPort = '443'
        ApiKey = 'Viele Zeichen und Buchstaben'
        ApiSecret = 'Viele Zeichen und Buchstaben'
    }
}

# Das Ziel der Backups
$BackupDestination = "\\Backup_Server\Backup_Dir"

# E-Mail Sachen
$EmailSmtpServer = "mailer.irgendwo.local"
$EmailEmpfaenger = "admin@irgendwo.com"
$EmailSender = "dersender@irgendwo.com"
$EmailBetreff = "Backup-Script fuer OPNsense: "
$EmailText = "Folgendes ist aufgetreten:"

# Wie viele Backups pro Host behalten wir?
$AnzahlBackupsBehalten = 10

# Eine E-MAil-Versendefunktion
function SendMyMail {
    Send-MailMessage -From $EmailSender -to $EmailEmpfaenger -Subject $EmailBetreff -Body $EmailText -SmtpServer $EmailSmtpServer
}

# Wir wollen in das $BackupDestination wechseln. Wenn nicht E-Mail und raus...
try {
    Set-Location -Path $BackupDestination -ErrorAction Stop
}
catch {
    $EmailBetreff = $EmailBetreff + "Fehler, kein Backup erstellt"
    $EmailText = @"
Das Backup-Script konnte nicht in das Arbeitsverzeichnis wechseln.
"@
    SendMyMail
    exit 1
}


foreach ( $OpnSenseHost in $OpnSenseCredentials.Keys) {
    $BackupDestinationHostDir = "$BackupDestination" + "\" + "$OpnSenseHost"
    if ( -not (test-path -Path "$BackupDestinationHostDir" )) {
        try {
            New-Item -Path "$BackupDestinationHostDir" -ItemType Directory -ErrorAction Stop
        }
        catch {
            $EmailBetreff = $EmailBetreff + "Fehler, kein Backup erstellt"
            $EmailText = @"
Das Backup-Script konnte kein Unterverzeichnis erstellen. Das Backup File wurde NICHT
von \"$OpnSenseHost\" heruntergeladen!
"@
            SendMyMail
            continue         
        }
    }
   


    try {
        Set-Location -Path $BackupDestinationHostDir -ErrorAction Stop
    }
    catch {
        $EmailBetreff = $EmailBetreff + "Fehler, kein Backup erstellt"
        $EmailText = @"
Das Backup-Script konnte nicht in das Arbeitsverzeichnis wechseln. Das Backup File wurde NICHT
von \"$OpnSenseHost\" heruntergeladen!
"@
        SendMyMail
        continue         
    }

    $ApiCredentialPair = $OpnSenseCredentials[$OpnSenseHost]['ApiKey'] + ":" + $OpnSenseCredentials[$OpnSenseHost]['ApiSecret']
    $Bytes = [System.Text.Encoding]::ASCII.GetBytes($ApiCredentialPair)
    $Base64Coded = [System.Convert]::ToBase64String($Bytes)
    $BasicAuthValue = "Basic $Base64Coded"

    $Headers = @{ Authorization = $BasicAuthValue }

    $Uri = "https://" + $OpnSenseHost + ":" + $($OpnSenseCredentials[$OpnSenseHost]['UrlPort']) + "/api/backup/backup/download"

    try {
        invoke-webrequest -uri $Uri -Headers $Headers -OutFile config.xml
    }
    catch {
        $EmailBetreff = $EmailBetreff + "Fehler, kein Backup erstellt"
        $EmailText = @"
Fehler beim web-request. Das Backup File wurde NICHT
von \"$OpnSenseHost\" heruntergeladen!
"@
        SendMyMail
        continue     
    }

    Rename-Item config.xml backup_$(get-date -Format yyyyMMddhhmmss).xml

    $AnzahlBackupDateien = $(Get-ChildItem -Path backup_??????????????.xml | measure-object).count
    while ($AnzahlBackupDateien -gt $AnzahlBackupsBehalten) {
        Get-ChildItem -Path backup_??????????????.xml | Sort-Object | Select-Object -First 1 | Remove-Item
        $AnzahlBackupDateien = $(Get-ChildItem -Path backup_??????????????.xml | measure-object).count
    }
}   


--- schnapp ---

Das Skript läuft über eine Aufgabenplanung regelmäßig.


Schöne Grüße

Alex

Ihr benutzt das auf eigenes Risiko!


Bei mir funktioniert das Script leider nicht...

... erst wenn ich folgende Zeilen an den Anfang setze, funktioniert es.

add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
    public bool CheckValidationResult(
        ServicePoint srvPoint, X509Certificate certificate,
        WebRequest request, int certificateProblem) {
        return true;
    }
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy


Ich habe wenig Erfahrung mit Powershell und bin mir nicht sicher, ob Du dies einfach vorausgesetzt hast.

Der Code stammt nicht von mir, ich habe diesen in einem anderen Script gefunden.

Quote from: wasmitedv on August 25, 2022, 09:46:52 AM
beim Konsolidieren unserer Backups haben wir für unsere OPNsense Hosts vom Nextcloud Plugin auf os-api-backup umgestellt.
Rein Interessehalber, wie nutzt du das Script, sicherst du die OPNSense von einem Windows-Host aus, anders wüßte ich nicht, warum man PowerShell nutzen müsste.

Ich mache meine Backups ( OPNSense Konfig und AdGuard-Konfig ) direkt per Script von der OPNSense aus auf eine NAS.


September 24, 2022, 11:47:58 AM #3 Last Edit: September 24, 2022, 11:51:31 AM by Adm1n-1337
Noch gar nicht.

Ich habe das Script hier zufällig gesehen, hatte nichts zu tun und wollte es einfach einmal testen.

Da ich in Zukunft aber ~20 Installationen betreuen werde, fand ich die Idee interessant, die Backups von einer zentralen Stelle abzurufen.

Quote from: Adm1n-1337 on September 24, 2022, 11:47:58 AM
Da ich in Zukunft aber ~20 Installationen betreuen werde, fand ich die Idee interessant, die Backups von einer zentralen Stelle abzurufen.
Jau macht Sinn.

Kurze Beschreibung wie mein Weg aussieht ( Privat-Installation zuhause ):
- auf der OPNSense habe ich einen Backup-Ordner angelegt und "/mnt"
- ein cronjob synchronisiert alle 4 h. die Config-Dateinen von /conf/backup/  dort hin per rsync
- zudem wird per rsync der Backup-Ordner auf meine NAS per rsync synconisiert ( Login mit Public-key )

Durch die Standart-Einstellungen in OPNSense, wieviele Config-Files aufbewahrt werden, räumt sich das ganze auch selber auf, da rsync ja gelöschte Files in der Quelle auch im Ziel löscht, wenn eingestellt.

Das Betriebssystem selber sicher ich nicht, das ist per USB-Stick schnell neu aufgesetzt und ein fertiger Stick liegt im Schrank bereit.

Ich mache mein Backup zentral auf meinem Unraid Server.

Folgendes Skript holt das Backup wöchentlich via dem os-api-backup Plugin ab.
Zusätzlich werden nur die letzten 5 Backups behalten, alle anderen werden gelöscht.

#!/bin/bash
KEY="MEINKEY"
SECRET="MEINSECRET"
HOST="192.168.200.1"
PATHCONFIG="/mnt/user/backup/opnsensebackup"
DATE="$(date +%Y%m%d_%H%M%S)"
BACKUP_TO_KEEP="5"

# download the config file from OPNsense
curl -s -u ${KEY}:${SECRET} http://${HOST}/api/backup/backup/download -o ${PATHCONFIG}/opnsense-config-${DATE}.xml
if [ $? -eq 0 ]; then
  /usr/local/emhttp/webGui/scripts/notify -i normal -s "Backup OPNsense done." -d "Downloading the xml config file from OPNsense successfully finished."
else
  /usr/local/emhttp/webGui/scripts/notify -i alert -s "Backup OPNsense failed!" -d "Downloading the xml config file from OPNsense failed!"
  exit 1
fi

# delete old backups
cd ${PATHCONFIG}
ls -1tr ${PATHCONFIG} | sort | head -n -${BACKUP_TO_KEEP} | xargs -d '\n' rm -f --