mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-19 22:19:39 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,271 @@
|
||||
---
|
||||
name: implementing-ransomware-backup-strategy
|
||||
description: >
|
||||
Designs and implements a ransomware-resilient backup strategy following the 3-2-1-1-0
|
||||
methodology (3 copies, 2 media types, 1 offsite, 1 immutable/air-gapped, 0 errors on
|
||||
restore verification). Configures backup schedules aligned to RPO/RTO requirements,
|
||||
implements backup credential isolation to prevent ransomware from compromising backup
|
||||
infrastructure, and establishes automated restore testing. Activates for requests involving
|
||||
ransomware backup planning, backup resilience, air-gapped backup design, or backup
|
||||
recovery point objective configuration.
|
||||
domain: cybersecurity
|
||||
subdomain: ransomware-defense
|
||||
tags: [ransomware, backup, incident-response, defense, recovery, immutable-storage]
|
||||
version: 1.0.0
|
||||
author: mahipal
|
||||
license: MIT
|
||||
---
|
||||
# Implementing Ransomware Backup Strategy
|
||||
|
||||
## When to Use
|
||||
|
||||
- Designing backup architecture that withstands ransomware encryption and deletion attempts
|
||||
- Migrating from traditional backup to ransomware-resilient backup with immutable storage
|
||||
- Establishing RPO/RTO targets for critical systems and validating them through restore testing
|
||||
- Isolating backup credentials and infrastructure from the production Active Directory domain
|
||||
- Meeting cyber insurance requirements for backup resilience and tested recovery capabilities
|
||||
|
||||
**Do not use** as a substitute for endpoint protection, network segmentation, or incident response planning. Backups are a last line of defense, not a primary prevention control.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Inventory of critical systems, applications, and data classified by business impact (Tier 1/2/3)
|
||||
- Defined RPO (Recovery Point Objective) and RTO (Recovery Time Objective) per tier
|
||||
- Backup software supporting immutable repositories (Veeam 12+, Commvault, Rubrik, Cohesity)
|
||||
- Isolated backup network segment or air-gapped storage infrastructure
|
||||
- Separate backup admin credentials not joined to the production AD domain
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Classify Assets and Define Recovery Objectives
|
||||
|
||||
Map all systems into recovery tiers based on business impact:
|
||||
|
||||
| Tier | Examples | RPO | RTO | Backup Frequency |
|
||||
|------|----------|-----|-----|------------------|
|
||||
| Tier 1 (Critical) | Domain controllers, ERP, databases | 1 hour | 4 hours | Hourly incremental, daily full |
|
||||
| Tier 2 (Important) | File servers, email, web apps | 4 hours | 12 hours | Every 4 hours incremental, daily full |
|
||||
| Tier 3 (Standard) | Dev environments, archives | 24 hours | 48 hours | Daily incremental, weekly full |
|
||||
|
||||
Document dependencies between systems. Domain controllers and DNS must recover before application servers. Database servers before application tiers.
|
||||
|
||||
### Step 2: Implement 3-2-1-1-0 Architecture
|
||||
|
||||
Configure backup storage following the extended 3-2-1-1-0 rule:
|
||||
|
||||
**Copy 1 - Primary backup on local storage:**
|
||||
```
|
||||
# Veeam backup job targeting local repository
|
||||
# Fast restore for operational recovery
|
||||
Backup Repository: Local NAS (CIFS/NFS) or SAN
|
||||
Retention: 14 days of restore points
|
||||
Encryption: AES-256 with password not stored in AD
|
||||
```
|
||||
|
||||
**Copy 2 - Secondary backup on different media:**
|
||||
```
|
||||
# Replicate to secondary site or cloud
|
||||
# Veeam Backup Copy Job or Scale-Out Backup Repository
|
||||
Target: AWS S3 / Azure Blob / Wasabi / tape library
|
||||
Retention: 30 days
|
||||
Transfer: Encrypted TLS 1.2+ in transit
|
||||
```
|
||||
|
||||
**Copy 3 - Offsite copy:**
|
||||
```
|
||||
# Geographically separated from primary and secondary
|
||||
# Cloud object storage in different region or physical tape rotation
|
||||
Target: Cross-region cloud storage or Iron Mountain tape vaulting
|
||||
Retention: 90 days
|
||||
```
|
||||
|
||||
**+1 - Immutable or air-gapped copy:**
|
||||
```
|
||||
# Cannot be modified or deleted for defined retention period
|
||||
# Veeam Hardened Repository on Linux with immutable flag
|
||||
# Or AWS S3 Object Lock in Compliance mode
|
||||
# Or physical air-gapped tape
|
||||
```
|
||||
|
||||
**+0 - Zero errors on restore verification:**
|
||||
```
|
||||
# Automated restore testing using Veeam SureBackup or equivalent
|
||||
# Scheduled weekly for Tier 1, monthly for Tier 2/3
|
||||
# Verify boot, network connectivity, and application health
|
||||
```
|
||||
|
||||
### Step 3: Isolate Backup Credentials
|
||||
|
||||
Ransomware operators target backup infrastructure by compromising backup admin credentials through Active Directory:
|
||||
|
||||
1. **Separate backup admin accounts** from the production AD domain. Use local accounts on backup servers or a dedicated backup management domain.
|
||||
2. **Dedicated backup network segment** with firewall rules allowing only backup traffic (specific ports, specific source/destination IPs).
|
||||
3. **MFA on backup console access** using hardware tokens or authenticator apps, not SMS.
|
||||
4. **Disable RDP** on backup servers. Use out-of-band management (iLO/iDRAC/IPMI) for emergency access.
|
||||
5. **Remove backup servers from domain** or place in a dedicated OU with restricted GPO inheritance.
|
||||
|
||||
```bash
|
||||
# Linux Hardened Repository - disable SSH password auth
|
||||
sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
|
||||
sudo systemctl restart sshd
|
||||
|
||||
# Set immutable flag on backup files (XFS filesystem)
|
||||
sudo chattr +i /mnt/backup/repository/*
|
||||
|
||||
# Veeam Hardened Repository uses single-use credentials
|
||||
# that are not stored on the Veeam server after initial setup
|
||||
```
|
||||
|
||||
### Step 4: Configure Immutable Storage
|
||||
|
||||
**Veeam Hardened Linux Repository:**
|
||||
```bash
|
||||
# Minimal Ubuntu 22.04 LTS installation
|
||||
# No GUI, no unnecessary services
|
||||
# Veeam uses temporary SSH credentials during backup window only
|
||||
|
||||
# Configure XFS with reflink support
|
||||
sudo mkfs.xfs -b size=4096 -m reflink=1 /dev/sdb1
|
||||
sudo mount /dev/sdb1 /mnt/veeam-repo
|
||||
|
||||
# Create dedicated Veeam user with limited permissions
|
||||
sudo useradd -m -s /bin/bash veeamuser
|
||||
sudo mkdir -p /mnt/veeam-repo/backups
|
||||
sudo chown veeamuser:veeamuser /mnt/veeam-repo/backups
|
||||
```
|
||||
|
||||
**AWS S3 Object Lock (Compliance Mode):**
|
||||
```bash
|
||||
# Create bucket with Object Lock enabled
|
||||
aws s3api create-bucket \
|
||||
--bucket company-immutable-backups \
|
||||
--object-lock-enabled-for-bucket \
|
||||
--region us-east-1
|
||||
|
||||
# Set default retention - 30 days compliance mode
|
||||
aws s3api put-object-lock-configuration \
|
||||
--bucket company-immutable-backups \
|
||||
--object-lock-configuration '{
|
||||
"ObjectLockEnabled": "Enabled",
|
||||
"Rule": {
|
||||
"DefaultRetention": {
|
||||
"Mode": "COMPLIANCE",
|
||||
"Days": 30
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
**Azure Immutable Blob Storage:**
|
||||
```bash
|
||||
# Create storage account with immutable storage
|
||||
az storage container immutability-policy create \
|
||||
--account-name backupaccount \
|
||||
--container-name immutable-backups \
|
||||
--period 30
|
||||
|
||||
# Lock the policy (irreversible)
|
||||
az storage container immutability-policy lock \
|
||||
--account-name backupaccount \
|
||||
--container-name immutable-backups
|
||||
```
|
||||
|
||||
### Step 5: Automate Restore Testing
|
||||
|
||||
Configure automated restore verification on a recurring schedule:
|
||||
|
||||
```powershell
|
||||
# Veeam SureBackup verification job (PowerShell)
|
||||
# Tests VM boot, network ping, and application health
|
||||
|
||||
Add-PSSnapin VeeamPSSnapin
|
||||
$backupJob = Get-VBRJob -Name "Tier1-DailyBackup"
|
||||
$sureBackupJob = Get-VSBJob -Name "Tier1-RestoreTest"
|
||||
|
||||
# Verify last restore test completed successfully
|
||||
$lastSession = Get-VSBSession -Job $sureBackupJob -Last
|
||||
if ($lastSession.Result -ne "Success") {
|
||||
Send-MailMessage -To "backup-team@company.com" `
|
||||
-Subject "ALERT: SureBackup verification failed" `
|
||||
-Body "Tier 1 restore test failed. Last result: $($lastSession.Result)" `
|
||||
-SmtpServer "smtp.company.com"
|
||||
}
|
||||
```
|
||||
|
||||
Document restore test results and maintain a recovery runbook with step-by-step procedures for each tier.
|
||||
|
||||
## Key Concepts
|
||||
|
||||
| Term | Definition |
|
||||
|------|------------|
|
||||
| **3-2-1-1-0** | Extended backup rule: 3 copies, 2 media types, 1 offsite, 1 immutable/air-gapped, 0 restore verification errors |
|
||||
| **RPO** | Recovery Point Objective: maximum acceptable data loss measured in time (e.g., 1 hour RPO means max 1 hour of data loss) |
|
||||
| **RTO** | Recovery Time Objective: maximum acceptable downtime before system must be operational |
|
||||
| **Immutable Backup** | Backup copy that cannot be modified, encrypted, or deleted for a defined retention period, even by administrators |
|
||||
| **Air-Gapped Backup** | Physically isolated backup with no network connectivity to production systems, providing strongest ransomware protection |
|
||||
| **Hardened Repository** | Linux-based backup storage with minimal attack surface, no persistent SSH, and immutable file flags |
|
||||
|
||||
## Tools & Systems
|
||||
|
||||
- **Veeam Backup & Replication 12**: Enterprise backup with Hardened Linux Repository, SureBackup verification, and immutable backup support
|
||||
- **Rubrik Security Cloud**: Zero-trust backup platform with immutable snapshots, anomaly detection, and air-gapped recovery
|
||||
- **Commvault**: Backup with Metallic air-gap protection, anomaly detection, and automated recovery orchestration
|
||||
- **AWS S3 Object Lock**: Cloud-native immutable storage in Compliance or Governance mode for backup copies
|
||||
- **Cohesity DataProtect**: Backup platform with DataLock immutability, anti-ransomware detection, and instant mass restore
|
||||
|
||||
## Common Scenarios
|
||||
|
||||
### Scenario: Financial Services Firm Implementing Ransomware-Resilient Backup
|
||||
|
||||
**Context**: A mid-size bank with 500 servers, 200TB of data, and regulatory requirements for 7-year retention must redesign backup after a peer institution was hit by ransomware. Current backups use a single Veeam repository on a Windows server joined to the production domain.
|
||||
|
||||
**Approach**:
|
||||
1. Classify all 500 servers into three tiers: 50 Tier 1 (core banking, AD, DNS), 200 Tier 2 (email, file shares, web), 250 Tier 3 (dev, test, archive)
|
||||
2. Deploy Veeam Hardened Linux Repository on dedicated Ubuntu 22.04 servers with XFS immutability for primary backup
|
||||
3. Configure S3 Object Lock in Compliance mode for 30-day immutable cloud copy with Veeam Scale-Out Repository capacity tier
|
||||
4. Establish quarterly tape rotation to Iron Mountain for 7-year regulatory retention
|
||||
5. Remove all backup servers from the production AD domain and create isolated backup admin accounts with hardware MFA tokens
|
||||
6. Deploy SureBackup jobs: weekly for Tier 1, monthly for Tier 2, quarterly for Tier 3
|
||||
7. Conduct annual full recovery drill restoring AD, DNS, core banking, and dependent applications to validate documented RTO
|
||||
|
||||
**Pitfalls**:
|
||||
- Leaving backup admin credentials in the production AD domain where ransomware operators can compromise them via Kerberoasting or DCSync
|
||||
- Configuring immutable retention periods shorter than the dwell time of typical ransomware (average 21 days), allowing attackers to wait for immutability to expire
|
||||
- Testing only individual VM restores without testing full application stack recovery including dependencies
|
||||
- Forgetting to back up backup server configuration (Veeam config database, encryption keys) separately from the backup infrastructure itself
|
||||
|
||||
## Output Format
|
||||
|
||||
```
|
||||
## Ransomware Backup Strategy Assessment
|
||||
|
||||
**Organization**: [Name]
|
||||
**Assessment Date**: [Date]
|
||||
**Assessor**: [Name]
|
||||
|
||||
### Current State
|
||||
- Backup Solution: [Product/Version]
|
||||
- Copies: [Number and locations]
|
||||
- Immutable Copy: [Yes/No - Details]
|
||||
- Air-Gapped Copy: [Yes/No - Details]
|
||||
- Credential Isolation: [Yes/No - Details]
|
||||
- Last Restore Test: [Date - Result]
|
||||
|
||||
### Gap Analysis
|
||||
| Control | Current | Target | Gap | Priority |
|
||||
|---------|---------|--------|-----|----------|
|
||||
| Immutable backup | None | S3 Object Lock + Linux Hardened Repo | Missing | Critical |
|
||||
| Credential isolation | Domain-joined | Standalone local accounts + MFA | Partial | Critical |
|
||||
| Restore testing | Ad-hoc manual | Automated weekly SureBackup | Missing | High |
|
||||
|
||||
### Recommendations
|
||||
1. [Priority] [Recommendation] - [Estimated effort]
|
||||
2. ...
|
||||
|
||||
### Recovery Tier Summary
|
||||
| Tier | Systems | RPO | RTO | Backup Schedule | Restore Test Frequency |
|
||||
|------|---------|-----|-----|-----------------|----------------------|
|
||||
| 1 | 50 | 1hr | 4hr | Hourly inc/Daily full | Weekly |
|
||||
| 2 | 200 | 4hr | 12hr | 4hr inc/Daily full | Monthly |
|
||||
| 3 | 250 | 24hr | 48hr | Daily inc/Weekly full | Quarterly |
|
||||
```
|
||||
@@ -0,0 +1,122 @@
|
||||
# Ransomware Backup Strategy Assessment Template
|
||||
|
||||
## Organization Information
|
||||
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| Organization Name | |
|
||||
| Assessment Date | |
|
||||
| Assessor Name | |
|
||||
| Backup Solution | |
|
||||
| Number of Servers | |
|
||||
| Total Data Volume | |
|
||||
|
||||
## Current Backup Architecture
|
||||
|
||||
### Backup Copies Inventory
|
||||
|
||||
| Copy # | Location | Media Type | Offsite? | Immutable? | Air-Gapped? | Retention | Encrypted? | Last Successful |
|
||||
|--------|----------|------------|----------|------------|-------------|-----------|------------|-----------------|
|
||||
| 1 | | | | | | | | |
|
||||
| 2 | | | | | | | | |
|
||||
| 3 | | | | | | | | |
|
||||
|
||||
### 3-2-1-1-0 Compliance Checklist
|
||||
|
||||
- [ ] **3 Copies**: At least 3 copies of data exist
|
||||
- [ ] **2 Media Types**: Backups stored on at least 2 different media types
|
||||
- [ ] **1 Offsite**: At least 1 copy stored offsite or in a different geographic location
|
||||
- [ ] **1 Immutable/Air-Gapped**: At least 1 copy is immutable or physically air-gapped
|
||||
- [ ] **0 Errors**: Automated restore testing passes with zero errors
|
||||
|
||||
## Recovery Tier Classification
|
||||
|
||||
### Tier 1 - Critical Systems
|
||||
|
||||
| System | RPO Target | RTO Target | Backup Frequency | Dependencies |
|
||||
|--------|-----------|-----------|-------------------|--------------|
|
||||
| | | | | |
|
||||
|
||||
### Tier 2 - Important Systems
|
||||
|
||||
| System | RPO Target | RTO Target | Backup Frequency | Dependencies |
|
||||
|--------|-----------|-----------|-------------------|--------------|
|
||||
| | | | | |
|
||||
|
||||
### Tier 3 - Standard Systems
|
||||
|
||||
| System | RPO Target | RTO Target | Backup Frequency | Dependencies |
|
||||
|--------|-----------|-----------|-------------------|--------------|
|
||||
| | | | | |
|
||||
|
||||
## Credential Isolation Assessment
|
||||
|
||||
| Control | Status | Evidence |
|
||||
|---------|--------|----------|
|
||||
| Backup servers removed from production AD | Yes / No | |
|
||||
| Dedicated backup admin accounts | Yes / No | |
|
||||
| MFA enabled for backup console | Yes / No | |
|
||||
| Backup network segmented | Yes / No | |
|
||||
| RDP disabled on backup servers | Yes / No | |
|
||||
| Backup encryption keys stored separately | Yes / No | |
|
||||
|
||||
## Restore Testing History
|
||||
|
||||
| Date | Tier | Systems Tested | Result | RTO Achieved | Issues |
|
||||
|------|------|---------------|--------|-------------|--------|
|
||||
| | | | | | |
|
||||
|
||||
## Gap Analysis
|
||||
|
||||
| Control | Current State | Target State | Gap | Priority | Effort |
|
||||
|---------|--------------|-------------|-----|----------|--------|
|
||||
| Immutable backup | | | | | |
|
||||
| Credential isolation | | | | | |
|
||||
| Restore testing | | | | | |
|
||||
| Offsite copy | | | | | |
|
||||
| Encryption | | | | | |
|
||||
|
||||
## Recommendations
|
||||
|
||||
### Critical Priority
|
||||
|
||||
1. **[Finding]**: [Recommendation] - Estimated effort: [X days/weeks]
|
||||
|
||||
### High Priority
|
||||
|
||||
1. **[Finding]**: [Recommendation] - Estimated effort: [X days/weeks]
|
||||
|
||||
### Medium Priority
|
||||
|
||||
1. **[Finding]**: [Recommendation] - Estimated effort: [X days/weeks]
|
||||
|
||||
## Recovery Runbook Checklist
|
||||
|
||||
### Pre-Recovery
|
||||
- [ ] Incident declared and scope determined
|
||||
- [ ] Affected systems isolated from network
|
||||
- [ ] Backup integrity verified (immutable copies confirmed clean)
|
||||
- [ ] Backup timestamps verified to predate infection
|
||||
- [ ] Recovery environment prepared (clean network, fresh OS images)
|
||||
|
||||
### Recovery Execution
|
||||
- [ ] Phase 1: Identity infrastructure (AD, DNS, DHCP)
|
||||
- [ ] Phase 2: Tier 1 critical systems
|
||||
- [ ] Phase 3: Tier 2 important systems
|
||||
- [ ] Phase 4: Tier 3 standard systems
|
||||
- [ ] Each restored system validated before connecting to network
|
||||
|
||||
### Post-Recovery
|
||||
- [ ] All restored systems scanned for persistence mechanisms
|
||||
- [ ] Security controls validated (EDR, firewall rules, MFA)
|
||||
- [ ] Users notified and credentials reset
|
||||
- [ ] Recovery time documented against RTO targets
|
||||
- [ ] Lessons learned documented
|
||||
|
||||
## Sign-Off
|
||||
|
||||
| Role | Name | Signature | Date |
|
||||
|------|------|-----------|------|
|
||||
| IT Director | | | |
|
||||
| CISO | | | |
|
||||
| Backup Admin | | | |
|
||||
@@ -0,0 +1,58 @@
|
||||
# Standards & References - Ransomware Backup Strategy
|
||||
|
||||
## Industry Standards
|
||||
|
||||
### NIST SP 800-209: Security Guidelines for Storage Infrastructure
|
||||
- Defines security controls for storage systems including backup infrastructure
|
||||
- Covers access control, encryption, integrity verification, and audit logging for storage
|
||||
- Section 5.3: Backup and recovery security controls
|
||||
|
||||
### NIST IR 8374: Ransomware Risk Management
|
||||
- Identifies backup as a critical control in the Recover function
|
||||
- Recommends maintaining offline, encrypted backups with regular testing
|
||||
- Emphasizes credential separation for backup administration
|
||||
|
||||
### CISA #StopRansomware Guide (2023, updated 2025)
|
||||
- Prescribes 3-2-1 backup rule as baseline, recommends extending to 3-2-1-1-0
|
||||
- Mandates backup credential isolation from production domains
|
||||
- Requires documented and tested recovery procedures
|
||||
|
||||
### CIS Controls v8
|
||||
- Control 11: Data Recovery
|
||||
- 11.1: Establish and maintain a data recovery process
|
||||
- 11.2: Perform automated backups
|
||||
- 11.3: Protect recovery data (encryption, access control)
|
||||
- 11.4: Establish and maintain an isolated instance of recovery data (air-gapped/immutable)
|
||||
- 11.5: Test data recovery
|
||||
|
||||
### ISO 27001:2022
|
||||
- A.8.13: Information backup
|
||||
- A.8.14: Redundancy of information processing facilities
|
||||
|
||||
## Regulatory Requirements
|
||||
|
||||
### PCI DSS v4.0
|
||||
- Requirement 9.4.1: Backup media physically secured
|
||||
- Requirement 12.10.1: Incident response plan includes recovery procedures
|
||||
|
||||
### HIPAA Security Rule
|
||||
- 45 CFR 164.308(a)(7): Contingency plan including data backup, disaster recovery, emergency mode operation
|
||||
- 45 CFR 164.312(a)(2)(ii): Emergency access procedure
|
||||
|
||||
### SOX
|
||||
- Section 302/404: Internal controls over financial reporting must include IT controls for data backup and recovery
|
||||
|
||||
## Vendor Documentation
|
||||
|
||||
### Veeam
|
||||
- Hardened Repository Guide: https://helpcenter.veeam.com/docs/backup/vsphere/hardened_repository.html
|
||||
- SureBackup: https://helpcenter.veeam.com/docs/backup/vsphere/surebackup_job.html
|
||||
- Immutability: https://helpcenter.veeam.com/docs/backup/vsphere/immutability.html
|
||||
|
||||
### AWS
|
||||
- S3 Object Lock: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html
|
||||
- AWS Backup Vault Lock: https://docs.aws.amazon.com/aws-backup/latest/devguide/vault-lock.html
|
||||
|
||||
### Azure
|
||||
- Immutable Blob Storage: https://learn.microsoft.com/en-us/azure/storage/blobs/immutable-storage-overview
|
||||
- Azure Backup Immutable Vault: https://learn.microsoft.com/en-us/azure/backup/backup-azure-immutable-vault-concept
|
||||
@@ -0,0 +1,175 @@
|
||||
# Workflows - Ransomware Backup Strategy
|
||||
|
||||
## Workflow 1: Initial Backup Architecture Design
|
||||
|
||||
```
|
||||
Start
|
||||
|
|
||||
v
|
||||
[Inventory all systems and data] --> Classify into Tier 1/2/3 by business impact
|
||||
|
|
||||
v
|
||||
[Define RPO/RTO per tier] --> Document in recovery plan
|
||||
|
|
||||
v
|
||||
[Select backup platform] --> Veeam / Rubrik / Commvault / Cohesity
|
||||
|
|
||||
v
|
||||
[Design 3-2-1-1-0 architecture]
|
||||
|-- Copy 1: Local repository (fast restore)
|
||||
|-- Copy 2: Secondary site/cloud (different media)
|
||||
|-- Copy 3: Offsite (geographic separation)
|
||||
|-- +1: Immutable or air-gapped copy
|
||||
|-- +0: Automated restore verification
|
||||
|
|
||||
v
|
||||
[Isolate backup credentials]
|
||||
|-- Remove from production AD
|
||||
|-- Deploy MFA for backup admin access
|
||||
|-- Segment backup network
|
||||
|
|
||||
v
|
||||
[Configure immutable storage]
|
||||
|-- Linux Hardened Repository (XFS immutability)
|
||||
|-- S3 Object Lock / Azure Immutable Blob
|
||||
|-- Tape air-gap rotation
|
||||
|
|
||||
v
|
||||
[Set backup schedules per tier]
|
||||
|
|
||||
v
|
||||
[Configure automated restore testing]
|
||||
|-- SureBackup / SureReplica
|
||||
|-- Verify boot, network, application health
|
||||
|
|
||||
v
|
||||
[Document recovery runbook]
|
||||
|
|
||||
v
|
||||
End
|
||||
```
|
||||
|
||||
## Workflow 2: Restore Verification Process
|
||||
|
||||
```
|
||||
Start (Scheduled - Weekly for Tier 1, Monthly for Tier 2)
|
||||
|
|
||||
v
|
||||
[SureBackup job triggers VM restore to isolated sandbox]
|
||||
|
|
||||
v
|
||||
[VM boots in isolated network segment]
|
||||
|
|
||||
v
|
||||
[Heartbeat check] -- Fail --> Alert backup team
|
||||
|
|
||||
Pass
|
||||
|
|
||||
v
|
||||
[Network ping check] -- Fail --> Alert backup team
|
||||
|
|
||||
Pass
|
||||
|
|
||||
v
|
||||
[Application-specific check]
|
||||
|-- AD: LDAP query test
|
||||
|-- SQL: Database consistency check
|
||||
|-- Web: HTTP 200 response
|
||||
|-- Email: SMTP handshake
|
||||
|
|
||||
Fail --> Alert backup team with diagnostic details
|
||||
|
|
||||
Pass
|
||||
|
|
||||
v
|
||||
[Log successful restore] --> Update compliance dashboard
|
||||
|
|
||||
v
|
||||
[Clean up sandbox VMs]
|
||||
|
|
||||
v
|
||||
End
|
||||
```
|
||||
|
||||
## Workflow 3: Emergency Ransomware Recovery
|
||||
|
||||
```
|
||||
Ransomware Incident Declared
|
||||
|
|
||||
v
|
||||
[Isolate affected systems from network]
|
||||
|
|
||||
v
|
||||
[Verify backup integrity]
|
||||
|-- Check immutable copies are unaffected
|
||||
|-- Validate backup timestamps predate infection
|
||||
|-- Scan backup files for ransomware artifacts
|
||||
|
|
||||
v
|
||||
[Determine recovery scope]
|
||||
|-- Full environment rebuild vs. selective restore
|
||||
|-- Prioritize by tier: AD/DNS first, then Tier 1, then Tier 2/3
|
||||
|
|
||||
v
|
||||
[Rebuild infrastructure in clean environment]
|
||||
|-- Deploy clean OS images
|
||||
|-- Restore AD from immutable backup
|
||||
|-- Validate AD integrity with ADRestore/DSInternals
|
||||
|
|
||||
v
|
||||
[Restore applications in dependency order]
|
||||
|-- Database servers before application servers
|
||||
|-- Internal services before external-facing
|
||||
|
|
||||
v
|
||||
[Validate restored systems]
|
||||
|-- Application functionality testing
|
||||
|-- Data integrity verification
|
||||
|-- Security control validation
|
||||
|
|
||||
v
|
||||
[Reconnect to network in phases]
|
||||
|-- Monitor for re-infection indicators
|
||||
|-- Validate no persistence mechanisms in restored systems
|
||||
|
|
||||
v
|
||||
[Post-recovery documentation and lessons learned]
|
||||
|
|
||||
v
|
||||
End
|
||||
```
|
||||
|
||||
## Workflow 4: Backup Health Monitoring
|
||||
|
||||
```
|
||||
Daily Automated Check
|
||||
|
|
||||
v
|
||||
[Query backup job status via API/PowerShell]
|
||||
|
|
||||
v
|
||||
[Check for failed or warning jobs]
|
||||
|-- Failed --> Create P1 ticket, alert backup team
|
||||
|-- Warning --> Create P3 ticket, investigate within 24hr
|
||||
|-- Success --> Log and continue
|
||||
|
|
||||
v
|
||||
[Verify backup repository capacity]
|
||||
|-- >85% utilization --> Alert for capacity planning
|
||||
|-- >95% utilization --> Critical alert, backup jobs at risk
|
||||
|
|
||||
v
|
||||
[Check immutable copy synchronization]
|
||||
|-- Verify last immutable copy is within RPO window
|
||||
|-- Alert if immutable copy is stale
|
||||
|
|
||||
v
|
||||
[Generate weekly backup health report]
|
||||
|-- Success rate percentage
|
||||
|-- Data protected volume
|
||||
|-- Restore test results
|
||||
|-- Capacity forecast
|
||||
|
|
||||
v
|
||||
End
|
||||
```
|
||||
@@ -0,0 +1,582 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Ransomware Backup Strategy Assessment and Monitoring Tool
|
||||
|
||||
Audits backup infrastructure for ransomware resilience by checking:
|
||||
- 3-2-1-1-0 compliance (copies, media types, offsite, immutable, restore testing)
|
||||
- Backup credential isolation from production AD
|
||||
- Immutable storage configuration
|
||||
- Restore test history and success rates
|
||||
- RPO/RTO compliance per tier
|
||||
|
||||
Supports Veeam, AWS Backup, and Azure Backup via API integration.
|
||||
"""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import socket
|
||||
import ssl
|
||||
import datetime
|
||||
from dataclasses import dataclass, field, asdict
|
||||
from typing import Optional
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@dataclass
|
||||
class BackupCopy:
|
||||
location: str
|
||||
media_type: str
|
||||
is_offsite: bool
|
||||
is_immutable: bool
|
||||
is_airgapped: bool
|
||||
retention_days: int
|
||||
last_successful: Optional[str] = None
|
||||
encryption_algorithm: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RecoveryTier:
|
||||
name: str
|
||||
tier_level: int
|
||||
systems: list
|
||||
rpo_hours: float
|
||||
rto_hours: float
|
||||
backup_frequency: str
|
||||
restore_test_frequency: str
|
||||
last_restore_test: Optional[str] = None
|
||||
last_restore_result: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class BackupAssessment:
|
||||
organization: str
|
||||
assessment_date: str
|
||||
backup_solution: str
|
||||
copies: list = field(default_factory=list)
|
||||
tiers: list = field(default_factory=list)
|
||||
credential_isolation: dict = field(default_factory=dict)
|
||||
findings: list = field(default_factory=list)
|
||||
score: float = 0.0
|
||||
|
||||
|
||||
class BackupStrategyAuditor:
|
||||
"""Audits backup infrastructure for ransomware resilience."""
|
||||
|
||||
def __init__(self, org_name: str, backup_solution: str):
|
||||
self.assessment = BackupAssessment(
|
||||
organization=org_name,
|
||||
assessment_date=datetime.datetime.now().strftime("%Y-%m-%d"),
|
||||
backup_solution=backup_solution,
|
||||
)
|
||||
self.max_score = 0
|
||||
self.earned_score = 0
|
||||
|
||||
def add_backup_copy(self, copy: BackupCopy):
|
||||
self.assessment.copies.append(copy)
|
||||
|
||||
def add_recovery_tier(self, tier: RecoveryTier):
|
||||
self.assessment.tiers.append(tier)
|
||||
|
||||
def set_credential_isolation(
|
||||
self,
|
||||
domain_joined: bool,
|
||||
mfa_enabled: bool,
|
||||
separate_network: bool,
|
||||
rdp_disabled: bool,
|
||||
dedicated_admin_accounts: bool,
|
||||
):
|
||||
self.assessment.credential_isolation = {
|
||||
"domain_joined": domain_joined,
|
||||
"mfa_enabled": mfa_enabled,
|
||||
"separate_network": separate_network,
|
||||
"rdp_disabled": rdp_disabled,
|
||||
"dedicated_admin_accounts": dedicated_admin_accounts,
|
||||
}
|
||||
|
||||
def _add_finding(self, severity: str, category: str, title: str, detail: str, recommendation: str):
|
||||
self.assessment.findings.append({
|
||||
"severity": severity,
|
||||
"category": category,
|
||||
"title": title,
|
||||
"detail": detail,
|
||||
"recommendation": recommendation,
|
||||
})
|
||||
|
||||
def audit_321_10_compliance(self):
|
||||
"""Check compliance with the 3-2-1-1-0 backup rule."""
|
||||
copies = self.assessment.copies
|
||||
|
||||
# 3 - At least 3 copies
|
||||
self.max_score += 20
|
||||
if len(copies) >= 3:
|
||||
self.earned_score += 20
|
||||
else:
|
||||
self._add_finding(
|
||||
"CRITICAL", "3-2-1-1-0",
|
||||
f"Insufficient backup copies: {len(copies)} of 3 required",
|
||||
f"Only {len(copies)} backup copies configured. Minimum 3 required.",
|
||||
"Add additional backup copies to meet 3-2-1-1-0 minimum.",
|
||||
)
|
||||
|
||||
# 2 - At least 2 different media types
|
||||
self.max_score += 15
|
||||
media_types = set(c.media_type for c in copies)
|
||||
if len(media_types) >= 2:
|
||||
self.earned_score += 15
|
||||
else:
|
||||
self._add_finding(
|
||||
"HIGH", "3-2-1-1-0",
|
||||
f"Insufficient media diversity: {len(media_types)} type(s)",
|
||||
f"All backups use {media_types}. Need at least 2 different media types.",
|
||||
"Add backup copy on different media (e.g., tape, cloud object storage, SAN).",
|
||||
)
|
||||
|
||||
# 1 - At least 1 offsite copy
|
||||
self.max_score += 15
|
||||
offsite_copies = [c for c in copies if c.is_offsite]
|
||||
if offsite_copies:
|
||||
self.earned_score += 15
|
||||
else:
|
||||
self._add_finding(
|
||||
"CRITICAL", "3-2-1-1-0",
|
||||
"No offsite backup copy",
|
||||
"All backup copies are stored on-premises. A site-level disaster would destroy all copies.",
|
||||
"Configure at least one offsite backup copy (cloud, remote site, or tape vaulting).",
|
||||
)
|
||||
|
||||
# 1 - At least 1 immutable or air-gapped copy
|
||||
self.max_score += 25
|
||||
immutable_copies = [c for c in copies if c.is_immutable or c.is_airgapped]
|
||||
if immutable_copies:
|
||||
self.earned_score += 25
|
||||
else:
|
||||
self._add_finding(
|
||||
"CRITICAL", "3-2-1-1-0",
|
||||
"No immutable or air-gapped backup copy",
|
||||
"No backup copies are protected against modification or deletion. "
|
||||
"Ransomware operators routinely delete accessible backups.",
|
||||
"Deploy immutable storage (S3 Object Lock, Hardened Linux Repository) "
|
||||
"or air-gapped backup (tape with physical separation).",
|
||||
)
|
||||
|
||||
# 0 - Restore testing with zero errors
|
||||
self.max_score += 25
|
||||
if self.assessment.tiers:
|
||||
tested_tiers = [t for t in self.assessment.tiers if t.last_restore_result == "Success"]
|
||||
all_tiers = len(self.assessment.tiers)
|
||||
if len(tested_tiers) == all_tiers:
|
||||
self.earned_score += 25
|
||||
elif tested_tiers:
|
||||
partial_score = int(25 * len(tested_tiers) / all_tiers)
|
||||
self.earned_score += partial_score
|
||||
self._add_finding(
|
||||
"HIGH", "3-2-1-1-0",
|
||||
f"Incomplete restore testing: {len(tested_tiers)}/{all_tiers} tiers verified",
|
||||
f"Only {len(tested_tiers)} of {all_tiers} recovery tiers have successful restore tests.",
|
||||
"Implement automated restore testing (SureBackup) for all tiers.",
|
||||
)
|
||||
else:
|
||||
self._add_finding(
|
||||
"CRITICAL", "3-2-1-1-0",
|
||||
"No successful restore tests recorded",
|
||||
"No recovery tiers have documented successful restore verification.",
|
||||
"Implement automated restore testing immediately. Untested backups "
|
||||
"should be considered unreliable.",
|
||||
)
|
||||
|
||||
def audit_credential_isolation(self):
|
||||
"""Check backup credential isolation from production AD."""
|
||||
creds = self.assessment.credential_isolation
|
||||
if not creds:
|
||||
self._add_finding(
|
||||
"CRITICAL", "Credential Isolation",
|
||||
"Credential isolation not assessed",
|
||||
"No information provided about backup credential isolation.",
|
||||
"Assess backup admin account configuration and network isolation.",
|
||||
)
|
||||
return
|
||||
|
||||
self.max_score += 10
|
||||
if not creds.get("domain_joined", True):
|
||||
self.earned_score += 10
|
||||
else:
|
||||
self._add_finding(
|
||||
"CRITICAL", "Credential Isolation",
|
||||
"Backup servers joined to production AD domain",
|
||||
"Backup infrastructure is domain-joined. Ransomware operators compromise "
|
||||
"backup credentials via Kerberoasting, DCSync, or GPO manipulation.",
|
||||
"Remove backup servers from production AD. Use local accounts or a "
|
||||
"dedicated management domain.",
|
||||
)
|
||||
|
||||
self.max_score += 5
|
||||
if creds.get("mfa_enabled", False):
|
||||
self.earned_score += 5
|
||||
else:
|
||||
self._add_finding(
|
||||
"HIGH", "Credential Isolation",
|
||||
"MFA not enabled for backup administration",
|
||||
"Backup admin accounts do not require multi-factor authentication.",
|
||||
"Enable MFA for all backup console access using hardware tokens.",
|
||||
)
|
||||
|
||||
self.max_score += 5
|
||||
if creds.get("separate_network", False):
|
||||
self.earned_score += 5
|
||||
else:
|
||||
self._add_finding(
|
||||
"HIGH", "Credential Isolation",
|
||||
"Backup infrastructure not on separate network segment",
|
||||
"Backup servers share the production network segment.",
|
||||
"Segment backup infrastructure into a dedicated VLAN with strict firewall rules.",
|
||||
)
|
||||
|
||||
self.max_score += 3
|
||||
if creds.get("rdp_disabled", False):
|
||||
self.earned_score += 3
|
||||
else:
|
||||
self._add_finding(
|
||||
"MEDIUM", "Credential Isolation",
|
||||
"RDP enabled on backup servers",
|
||||
"Remote Desktop Protocol is accessible on backup servers.",
|
||||
"Disable RDP and use out-of-band management (iLO/iDRAC) for emergency access.",
|
||||
)
|
||||
|
||||
self.max_score += 2
|
||||
if creds.get("dedicated_admin_accounts", False):
|
||||
self.earned_score += 2
|
||||
else:
|
||||
self._add_finding(
|
||||
"HIGH", "Credential Isolation",
|
||||
"No dedicated backup admin accounts",
|
||||
"Backup administration uses shared or production admin accounts.",
|
||||
"Create dedicated backup admin accounts with least-privilege access.",
|
||||
)
|
||||
|
||||
def audit_rpo_rto_compliance(self):
|
||||
"""Check if backup frequency meets RPO targets and document RTO validation."""
|
||||
for tier in self.assessment.tiers:
|
||||
self.max_score += 5
|
||||
# Check if restore test is recent enough
|
||||
if tier.last_restore_test:
|
||||
try:
|
||||
last_test = datetime.datetime.strptime(tier.last_restore_test, "%Y-%m-%d")
|
||||
days_since_test = (datetime.datetime.now() - last_test).days
|
||||
|
||||
frequency_map = {
|
||||
"weekly": 7,
|
||||
"monthly": 30,
|
||||
"quarterly": 90,
|
||||
}
|
||||
expected_days = frequency_map.get(tier.restore_test_frequency.lower(), 30)
|
||||
|
||||
if days_since_test <= expected_days * 1.5:
|
||||
self.earned_score += 5
|
||||
else:
|
||||
self._add_finding(
|
||||
"HIGH", "RPO/RTO",
|
||||
f"Tier {tier.tier_level} ({tier.name}): Restore test overdue",
|
||||
f"Last test was {days_since_test} days ago. "
|
||||
f"Expected frequency: {tier.restore_test_frequency}.",
|
||||
f"Run restore test for {tier.name} tier immediately.",
|
||||
)
|
||||
except ValueError:
|
||||
self._add_finding(
|
||||
"MEDIUM", "RPO/RTO",
|
||||
f"Tier {tier.tier_level}: Invalid restore test date format",
|
||||
f"Date '{tier.last_restore_test}' could not be parsed.",
|
||||
"Use YYYY-MM-DD format for restore test dates.",
|
||||
)
|
||||
else:
|
||||
self._add_finding(
|
||||
"CRITICAL", "RPO/RTO",
|
||||
f"Tier {tier.tier_level} ({tier.name}): No restore test recorded",
|
||||
"No restore test has been documented for this recovery tier.",
|
||||
f"Implement {tier.restore_test_frequency} automated restore testing.",
|
||||
)
|
||||
|
||||
def audit_encryption(self):
|
||||
"""Check backup encryption configuration."""
|
||||
for copy in self.assessment.copies:
|
||||
self.max_score += 3
|
||||
if copy.encryption_algorithm:
|
||||
if copy.encryption_algorithm.upper() in ("AES-256", "AES256", "AES-256-GCM"):
|
||||
self.earned_score += 3
|
||||
else:
|
||||
self._add_finding(
|
||||
"MEDIUM", "Encryption",
|
||||
f"Weak backup encryption: {copy.encryption_algorithm}",
|
||||
f"Backup copy at {copy.location} uses {copy.encryption_algorithm}.",
|
||||
"Upgrade to AES-256 encryption for all backup copies.",
|
||||
)
|
||||
else:
|
||||
self._add_finding(
|
||||
"HIGH", "Encryption",
|
||||
f"Unencrypted backup: {copy.location}",
|
||||
f"Backup copy at {copy.location} is not encrypted.",
|
||||
"Enable AES-256 encryption for all backup copies, both at rest and in transit.",
|
||||
)
|
||||
|
||||
def audit_immutable_retention(self):
|
||||
"""Check immutable retention period against typical ransomware dwell time."""
|
||||
avg_dwell_time_days = 21 # Average ransomware dwell time
|
||||
|
||||
for copy in self.assessment.copies:
|
||||
if copy.is_immutable:
|
||||
self.max_score += 5
|
||||
if copy.retention_days > avg_dwell_time_days:
|
||||
self.earned_score += 5
|
||||
else:
|
||||
self._add_finding(
|
||||
"CRITICAL", "Immutable Retention",
|
||||
f"Immutable retention too short: {copy.retention_days} days",
|
||||
f"Immutable retention at {copy.location} is {copy.retention_days} days. "
|
||||
f"Average ransomware dwell time is {avg_dwell_time_days} days. "
|
||||
"Attackers may wait for immutability to expire.",
|
||||
f"Increase immutable retention to at least {avg_dwell_time_days * 2} days.",
|
||||
)
|
||||
|
||||
def run_full_audit(self) -> dict:
|
||||
"""Execute all audit checks and calculate overall score."""
|
||||
self.audit_321_10_compliance()
|
||||
self.audit_credential_isolation()
|
||||
self.audit_rpo_rto_compliance()
|
||||
self.audit_encryption()
|
||||
self.audit_immutable_retention()
|
||||
|
||||
if self.max_score > 0:
|
||||
self.assessment.score = round((self.earned_score / self.max_score) * 100, 1)
|
||||
|
||||
return asdict(self.assessment)
|
||||
|
||||
def generate_report(self) -> str:
|
||||
"""Generate human-readable assessment report."""
|
||||
result = self.run_full_audit()
|
||||
lines = []
|
||||
|
||||
lines.append("=" * 70)
|
||||
lines.append("RANSOMWARE BACKUP STRATEGY ASSESSMENT REPORT")
|
||||
lines.append("=" * 70)
|
||||
lines.append(f"Organization: {result['organization']}")
|
||||
lines.append(f"Date: {result['assessment_date']}")
|
||||
lines.append(f"Backup Solution: {result['backup_solution']}")
|
||||
lines.append(f"Overall Score: {result['score']}%")
|
||||
lines.append("")
|
||||
|
||||
# Score interpretation
|
||||
score = result["score"]
|
||||
if score >= 90:
|
||||
rating = "EXCELLENT - Ransomware-resilient backup architecture"
|
||||
elif score >= 75:
|
||||
rating = "GOOD - Minor gaps in ransomware resilience"
|
||||
elif score >= 50:
|
||||
rating = "FAIR - Significant gaps require remediation"
|
||||
else:
|
||||
rating = "POOR - Critical ransomware backup risks present"
|
||||
lines.append(f"Rating: {rating}")
|
||||
lines.append("")
|
||||
|
||||
# 3-2-1-1-0 Summary
|
||||
lines.append("-" * 40)
|
||||
lines.append("3-2-1-1-0 COMPLIANCE")
|
||||
lines.append("-" * 40)
|
||||
copies = result["copies"]
|
||||
lines.append(f"Total copies: {len(copies)} (minimum 3)")
|
||||
media_types = set(c["media_type"] for c in copies)
|
||||
lines.append(f"Media types: {', '.join(media_types)} ({len(media_types)} types, minimum 2)")
|
||||
offsite = sum(1 for c in copies if c["is_offsite"])
|
||||
lines.append(f"Offsite copies: {offsite} (minimum 1)")
|
||||
immutable = sum(1 for c in copies if c["is_immutable"] or c["is_airgapped"])
|
||||
lines.append(f"Immutable/Air-gapped copies: {immutable} (minimum 1)")
|
||||
lines.append("")
|
||||
|
||||
# Recovery Tiers
|
||||
lines.append("-" * 40)
|
||||
lines.append("RECOVERY TIERS")
|
||||
lines.append("-" * 40)
|
||||
for tier in result["tiers"]:
|
||||
lines.append(f" Tier {tier['tier_level']}: {tier['name']}")
|
||||
lines.append(f" Systems: {len(tier['systems'])}")
|
||||
lines.append(f" RPO: {tier['rpo_hours']}h | RTO: {tier['rto_hours']}h")
|
||||
lines.append(f" Backup: {tier['backup_frequency']}")
|
||||
lines.append(f" Restore test: {tier['restore_test_frequency']} "
|
||||
f"(Last: {tier['last_restore_test'] or 'Never'}, "
|
||||
f"Result: {tier['last_restore_result'] or 'N/A'})")
|
||||
lines.append("")
|
||||
|
||||
# Credential Isolation
|
||||
lines.append("-" * 40)
|
||||
lines.append("CREDENTIAL ISOLATION")
|
||||
lines.append("-" * 40)
|
||||
creds = result["credential_isolation"]
|
||||
for key, val in creds.items():
|
||||
status = "PASS" if (val if key != "domain_joined" else not val) else "FAIL"
|
||||
lines.append(f" {key}: {'Yes' if val else 'No'} [{status}]")
|
||||
lines.append("")
|
||||
|
||||
# Findings
|
||||
lines.append("-" * 40)
|
||||
lines.append(f"FINDINGS ({len(result['findings'])} total)")
|
||||
lines.append("-" * 40)
|
||||
severity_order = {"CRITICAL": 0, "HIGH": 1, "MEDIUM": 2, "LOW": 3, "INFO": 4}
|
||||
sorted_findings = sorted(result["findings"], key=lambda f: severity_order.get(f["severity"], 5))
|
||||
|
||||
for i, finding in enumerate(sorted_findings, 1):
|
||||
lines.append(f"\n [{finding['severity']}] #{i}: {finding['title']}")
|
||||
lines.append(f" Category: {finding['category']}")
|
||||
lines.append(f" Detail: {finding['detail']}")
|
||||
lines.append(f" Recommendation: {finding['recommendation']}")
|
||||
|
||||
lines.append("")
|
||||
lines.append("=" * 70)
|
||||
lines.append("END OF REPORT")
|
||||
lines.append("=" * 70)
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def check_veeam_api(server: str, port: int = 9419) -> dict:
|
||||
"""Check Veeam Backup & Replication API availability."""
|
||||
result = {"reachable": False, "tls": False, "api_version": None}
|
||||
try:
|
||||
sock = socket.create_connection((server, port), timeout=5)
|
||||
context = ssl.create_default_context()
|
||||
context.check_hostname = False
|
||||
context.verify_mode = ssl.CERT_NONE
|
||||
ssock = context.wrap_socket(sock, server_hostname=server)
|
||||
result["reachable"] = True
|
||||
result["tls"] = True
|
||||
ssock.close()
|
||||
except (socket.timeout, ConnectionRefusedError, OSError):
|
||||
try:
|
||||
sock = socket.create_connection((server, port), timeout=5)
|
||||
result["reachable"] = True
|
||||
sock.close()
|
||||
except (socket.timeout, ConnectionRefusedError, OSError):
|
||||
pass
|
||||
return result
|
||||
|
||||
|
||||
def check_s3_object_lock(bucket_name: str) -> dict:
|
||||
"""Check AWS S3 bucket for Object Lock configuration."""
|
||||
result = {"bucket": bucket_name, "object_lock_enabled": False, "retention_mode": None, "retention_days": None}
|
||||
try:
|
||||
output = subprocess.run(
|
||||
["aws", "s3api", "get-object-lock-configuration", "--bucket", bucket_name],
|
||||
capture_output=True, text=True, timeout=30,
|
||||
)
|
||||
if output.returncode == 0:
|
||||
config = json.loads(output.stdout)
|
||||
lock_config = config.get("ObjectLockConfiguration", {})
|
||||
result["object_lock_enabled"] = lock_config.get("ObjectLockEnabled") == "Enabled"
|
||||
rule = lock_config.get("Rule", {}).get("DefaultRetention", {})
|
||||
result["retention_mode"] = rule.get("Mode")
|
||||
result["retention_days"] = rule.get("Days")
|
||||
except (subprocess.TimeoutExpired, FileNotFoundError, json.JSONDecodeError):
|
||||
pass
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
"""Run example backup strategy assessment."""
|
||||
auditor = BackupStrategyAuditor(
|
||||
org_name="Example Financial Services",
|
||||
backup_solution="Veeam Backup & Replication 12",
|
||||
)
|
||||
|
||||
# Define backup copies
|
||||
auditor.add_backup_copy(BackupCopy(
|
||||
location="On-premises NAS (Building A)",
|
||||
media_type="NAS/NFS",
|
||||
is_offsite=False,
|
||||
is_immutable=False,
|
||||
is_airgapped=False,
|
||||
retention_days=14,
|
||||
last_successful="2026-02-22",
|
||||
encryption_algorithm="AES-256",
|
||||
))
|
||||
|
||||
auditor.add_backup_copy(BackupCopy(
|
||||
location="Veeam Hardened Linux Repository",
|
||||
media_type="Linux/XFS",
|
||||
is_offsite=False,
|
||||
is_immutable=True,
|
||||
is_airgapped=False,
|
||||
retention_days=30,
|
||||
last_successful="2026-02-22",
|
||||
encryption_algorithm="AES-256",
|
||||
))
|
||||
|
||||
auditor.add_backup_copy(BackupCopy(
|
||||
location="AWS S3 (us-west-2) Object Lock",
|
||||
media_type="Cloud Object Storage",
|
||||
is_offsite=True,
|
||||
is_immutable=True,
|
||||
is_airgapped=False,
|
||||
retention_days=60,
|
||||
last_successful="2026-02-22",
|
||||
encryption_algorithm="AES-256",
|
||||
))
|
||||
|
||||
# Define recovery tiers
|
||||
auditor.add_recovery_tier(RecoveryTier(
|
||||
name="Critical",
|
||||
tier_level=1,
|
||||
systems=["DC01", "DC02", "DNS01", "ERP-DB", "CoreBanking"],
|
||||
rpo_hours=1,
|
||||
rto_hours=4,
|
||||
backup_frequency="Hourly incremental, Daily full",
|
||||
restore_test_frequency="weekly",
|
||||
last_restore_test="2026-02-20",
|
||||
last_restore_result="Success",
|
||||
))
|
||||
|
||||
auditor.add_recovery_tier(RecoveryTier(
|
||||
name="Important",
|
||||
tier_level=2,
|
||||
systems=["Exchange", "FileServer01", "WebApp01", "SharePoint"],
|
||||
rpo_hours=4,
|
||||
rto_hours=12,
|
||||
backup_frequency="4-hour incremental, Daily full",
|
||||
restore_test_frequency="monthly",
|
||||
last_restore_test="2026-02-01",
|
||||
last_restore_result="Success",
|
||||
))
|
||||
|
||||
auditor.add_recovery_tier(RecoveryTier(
|
||||
name="Standard",
|
||||
tier_level=3,
|
||||
systems=["DevServer01", "TestDB", "ArchiveNAS"],
|
||||
rpo_hours=24,
|
||||
rto_hours=48,
|
||||
backup_frequency="Daily incremental, Weekly full",
|
||||
restore_test_frequency="quarterly",
|
||||
last_restore_test="2025-12-15",
|
||||
last_restore_result="Success",
|
||||
))
|
||||
|
||||
# Set credential isolation status
|
||||
auditor.set_credential_isolation(
|
||||
domain_joined=False,
|
||||
mfa_enabled=True,
|
||||
separate_network=True,
|
||||
rdp_disabled=True,
|
||||
dedicated_admin_accounts=True,
|
||||
)
|
||||
|
||||
# Generate and print report
|
||||
report = auditor.generate_report()
|
||||
print(report)
|
||||
|
||||
# Export JSON for integration
|
||||
result = auditor.run_full_audit()
|
||||
output_path = Path(__file__).parent / "assessment_result.json"
|
||||
with open(output_path, "w") as f:
|
||||
json.dump(result, f, indent=2)
|
||||
print(f"\nJSON report saved to: {output_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user