Diplom-Biologe | Senior IT-Consultant
|
SH |
Sascha Hess xenosystems.de - IT-Consulting & Data Management |
www.xenosystems.de |
|
|
Strategische Wissens-Roadmap 2026 |
|
|
SQL Server |
|
|
Backup & Sicherheitskonzepte |
|
|
Kein Datenverlust, kein unbefugter Zugriff — beides braucht ein Konzept |
WAS SIE IN DIESEM KIT ERHALTEN:
|
|
1 |
Backup-Strategie Full, Differential, Log — RTO/RPO-konform geplant |
|
|
2 |
Restore-Szenarien Point-in-Time, Einzeltabelle, Katastrophenfall — geübt |
|
|
3 |
Verschlüsselung & TDE Transparent Data Encryption — einrichten und betreiben |
|
|
4 |
Audit & Compliance Wer hat wann was gelesen oder geändert — lückenlos |
|
|
5 |
30-Tage-Sicherheitsplan Backup- und Sicherheitskonzept in einem Monat live |
HAFTUNGSAUSSCHLUSS
Alle Skripte, Konfigurationshinweise und Empfehlungen wurden sorgfältig erarbeitet. Der Autor übernimmt keinerlei Haftung für Datenverlust, fehlgeschlagene Restores, Sicherheitsvorfälle oder sonstige Schäden. Testen Sie alle Backup- und Restore-Prozeduren regelmäßig in einer Testumgebung — ein Backup das nie getestet wurde, ist kein Backup.
KEINE ERGEBNISGARANTIE
RTO/RPO-Angaben und Zeitschätzungen basieren auf Erfahrungswerten aus realen KMU-Umgebungen. Tatsächliche Werte hängen von Hardware, Netzwerk, Datenbankgröße und Transaktionsaufkommen ab.
VERSIONSHINWEIS
Die Inhalte beziehen sich auf SQL Server 2022 (16.x) und SQL Server 2025 (17.x), Stand März 2026. Kumulative Updates können Verhaltensweisen ändern.
URHEBERRECHT
Dieses Dokument ist für den persönlichen oder betriebsinternen Gebrauch des Käufers lizenziert. Weiterverkauf, Weitergabe und öffentliche Veröffentlichung sind ohne schriftliche Genehmigung nicht gestattet.
KEINE VERBINDUNG ZU MICROSOFT
Dieses Kit ist ein unabhängiges Werk. SQL Server ist eine eingetragene Marke der Microsoft Corporation.
Eine ausführliche Version dieses Haftungsausschlusses befindet sich am Ende dieses Dokuments.
01 Einleitung
Warum Backup und Sicherheit ein gemeinsames Konzept brauchen
02 Backup-Grundlagen
Recovery-Modelle, RTO/RPO, Backup-Typen verstehen
03 Backup-Strategie
Full, Differential, Log — optimal kombiniert
04 Restore-Szenarien
Point-in-Time, Einzelobjekt, Katastrophenfall
05 Verschlüsselung & TDE
Daten im Ruhezustand und auf dem Transport schützen
06 Authentifizierung & Zugriff
Login-Sicherheit, Least Privilege, Service Accounts
07 SQL Server Audit
Wer hat wann was — lückenlos protokolliert
08 Netzwerk & Härtung
Surface Area Reduction, Firewall, Verschlüsselung im Transit
09 Monitoring & Alerting
Backup-Überwachung, Fehlermeldungen, Security-Events
10 30-Tage-Sicherheitsplan
Backup- und Sicherheitskonzept produktiv in einem Monat
01
Backup und Datenbankssicherheit werden im Mittelstand meist getrennt behandelt — Backup als "läuft irgendwie", Sicherheit als "machen wir beim nächsten Audit". Beide Annahmen sind gefährlich, und beide Themen sind untrennbar miteinander verbunden.
Ein Backup schützt nicht vor einem Angreifer der Zugangsdaten kennt — und Zugriffskontrolle schützt nicht vor Hardwareausfall.
→ Ransomware verschlüsselt nicht nur Produktionsdaten sondern auch lokale Backups — wenn die Backup-Strategie keine offline oder cloud-isolierten Kopien vorsieht.
→ Ein kompromittiertes sa-Konto kann alle Backups löschen, alle Audit-Logs leeren und alle Daten exfiltrieren — bevor irgendjemand es bemerkt.
→ NIS-2 und DSGVO verlangen nachweisbar funktionierende Wiederherstellungsprozesse und lückenlose Zugriffsprotokolle — nicht nur das Vorhandensein von Backups.
→ In 80 % der Fälle in denen Backups gebraucht werden, fehlt nicht die Datei — sondern die getestete und dokumentierte Restore-Prozedur.
Dieses Kit behandelt beides als integriertes Konzept: eine solide Backup-Strategie, die im Ernstfall funktioniert — und eine Sicherheitskonfiguration, die Angreifern keinen leichten Weg lässt.
|
|
WAS SIE IN DIESEM KIT ERWARTEN DÜRFEN ■ Backup-Strategie — RTO/RPO-konforme Planung mit Full, Differential und Log Backups. ■ Restore-Playbook — Point-in-Time Restore, Einzelobjekt-Wiederherstellung, Katastrophenfall. ■ TDE & Verschlüsselung — Transparent Data Encryption einrichten und sicher betreiben. ■ Audit & Compliance — SQL Server Audit für DSGVO und NIS-2 konfigurieren. ■ 30-Tage-Plan — Backup- und Sicherheitskonzept vollständig und dokumentiert. |
|
|
ZIEL DIESES KITS Nach dem Lesen und Umsetzen dieses Kits haben Sie eine getestete Backup-Strategie, ein dokumentiertes Restore-Playbook, eine gehärtete SQL Server-Konfiguration und ein lückenloses Audit-Trail — revisionsicher und NIS-2-konform. |
02
Bevor die erste Backup-Strategie definiert wird, müssen drei grundlegende Konzepte verstanden sein: Recovery-Modell, RTO/RPO und Backup-Typen. Wer diese nicht kennt, plant am Bedarf vorbei.
|
SIMPLE RECOVERY MODEL: Log wird automatisch abgeschnitten nach Checkpoint. Kein Log-Backup möglich → kein Point-in-Time Restore. Nur Full + Differential Backup. → Für: Entwicklung, Testsysteme, nicht-kritische Daten → NICHT für: Produktive ERP-Datenbanken
FULL RECOVERY MODEL: Log wird aufbewahrt bis zum nächsten Log-Backup. Point-in-Time Restore bis auf die Minute möglich. Log wächst wenn Log-Backups vergessen werden! → Für: Alle produktiven Datenbanken
BULK-LOGGED RECOVERY: Wie FULL, aber Bulk-Operationen werden minimal geloggt. Schnellere Bulk-Loads bei fast gleichem Schutz. Point-in-Time während Bulk-Op eingeschränkt. → Für: ETL-Prozesse, Data Warehouses mit großen Loads
-- Recovery Model prüfen und setzen: SELECT name, recovery_model_desc FROM sys.databases ORDER BY name;
ALTER DATABASE IhreERP_DB SET RECOVERY FULL; |
|
RPO — Recovery Point Objective: "Wie viel Datenverlust ist akzeptabel?" Beispiel RPO = 1 Stunde → Log-Backups alle 60 Minuten Beispiel RPO = 15 Min. → Log-Backups alle 15 Minuten Beispiel RPO = 0 → Synchrone Spiegelung / Always On
RTO — Recovery Time Objective: "Wie lange darf die Wiederherstellung dauern?" Beispiel RTO = 4 Stunden → Full Backup muss in 4h restorbar sein Beispiel RTO = 1 Stunde → Full muss klein genug oder Differential reichen Beispiel RTO = 0 → Always On mit automatischem Failover
STRATEGIEABLEITUNG: RPO = 1h, RTO = 4h → Full wöchentlich + Differential täglich + Log stündlich RPO = 15min, RTO = 2h → Full täglich + Log alle 15 Min. + Backup auf NAS + Cloud RPO = 0, RTO = 0 → Always On Availability Group (Enterprise-Feature)
WICHTIG: RPO und RTO müssen vom Business definiert werden — nicht von der IT. "Was kostet 1 Stunde Datenverlust?" |
|
Backup-Typ |
Was wird gesichert |
Größe |
Abhängigkeit |
Restore-Kette |
|
Full Backup |
Gesamte Datenbank |
Groß |
Keine |
Basis jeder Kette |
|
Differential |
Alles seit letztem Full |
Mittel |
Letztes Full |
Full + dieses Diff |
|
Log Backup |
Transaktionslog seit letztem Log |
Klein |
Vorheriger Log |
Full + alle Logs |
|
Copy-Only |
Wie Full, unterbricht keine Kette |
Groß |
Keine |
Unabhängig |
|
File/Filegroup |
Nur bestimmte Dateigruppen |
Variabel |
Full der FG |
Komplex |
03
Eine gute Backup-Strategie balanciert drei Faktoren: Datenverlustrisiko (RPO), Wiederherstellungszeit (RTO) und Backup-Aufwand (Speicher, I/O, Zeit). Es gibt keine Universallösung — aber bewährte Muster.
|
STANDARD-STRATEGIE KMU-ERP (RPO 1h, RTO 4h):
SONNTAG 23:00 Full Backup (komprimiert) → lokaler NAS + Cloud TÄGLICH 23:00 Differential Backup → lokaler NAS STÜNDLICH Log Backup (Mo-Sa, ganztags) → lokaler NAS TÄGLICH 02:00 Log Backup Archivierung → Cloud (7 Tage Log)
AUFBEWAHRUNG: Full Backups: 4 Wochen (4 Generationen) Differential Backups: 1 Woche (7 Generationen) Log Backups: 7 Tage (kontinuierlich) Monatliches Full: 12 Monate (Jahresarchiv)
SPEICHERSCHÄTZUNG (Beispiel 100 GB Datenbank): Full komprimiert: ~20-30 GB Differential (tägl.): ~2-5 GB Log-Backup (stündl.): ~0.2-1 GB Gesamt pro Woche: ~50-70 GB |
|
-- Full Backup — Sonntag 23:00 EXECUTE dbo.DatabaseBackup @Databases = 'USER_DATABASES', @Directory = 'E:\Backup\Full', @BackupType = 'FULL', @Verify = 'Y', @Compress = 'Y', @CompressionAlgorithm = 'ZSTD', -- SQL Server 2025: bis 40% kleiner @CheckSum = 'Y', @LogToTable = 'Y', @CleanupTime = 672, -- 28 Tage in Stunden @CleanupMode = 'AFTER_BACKUP';
-- Differential Backup — täglich Mo-Sa 23:00 EXECUTE dbo.DatabaseBackup @Databases = 'USER_DATABASES', @Directory = 'E:\Backup\Diff', @BackupType = 'DIFF', @Verify = 'Y', @Compress = 'Y', @CompressionAlgorithm = 'ZSTD', @CheckSum = 'Y', @LogToTable = 'Y', @CleanupTime = 168; -- 7 Tage
-- Log Backup — stündlich EXECUTE dbo.DatabaseBackup @Databases = 'USER_DATABASES', @Directory = 'E:\Backup\Log', @BackupType = 'LOG', @Verify = 'Y', @Compress = 'Y', @CheckSum = 'Y', @LogToTable = 'Y', @CleanupTime = 168; -- 7 Tage |
|
-- RESTORE VERIFYONLY — prüft Backup-Integrität ohne tatsächlichen Restore -- Als SQL Agent Job täglich nach dem Backup laufen lassen
DECLARE @BackupFile NVARCHAR(500); DECLARE @Fehler NVARCHAR(MAX) = '';
DECLARE backup_cursor CURSOR FOR SELECT physical_device_name FROM msdb.dbo.backupmediafamily bmf JOIN msdb.dbo.backupset bs ON bmf.media_set_id = bs.media_set_id WHERE bs.backup_finish_date >= DATEADD(DAY, -1, GETDATE()) AND bs.database_name IN ( SELECT name FROM sys.databases WHERE database_id > 4 );
OPEN backup_cursor; FETCH NEXT FROM backup_cursor INTO @BackupFile;
WHILE @@FETCH_STATUS = 0 BEGIN BEGIN TRY RESTORE VERIFYONLY FROM DISK = @BackupFile WITH CHECKSUM; END TRY BEGIN CATCH SET @Fehler = @Fehler + 'FEHLER: ' + @BackupFile + ' — ' + ERROR_MESSAGE() + CHAR(13); END CATCH FETCH NEXT FROM backup_cursor INTO @BackupFile; END
CLOSE backup_cursor; DEALLOCATE backup_cursor;
IF LEN(@Fehler) > 0 EXEC msdb.dbo.sp_send_dbmail @profile_name = 'DBA-Alerts', @recipients = 'dba@firma.de', @subject = 'BACKUP-VALIDIERUNG FEHLGESCHLAGEN', @body = @Fehler; |
|
|
DIE 3-2-1-REGEL — PFLICHT FÜR JEDEN PRODUKTIVSERVER ■ 3 Kopien der Daten — Original + 2 Backups ■ 2 verschiedene Medien — z.B. lokaler NAS + externer Cloudspeicher ■ 1 Kopie off-site / offline — nicht erreichbar vom Produktionsnetz Ransomware verschlüsselt alles was das kompromittierte System erreichen kann. Die offline/off-site Kopie ist die einzige Garantie im Ernstfall — und muss regelmäßig getestet werden. |
04
Der Restore ist der eigentliche Test jeder Backup-Strategie. Ein Backup ist erst dann wertlos, wenn der Restore nicht funktioniert. Dieses Kapitel zeigt die wichtigsten Szenarien — mit konkreten Befehlen.
|
-- SZENARIO: "Jemand hat heute um 14:37 Uhr versehentlich 5000 Zeilen gelöscht" -- Ziel: Datenbank auf Stand 14:36 Uhr wiederherstellen
-- SCHRITT 1: Tail-Log Backup (sichert Log bis zum aktuellen Zeitpunkt) BACKUP LOG IhreDB TO DISK = 'E:\Restore\IhreDB_tail.bak' WITH NORECOVERY, STATS = 10; -- NORECOVERY: Datenbank bleibt im Restore-Modus
-- SCHRITT 2: Letztes Full Backup vor dem Vorfall restoren RESTORE DATABASE IhreDB_Restore FROM DISK = 'E:\Backup\Full\IhreDB_2026-01-26_230000.bak' WITH MOVE 'IhreDB' TO 'D:\Data\IhreDB_Restore.mdf', MOVE 'IhreDB_log' TO 'D:\Log\IhreDB_Restore.ldf', NORECOVERY, -- Noch nicht fertig: weitere Logs folgen STATS = 10;
-- SCHRITT 3: Differential Backup restoren (falls vorhanden) RESTORE DATABASE IhreDB_Restore FROM DISK = 'E:\Backup\Diff\IhreDB_2026-01-27_000000.bak' WITH NORECOVERY, STATS = 10;
-- SCHRITT 4: Log Backups bis kurz VOR dem Vorfall einspielen RESTORE LOG IhreDB_Restore FROM DISK = 'E:\Backup\Log\IhreDB_2026-01-27_140000.bak' WITH NORECOVERY, STATS = 10;
RESTORE LOG IhreDB_Restore FROM DISK = 'E:\Backup\Log\IhreDB_2026-01-27_150000.bak' WITH STOPAT = '2026-01-27 14:36:00', -- Stopp VOR dem Fehler! RECOVERY; -- Jetzt ist die DB online und konsistent |
|
-- SZENARIO: "Eine Tabelle versehentlich geleert — Rest der DB ist OK" -- Lösung: Backup in separate DB restoren, dann Daten exportieren
-- Schritt 1: Full Backup in Hilfs-Datenbank restoren RESTORE DATABASE IhreDB_Hilf FROM DISK = 'E:\Backup\Full\IhreDB_2026-01-26_230000.bak' WITH MOVE 'IhreDB' TO 'D:\Data\IhreDB_Hilf.mdf', MOVE 'IhreDB_log' TO 'D:\Log\IhreDB_Hilf.ldf', RECOVERY, -- Sofort online STATS = 10;
-- Schritt 2: Fehlende Daten aus Hilfs-DB in Produktion zurückkopieren INSERT INTO dbo.IhreTabelle (Spalte1, Spalte2, Spalte3) SELECT Spalte1, Spalte2, Spalte3 FROM IhreDB_Hilf.dbo.IhreTabelle WHERE ... ; -- Nur die fehlenden Zeilen!
-- Schritt 3: Hilfs-DB bereinigen DROP DATABASE IhreDB_Hilf; |
|
KATASTROPHENSZENARIO: Kompletter Serververlust (Brand, Ransomware, Hardware)
VORAUSSETZUNGEN (müssen VOR dem Ernstfall vorbereitet sein!): ✓ Dokumentierter Restore-Plan mit allen Pfaden und Passwörtern ✓ Backup-Verschlüsselungs-Zertifikat offline gesichert (!) — ohne dieses sind verschlüsselte Backups WERTLOS ✓ Service-Master-Key gesichert (für TDE) ✓ Letztes Backup off-site verfügbar (Cloud oder externes Medium) ✓ SQL Server Lizenz und Installationsmedien griffbereit
ABLAUF IM ERNSTFALL: T+0h: Schadensausmaß feststellen, Incident-Team aktivieren T+1h: Neuen Server bereitstellen (oder Cloud-VM) T+2h: SQL Server installieren, gleiche Version wie Produktion! T+3h: Service Master Key und TDE-Zertifikate einspielen T+4h: Full Backup restoren (NORECOVERY) T+5h: Differential und Log Backups einspielen (RECOVERY) T+6h: Applikations-Konnektivität prüfen, Logins anlegen T+7h: Fachbereichs-Abnahme, System freigeben
TIPP: Üben Sie diesen Ablauf jährlich auf einem Testsystem — mit Stoppuhr. Der Ernstfall ist der falsche Zeitpunkt, um herauszufinden dass das TDE-Zertifikat fehlt. |
|
-- Monatlicher Test-Restore — Ergebnis protokollieren INSERT INTO dbo.Restore_Test_Protokoll (Test_Datum, Datenbank, Backup_Datei, Restore_Dauer_Min, Datenbank_Groesse_GB, Test_Query_OK, Getestet_Von) VALUES ( GETDATE(), 'IhreERP_DB', 'E:\Backup\Full\IhreERP_DB_2026-01-26.bak', 47, -- Tatsächliche Restore-Dauer in Minuten 85.3, -- Datenbankgröße nach Restore 1, -- 1 = Test-Query erfolgreich 'S.Hess' ); |
05
Transparent Data Encryption (TDE) verschlüsselt Datenbankdateien (.mdf, .ldf, Backups) auf Dateisystemebene — transparent für Applikation und Benutzer. Ein Angreifer der die Datenbankdatei stiehlt, kann ohne den Schlüssel nichts damit anfangen.
|
-- SCHRITT 1: Master Key in master-Datenbank erstellen USE master; CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'S3hr$icheres!Passwort2026';
-- SCHRITT 2: TDE-Zertifikat erstellen CREATE CERTIFICATE TDE_Cert_ERP WITH SUBJECT = 'TDE Zertifikat ERP-Datenbank', EXPIRY_DATE = '2030-12-31';
-- SCHRITT 3: Zertifikat SOFORT sichern — ohne diese Datei kein Restore! BACKUP CERTIFICATE TDE_Cert_ERP TO FILE = 'E:\Sicherheit\TDE_Cert_ERP.cer' WITH PRIVATE KEY ( FILE = 'E:\Sicherheit\TDE_Cert_ERP_Key.pvk', ENCRYPTION BY PASSWORD = 'Zertifikat$Passwort2026!' ); -- KRITISCH: Diese Dateien OFFLINE sichern (USB, Safe, Cloud-Tresor) -- Niemals nur auf dem SQL Server selbst aufbewahren!
-- SCHRITT 4: Database Encryption Key in Zieldatenbank erstellen USE IhreERP_DB; CREATE DATABASE ENCRYPTION KEY WITH ALGORITHM = AES_256 ENCRYPTION BY SERVER CERTIFICATE TDE_Cert_ERP;
-- SCHRITT 5: TDE aktivieren ALTER DATABASE IhreERP_DB SET ENCRYPTION ON;
-- Verschlüsselungsstatus prüfen (Encryption State 3 = vollständig verschlüsselt) SELECT db.name AS Datenbank, dek.encryption_state AS State, CASE dek.encryption_state WHEN 0 THEN 'Keine Verschlüsselung' WHEN 1 THEN 'Unverschlüsselt' WHEN 2 THEN 'Verschlüsselung läuft...' WHEN 3 THEN 'Vollständig verschlüsselt' WHEN 4 THEN 'Schlüssel-Änderung läuft' WHEN 5 THEN 'Entschlüsselung läuft' END AS Status, ROUND(dek.percent_complete, 1) AS Fortschritt_Pct, dek.encryptor_type AS Verschlüsselungstyp FROM sys.dm_database_encryption_keys dek JOIN sys.databases db ON dek.database_id = db.database_id; |
|
-- Backups zusätzlich verschlüsseln (unabhängig von TDE) -- Schutz der Backup-Dateien auch ohne TDE auf Datenbankebene BACKUP DATABASE IhreERP_DB TO DISK = 'E:\Backup\Full\IhreERP_DB_verschluesselt.bak' WITH COMPRESSION, ENCRYPTION (ALGORITHM = AES_256, SERVER CERTIFICATE = TDE_Cert_ERP), STATS = 10;
-- WICHTIG: Backup-verschlüsselte Dateien brauchen das Zertifikat zum Restore! -- Ohne Zertifikat ist das Backup unbrauchbar — sichern Sie das Zertifikat -- immer getrennt vom Backup selbst. |
|
FORCE ENCRYPTION auf dem SQL Server aktivieren:
1. SQL Server Configuration Manager öffnen 2. SQL Server Network Configuration → Protocols for MSSQLSERVER 3. Eigenschaften → Certificate → TLS-Zertifikat auswählen 4. "Force Encryption" = Yes setzen 5. SQL Server Dienst neu starten
ERGEBNIS: Alle Verbindungen zum SQL Server sind nun verschlüsselt. Nicht verschlüsselte Verbindungen werden abgelehnt.
ZERTIFIKAT: Entweder CA-signiertes Zertifikat (empfohlen für Produktion) oder selbstsigniertes Zertifikat (für interne Systeme). Selbstsignierte Zertifikate brauchen "Trust Server Certificate" auf dem Client. |
06
Die stärkste Verschlüsselung nützt nichts wenn ein Angreifer gültige Zugangsdaten hat. SQL Server Authentifizierung ist häufig der schwächste Punkt — und der einfachste zu härten.
|
-- Sicherheits-kritische Konten und Konfigurationen prüfen SELECT sp.name AS Login_Name, sp.type_desc AS Login_Typ, sp.is_disabled AS Deaktiviert, sp.is_policy_checked AS Passwort_Policy, sp.is_expiration_checked AS Passwort_Ablauf, LOGINPROPERTY(sp.name, 'IsMustChange') AS Muss_Aendern, LOGINPROPERTY(sp.name, 'PasswordLastSetTime') AS PW_Gesetzt_Am, -- Sysadmin-Mitgliedschaft prüfen IS_SRVROLEMEMBER('sysadmin', sp.name) AS Ist_Sysadmin, CASE WHEN sp.name = 'sa' AND sp.is_disabled = 0 THEN 'KRITISCH: sa-Login aktiv!' WHEN sp.type_desc = 'SQL_LOGIN' AND sp.is_policy_checked = 0 THEN 'Warnung: Keine Passwort-Policy' WHEN IS_SRVROLEMEMBER('sysadmin', sp.name) = 1 AND sp.type_desc = 'SQL_LOGIN' THEN 'Prüfen: SQL-Login mit sysadmin-Rechten' ELSE 'OK' END AS Bewertung FROM sys.server_principals sp WHERE sp.type IN ('S', 'U', 'G') -- SQL, Windows User, Windows Group AND sp.name NOT LIKE '##%' -- Interne System-Logins ausschließen ORDER BY Ist_Sysadmin DESC, Login_Typ, Login_Name; |
|
-- sa ist das bekannteste Angriffsziel — immer deaktivieren! -- Schritt 1: Sicherstellen dass ein anderes sysadmin-Konto existiert SELECT name FROM sys.server_principals WHERE IS_SRVROLEMEMBER('sysadmin', name) = 1 AND name != 'sa' AND is_disabled = 0;
-- Schritt 2: sa deaktivieren (niemals löschen — geht nicht) ALTER LOGIN sa DISABLE;
-- Schritt 3: sa umbenennen (erschwerter Brute Force) ALTER LOGIN sa WITH NAME = [sa_deaktiviert];
-- Schritt 4: Starkes Passwort setzen (auch wenn deaktiviert) ALTER LOGIN [sa_deaktiviert] WITH PASSWORD = 'x9#Kz!2026$RndPasswort_NichtNutzen'; |
|
-- Service Accounts für Anwendungen: minimale Rechte -- Prinzip: Jede Anwendung bekommt nur was sie wirklich braucht
-- Anwendungs-Login anlegen (Windows Auth bevorzugt!) CREATE LOGIN [DOMAIN\ERP_ServiceAccount] FROM WINDOWS;
-- Datenbankbenutzer anlegen USE IhreERP_DB; CREATE USER ERP_App FOR LOGIN [DOMAIN\ERP_ServiceAccount];
-- Nur notwendige Rechte vergeben (KEIN db_owner!) GRANT EXECUTE ON SCHEMA::dbo TO ERP_App; -- Stored Procs ausführen -- KEIN direkter Tabellenzugriff wenn über Stored Procs steuerbar
-- Für lesende BI-Verbindungen: CREATE USER BI_ReadOnly FOR LOGIN [DOMAIN\BI_ServiceAccount]; GRANT SELECT ON SCHEMA::dbo TO BI_ReadOnly; -- Oder spezifisch nur auf Views: GRANT SELECT ON dbo.vw_PBI_Umsatz TO BI_ReadOnly; GRANT SELECT ON dbo.vw_PBI_Lager TO BI_ReadOnly;
-- Regelmäßige Berechtigungsprüfung: SELECT dp.name AS Datenbankbenutzer, sp.name AS Server_Login, r.name AS Datenbankrolle FROM sys.database_principals dp JOIN sys.server_principals sp ON dp.sid = sp.sid JOIN sys.database_role_members drm ON dp.principal_id = drm.member_principal_id JOIN sys.database_principals r ON drm.role_principal_id = r.principal_id WHERE dp.type IN ('U', 'G', 'S') ORDER BY dp.name; |
|
-- Alle SQL Logins auf Policy-Konformität prüfen SELECT name AS Login, is_policy_checked, is_expiration_checked, LOGINPROPERTY(name, 'BadPasswordCount') AS Fehlversuche, LOGINPROPERTY(name, 'IsLocked') AS Gesperrt, CAST(LOGINPROPERTY(name, 'PasswordLastSetTime') AS DATE) AS PW_Datum FROM sys.sql_logins WHERE is_disabled = 0 ORDER BY LOGINPROPERTY(name, 'PasswordLastSetTime') ASC;
-- Policy für bestehende Logins aktivieren ALTER LOGIN AppUser WITH CHECK_POLICY = ON, CHECK_EXPIRATION = ON; |
07
SQL Server Audit protokolliert Datenbankaktivitäten tamper-evident in Dateien oder den Windows Event Log — unveränderbar, lückenlos und DSGVO/NIS-2 konform.
|
-- Server Audit: protokolliert alle sicherheitsrelevanten Ereignisse -- in eine Datei (kann auch Windows Event Log oder Application Log sein) CREATE SERVER AUDIT SQL_Security_Audit TO FILE ( FILEPATH = 'E:\Audit\', MAXSIZE = 100 MB, MAX_FILES = 50, -- 50 × 100 MB = 5 GB Audit-Log RESERVE_DISK_SPACE = OFF ) WITH ( QUEUE_DELAY = 1000, -- 1 Sekunde Puffer (Performance) ON_FAILURE = CONTINUE -- Server läuft auch wenn Audit-Schreiben fehlt -- ON_FAILURE = SHUTDOWN -- Für höchste Compliance: Server stoppt! );
-- Audit aktivieren ALTER SERVER AUDIT SQL_Security_Audit WITH (STATE = ON);
-- Server Audit Specification: Was wird auf Server-Ebene protokolliert? CREATE SERVER AUDIT SPECIFICATION SA_Security_Events FOR SERVER AUDIT SQL_Security_Audit ADD (FAILED_LOGIN_GROUP), -- Fehlgeschlagene Logins ADD (SUCCESSFUL_LOGIN_GROUP), -- Erfolgreiche Logins (optional — viel Traffic) ADD (LOGOUT_GROUP), -- Abmeldungen ADD (SERVER_ROLE_MEMBER_CHANGE_GROUP), -- Sysadmin-Mitglied hinzugefügt/entfernt ADD (DATABASE_OWNERSHIP_CHANGE_GROUP), -- DB-Besitzer geändert ADD (LOGIN_CHANGE_PASSWORD_GROUP), -- Passwortänderungen ADD (AUDIT_CHANGE_GROUP) -- Änderungen am Audit selbst WITH (STATE = ON); |
|
-- Datenbankspezifisches Audit — was wird in der Datenbank protokolliert? CREATE DATABASE AUDIT SPECIFICATION DA_ERP_Audit FOR SERVER AUDIT SQL_Security_Audit ADD (SELECT ON dbo.Gehaelter BY PUBLIC), -- Lesezugriff auf Gehaltsdaten ADD (INSERT, UPDATE, DELETE ON dbo.Kunden BY PUBLIC), -- CUD auf Kunden ADD (INSERT, UPDATE, DELETE ON dbo.Lieferanten BY PUBLIC), -- CUD Lieferanten ADD (EXECUTE ON dbo.sp_ZahlungFreigeben BY PUBLIC), -- Zahlungsfreigabe ADD (DATABASE_ROLE_MEMBER_CHANGE_GROUP), -- Rollenzuweisungen ADD (DATABASE_OBJECT_PERMISSION_CHANGE_GROUP), -- Rechtevergabe ADD (SCHEMA_OBJECT_CHANGE_GROUP) -- DDL: CREATE, ALTER, DROP WITH (STATE = ON); |
|
-- Audit-Log lesen: Wer hat wann auf was zugegriffen? SELECT TOP 1000 CAST(event_time AT TIME ZONE 'UTC' AT TIME ZONE 'W. Europe Standard Time' AS DATETIME) AS Ereigniszeit, action_id AS Aktion, succeeded AS Erfolgreich, server_principal_name AS Benutzer, database_name AS Datenbank, object_name AS Objekt, statement AS SQL_Statement, client_ip AS Client_IP, application_name AS Anwendung FROM sys.fn_get_audit_file('E:\Audit\*.sqlaudit', DEFAULT, DEFAULT) WHERE event_time >= DATEADD(DAY, -7, GETDATE()) ORDER BY event_time DESC;
-- Fehlgeschlagene Logins der letzten 24h (Brute Force Erkennung) SELECT server_principal_name AS Login_Versuch, client_ip AS Von_IP, COUNT(*) AS Fehlversuche, MIN(event_time) AS Erster_Versuch, MAX(event_time) AS Letzter_Versuch FROM sys.fn_get_audit_file('E:\Audit\*.sqlaudit', DEFAULT, DEFAULT) WHERE action_id = 'LGIF' -- Failed Login AND event_time >= DATEADD(HOUR, -24, GETDATE()) GROUP BY server_principal_name, client_ip HAVING COUNT(*) > 10 -- > 10 Fehlversuche = Alarm ORDER BY Fehlversuche DESC; |
08
SQL Server kommt mit aktivierten Features, die in den meisten Umgebungen nicht gebraucht werden — aber Angriffsfläche bieten. Surface Area Reduction deaktiviert was nicht genutzt wird.
|
-- Unnötige Features deaktivieren (sp_configure) EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
-- xp_cmdshell: Shell-Befehle aus SQL — fast immer unnötig, hohes Risiko EXEC sp_configure 'xp_cmdshell', 0; RECONFIGURE;
-- Ole Automation: COM-Objekte aus SQL — unnötig in ERP-Umgebungen EXEC sp_configure 'Ole Automation Procedures', 0; RECONFIGURE;
-- Ad Hoc Distributed Queries: OPENROWSET / OPENDATASOURCE -- Nur aktivieren wenn explizit benötigt EXEC sp_configure 'Ad Hoc Distributed Queries', 0; RECONFIGURE;
-- CLR: .NET Code in SQL — nur aktivieren wenn CLR-Assemblies genutzt werden EXEC sp_configure 'clr enabled', 0; RECONFIGURE;
-- Remote Admin Connection: DAC nur lokal erlauben EXEC sp_configure 'remote admin connections', 0; RECONFIGURE;
EXEC sp_configure 'show advanced options', 0; RECONFIGURE;
-- Aktuellen Zustand aller sicherheitsrelevanten Konfigurationen prüfen SELECT name, value_in_use, description FROM sys.configurations WHERE name IN ( 'xp_cmdshell', 'Ole Automation Procedures', 'Ad Hoc Distributed Queries', 'clr enabled', 'remote admin connections', 'cross db ownership chaining', 'Database Mail XPs', 'SMO and DMO XPs' ) ORDER BY name; |
|
FIREWALL-REGELN FÜR SQL SERVER:
ERLAUBEN: Port 1433 (TCP) → Nur von Anwendungsservern und Admin-Workstations Port 1434 (UDP) → SQL Server Browser (nur wenn Named Instances genutzt) Port 135 (TCP) → SQL Server Configuration Manager Remote
BLOCKIEREN: Port 1433 aus dem Internet → NIEMALS direkt exponieren Port 1433 aus fremden Netzwerken → Nur definierte Quell-IPs
EMPFEHLUNG: SQL Server niemals direkt im Internet erreichbar. Zugriff nur über VPN oder Jump Server (Bastion Host). Windows Firewall auf dem SQL Server aktivieren und konfigurieren. Named Pipes deaktivieren (nur TCP/IP verwenden).
-- Named Pipes Status prüfen (sollte 0 sein für reine TCP-Umgebungen): -- SQL Server Configuration Manager → -- SQL Server Network Configuration → -- Protocols: Named Pipes = Disabled |
|
Punkt |
Soll |
Prüfung |
|
sa-Login deaktiviert |
Ja |
sys.server_principals |
|
Windows-Auth erzwungen |
Empfohlen |
SQL Server Properties |
|
Passwort-Policy aktiv |
Ja |
sys.sql_logins |
|
TDE aktiviert |
Ja (Prod.) |
sys.dm_database_encryption_keys |
|
TLS erzwungen |
Ja |
SQL Server Config Manager |
|
xp_cmdshell deaktiviert |
Ja |
sys.configurations |
|
Audit aktiv |
Ja |
sys.server_audits |
|
Backup-Verschlüsselung |
Empfohlen |
Backup-History |
|
Firewall-Regel Port 1433 |
Ja |
Windows Firewall |
|
Regelmäßiger Restore-Test |
Monatlich |
Restore_Test_Protokoll |
09
Ein Sicherheitskonzept ohne Monitoring ist ein Konzept auf dem Papier. Dieses Kapitel zeigt wie SQL Agent, Database Mail und DMVs zusammenwirken um den DBA proaktiv zu informieren.
|
-- Kritischer Alert: Datenbankn ohne Backup in den letzten 26 Stunden -- Als SQL Agent Job täglich 08:00 laufen lassen DECLARE @Fehlende NVARCHAR(MAX) = '';
SELECT @Fehlende = @Fehlende + d.name + CHAR(13) FROM sys.databases d WHERE d.database_id > 4 -- Keine Systemdatenbanken AND d.state = 0 -- Nur Online-Datenbanken AND d.name NOT IN ( SELECT database_name FROM msdb.dbo.backupset WHERE type = 'D' -- Full Backup AND backup_finish_date > DATEADD(HOUR, -26, GETDATE()) );
IF LEN(@Fehlende) > 0 EXEC msdb.dbo.sp_send_dbmail @profile_name = 'DBA-Alerts', @recipients = 'dba@firma.de;itl@firma.de', @subject = 'ALARM: Fehlende Backups auf ' + @@SERVERNAME, @body = 'Folgende Datenbanken haben seit > 26h kein Full Backup:' + CHAR(13) + @Fehlende + CHAR(13) + 'Bitte sofort prüfen!';
-- Backup-History der letzten 7 Tage SELECT bs.database_name AS Datenbank, bs.type AS Typ, -- D=Full, I=Diff, L=Log bs.backup_finish_date AS Abgeschlossen_Am, ROUND(bs.backup_size / 1024.0 / 1024.0, 0) AS Groesse_MB, ROUND(bs.compressed_backup_size / 1024.0 / 1024.0, 0) AS Komprimiert_MB, ROUND(100.0 * (1 - bs.compressed_backup_size / NULLIF(bs.backup_size, 0)), 1) AS Kompression_Pct, bmf.physical_device_name AS Backup_Pfad, bs.has_backup_checksums AS Checksum_OK FROM msdb.dbo.backupset bs JOIN msdb.dbo.backupmediafamily bmf ON bs.media_set_id = bmf.media_set_id WHERE bs.backup_finish_date >= DATEADD(DAY, -7, GETDATE()) AND bs.database_name NOT IN ('tempdb') ORDER BY bs.database_name, bs.backup_finish_date DESC; |
|
-- Brute-Force-Erkennung: Viele fehlgeschlagene Logins von einer IP -- Als SQL Agent Job stündlich laufen lassen DECLARE @BruteForce NVARCHAR(MAX) = '';
SELECT @BruteForce = @BruteForce + client_ip + ': ' + CAST(COUNT(*) AS VARCHAR) + ' Fehlversuche (Login: ' + ISNULL(server_principal_name, 'unbekannt') + ')' + CHAR(13) FROM sys.fn_get_audit_file('E:\Audit\*.sqlaudit', DEFAULT, DEFAULT) WHERE action_id = 'LGIF' AND event_time >= DATEADD(HOUR, -1, GETDATE()) GROUP BY client_ip, server_principal_name HAVING COUNT(*) > 20; -- > 20 Fehlversuche/Stunde = Alarm
IF LEN(@BruteForce) > 0 EXEC msdb.dbo.sp_send_dbmail @profile_name = 'DBA-Alerts', @recipients = 'security@firma.de;dba@firma.de', @subject = 'SICHERHEITS-ALARM: Möglicher Brute Force auf ' + @@SERVERNAME, @body = 'Verdächtige Login-Aktivität:' + CHAR(13) + @BruteForce; |
|
-- Kritische Fehler aus dem SQL Server Error Log extrahieren -- (Die letzten 24 Stunden) DECLARE @Fehler TABLE ( LogDate DATETIME, ProcessInfo NVARCHAR(50), [Text] NVARCHAR(MAX));
INSERT INTO @Fehler EXEC xp_readerrorlog 0, 1, NULL, NULL, DATEADD(DAY, -1, GETDATE()), GETDATE(), N'desc';
SELECT LogDate, ProcessInfo, [Text] FROM @Fehler WHERE [Text] LIKE '%error%' OR [Text] LIKE '%failed%' OR [Text] LIKE '%corrupt%' OR [Text] LIKE '%cannot%' OR [Text] LIKE '%fatal%' ORDER BY LogDate DESC; |
10
Dieser Plan führt systematisch durch alle Schritte — von der ersten Bestandsaufnahme bis zu einem vollständig dokumentierten, getesteten und laufend überwachten Backup- und Sicherheitskonzept.
|
|
VOR DEM START Vollständiges Backup aller produktiven Datenbanken erstellen. Change-Management-Prozess aktivieren — alle Änderungen protokollieren. IT-Leitung und Geschäftsführung über den Audit informieren. RPO/RPO-Anforderungen vom Business einholen (nicht selbst festlegen!). |
■ TAG 1-2: BACKUP-STATUS ANALYSIEREN
■ Alle Datenbanken und Recovery-Modelle auflisten (Skript Kapitel 2.1)
■ Letzte Full-/Differential-/Log-Backups je Datenbank prüfen
■ Backup-Speicherorte dokumentieren: Wo liegen die Backup-Dateien?
■ 3-2-1-Regel prüfen: Gibt es eine offline/off-site Kopie?
■ TDE-Status prüfen (Skript Kapitel 5.1): Sind die Zertifikate gesichert?
■ TAG 3-5: SICHERHEITS-AUDIT
■ Login-Security-Report ausführen (Skript Kapitel 6.1)
■ sa-Login: aktiv oder deaktiviert? Sofort deaktivieren wenn aktiv!
■ Sysadmin-Mitglieder prüfen: Wer hat welche Serverrechte?
■ Surface Area prüfen (Skript Kapitel 8.1): xp_cmdshell aktiv?
■ Audit aktiv? Falls nicht: sofort als Priorität einplanen
■ TAG 6-9: BACKUP-JOBS EINRICHTEN
■ Recovery-Modell auf FULL setzen für alle produktiven DBs
■ Ola Hallengren DatabaseBackup Jobs konfigurieren (Skript Kapitel 3.2)
■ Full-Backup-Job: Sonntag 23:00 — mit VERIFY und CHECKSUM
■ Differential-Job: Mo-Sa 23:00
■ Log-Backup-Job: stündlich — auf separatem Pfad
■ Backup-Validierungs-Job einrichten (Skript Kapitel 3.3)
■ TAG 10-14: RESTORE-TEST DURCHFÜHREN
■ Test-Restore der letzten Full-Backups auf Testsystem durchführen
■ Zeit messen: Wie lange dauert ein Full-Restore?
■ Point-in-Time Restore testen (Skript Kapitel 4.1)
■ Restore-Test-Protokoll anlegen (Skript Kapitel 4.4)
■ TDE-Zertifikate testen: Restore mit Zertifikat auf Testsystem erfolgreich?
■ TAG 15-17: ZUGRIFFSRECHTE BEREINIGEN
■ Login-Bereinigung: Inaktive Logins deaktivieren (kein Login > 90 Tage)
■ sa deaktivieren und umbenennen (Skript Kapitel 6.2)
■ Passwort-Policy auf allen SQL Logins aktivieren
■ Service-Account-Rechte minimieren (Skript Kapitel 6.3)
■ TLS/Force Encryption aktivieren (Kapitel 5.3)
■ TAG 18-21: AUDIT & VERSCHLÜSSELUNG
■ TDE auf alle produktiven Datenbanken aktivieren (Skript Kapitel 5.1)
■ TDE-Zertifikate OFFLINE sichern — physisch, nicht nur auf Server
■ Server Audit einrichten (Skript Kapitel 7.1)
■ Database Audit Specification für kritische Tabellen (Kapitel 7.2)
■ Surface Area Reduction: xp_cmdshell und unnötige Features deaktivieren
■ TAG 22-25: MONITORING AKTIVIEREN
■ Backup-Monitoring-Job einrichten (Skript Kapitel 9.1): täglich 08:00
■ Security-Event-Monitoring: Brute-Force-Alert (Skript Kapitel 9.2)
■ Error-Log-Monitoring als täglichen Job einrichten
■ Database Mail konfigurieren und testen: Kommt der Alert an?
■ Eskalationspfad definieren: Wer bekommt welchen Alert?
■ TAG 26-28: DOKUMENTATION
■ Backup-Konzept dokumentieren: Strategie, Zeitplan, Aufbewahrung, Pfade
■ Restore-Playbook schreiben: Schritt-für-Schritt für jeden Restore-Typ
■ TDE-Zertifikat-Dokumentation: Wo liegt das Zertifikat, wer kennt das Passwort?
■ Sicherheitskonzept dokumentieren: Logins, Rollen, Audit-Konfiguration
■ Notfall-Kontaktliste: Wer wird wann angerufen?
■ TAG 29-30: ABSCHLUSS & REVIEW
■ Sicherheitscheckliste (Kapitel 8.3) vollständig abhaken
■ Backup-Konzept und Sicherheitskonzept von IT-Leitung freigeben lassen
■ Jährlichen Review-Termin festlegen: Konzept, Restore-Test, Zertifikate
■ NIS-2/DSGVO Konformität mit Datenschutzbeauftragtem abstimmen ■
|
|
ERGEBNIS NACH 30 TAGEN Nach 30 Tagen haben Sie eine getestete Backup-Strategie die RPO/RTO-Anforderungen erfüllt, ein dokumentiertes Restore-Playbook das im Ernstfall funktioniert, TDE auf allen produktiven Datenbanken, einen lückenlosen Audit-Trail und ein automatisiertes Monitoring das Probleme sofort meldet — revisionsicher und NIS-2-konform. |
Die in diesem Dokument enthaltenen Informationen, Skripte und Sicherheitsempfehlungen wurden nach bestem Wissen und Gewissen auf der Grundlage langjähriger praktischer Erfahrung erstellt. Der Autor übernimmt ausdrücklich keinerlei Haftung für Datenverlust, fehlgeschlagene Restores, Sicherheitsvorfälle, Compliance-Verstöße oder sonstige Schäden.
Sicherheitskonfigurationen und Backup-Strategien müssen an die spezifische Unternehmensumgebung, die geltenden Compliance-Anforderungen und die vorhandene Infrastruktur angepasst werden. Die Nutzung erfolgt ausschließlich auf eigenes Risiko.
Hinweise zu NIS-2, DSGVO und Compliance-Anforderungen ersetzen keine rechtliche Beratung. Für rechtsverbindliche Aussagen zur regulatorischen Konformität sind entsprechende Fachberater hinzuzuziehen.
Die Inhalte beziehen sich auf SQL Server 2022 (16.x) und SQL Server 2025 (17.x), Stand März 2026. Systemview-Namen, DMV-Felder und Feature-Verfügbarkeit können in anderen Versionen abweichen.
Dieses Dokument und alle Inhalte sind urheberrechtlich geschützt. © 2026 Sascha Hess, xenosystems.de. Alle Rechte vorbehalten.
SQL Server, Azure, Microsoft sind eingetragene Marken der Microsoft Corporation. Alle anderen genannten Produktnamen sind Eigentum ihrer jeweiligen Inhaber.
Es gilt ausschließlich deutsches Recht. Gerichtsstand ist, soweit gesetzlich zulässig, Weimar, Thüringen, Deutschland.
Sascha Hess ist Diplom-Biologe und IT-Professional mit über 20 Jahren Erfahrung in der Administration von ERP-, BI- und Datenbanksystemen. Er hat Backup-Konzepte und Sicherheitsarchitekturen für mehr als 300 SQL Server- und Oracle-Instanzen entwickelt und umgesetzt — von kleinen KMU bis zu Universitäten und Energieversorgern unter regulatorischen Anforderungen.
Sein Ansatz verbindet naturwissenschaftliche Präzision mit pragmatischer IT-Erfahrung. Schwerpunkte: SQL Server Security, Backup & Recovery, Performance-Tuning, ERP-Datenbankadministration und IT-Interim-Management.
Web: www.xenosystems.de | E-Mail: info@xenosystems.de | Standort: Weimar, Thüringen / Remote
|
Service |
Beschreibung |
|
SQL Server DB Health Check |
Vollständiger Audit inkl. Backup-Konzept, Sicherheitskonfiguration und Restore-Test — Managementreport und Maßnahmenplan. Scope: 3-5 Tage. |
|
SQL Server Security Review |
Tiefgehende Analyse der Sicherheitskonfiguration: Logins, Rechte, Audit, TDE, Netzwerk — mit priorisiertem Härtungsplan. |
|
Backup-Konzept & Restore-Test |
Entwicklung einer RTO/RPO-konformen Backup-Strategie, Dokumentation des Restore-Playbooks und Durchführung von Restore-Tests. |
|
SQL Server Performance-Tuning |
Index-Analyse, Query-Optimierung, Konfiguration — messbare Performance-Verbesserungen in Tagen. |
|
Interim IT-Management |
Übernahme der IT-Steuerung auf Zeit — Budgetplanung, Dienstleister-Management, strategische IT-Ausrichtung. |
Vollständiges Dokument
Strategische Wissens-Roadmap · Checklisten · Praxisbeispiele
49,90 €
Sichere Zahlung über PayPal · Sofort-Download nach Zahlungseingang