Categories
Database Backup

** Learn how to protect enterprise database archives from ransomware using immutable storage. Discover technical implementation steps for AWS S3 Object Lock, ZFS, PostgreSQL, and SQL Server.

현대의 위협 환경에서 랜섬웨어는 기회주의적인 암호화에서 고도로 표적화된 다중 갈취 캠페인으로 진화했습니다. 지능형 지속 위협(APT) 그룹과 랜섬웨어 조직은 이제 침투 기간 동안 백업 인프라와 데이터베이스 아카이브를 적극적으로 사냥합니다. 공격자가 기본 데이터베이스를 손상시키고 동시에 백업 저장소를 삭제하거나 암호화하면 조직은 치명적인 데이터 손실에 직면하게 됩니다.

데이터베이스 관리자(DBA)와 DevOps 엔지니어에게 기존의 3-2-1 백업 전략은 더 이상 충분하지 않습니다. 데이터 생존성을 보장하기 위해 인프라 팀은 마지막 ‘1’이 불변 스토리지(Immutable Storage)를 의미하는 3-2-1-1 규칙을 채택해야 합니다.

이 기사에서는 절대적인 랜섬웨어 복원력을 보장하기 위해 데이터베이스 아카이브용 불변 스토리지를 설계, 구현 및 관리하는 방법에 대한 포괄적이고 기술적인 심층 분석을 제공합니다.

불변 스토리지의 메커니즘

불변 스토리지는 WORM(Write-Once-Read-Many, 한 번 기록하여 여러 번 읽기) 아키텍처를 기반으로 합니다. 데이터가 불변 대상에 기록되면 수학적으로 강제된 시간 잠금이 만료될 때까지 루트 권한을 가진 관리자나 손상된 서비스 계정을 포함한 그 누구도 수정, 암호화 또는 삭제할 수 없습니다.

규정 준수 모드(Compliance Mode) vs. 거버넌스 모드(Governance Mode)

특히 AWS S3, Azure Blob 또는 S3 호환 온프레미스 SAN과 같은 클라우드 객체 스토리지에서 불변성을 구현할 때는 보존 모드 간의 차이를 이해해야 합니다.

  • 거버넌스 모드: 일반 사용자가 객체를 삭제하거나 변경하는 것을 방지합니다. 그러나 특정 IAM 권한(예: s3:BypassGovernanceRetention)을 가진 사용자는 잠금을 무시할 수 있습니다. 이는 테스트에는 유용하지만, 공격자가 도메인 관리자나 루트 권한으로 권한을 상승시키는 경우가 많기 때문에 랜섬웨어 보호에는 불충분합니다.
  • 규정 준수 모드: 랜섬웨어 방어를 위한 골드 표준입니다. 객체가 규정 준수 모드로 잠기면 보존 기간을 단축할 수 없으며 AWS 루트 계정을 포함한 그 누구도 객체를 삭제할 수 없습니다. 잠금은 스토리지 클러스터 수준에서 강제됩니다.

불변 백업 파이프라인 설계

강력한 데이터베이스 아카이빙 아키텍처는 활성 데이터베이스 작업과 불변 아카이브 계층을 분리합니다. 데이터베이스는 지속적인 읽기/쓰기 액세스가 필요하므로 활성 데이터베이스 파일(SQL Server의 .mdf/.ldf 또는 PostgreSQL의 pg_data 디렉토리 등)에는 불변성을 적용할 수 없습니다.

대신 불변성은 다음 항목에 적용됩니다:
1. 전체 및 차등 백업 파일: 데이터베이스의 기준 스냅샷.
2. 트랜잭션 로그 / WAL 파일: 특정 시점 복구(PITR)에 필요한 데이터베이스 변경 사항의 연속 스트림.

불변성을 위한 스토리지 대상

다양한 인프라 계층에서 불변 스토리지를 구현할 수 있습니다:
* 클라우드 객체 스토리지: AWS S3 Object Lock, Azure Blob Immutable Storage, Google Cloud Storage Retention Policies.
* 온프레미스 객체 스토리지: S3 Object Lock API를 지원하는 MinIO, Cloudian 또는 Pure Storage FlashBlade.
* 블록/파일 스토리지: 읽기 전용 스냅샷과 위임된 관리가 포함된 ZFS 또는 Linux 파일 속성.

불변 스토리지 구현: 기술적 단계

1. 클라우드 객체 스토리지: AWS S3 Object Lock

AWS에서 데이터베이스 덤프와 트랜잭션 로그를 보호하려면 버킷 생성 시점에 Object Lock을 활성화해야 합니다.

먼저 Object Lock이 활성화된 버킷을 생성합니다:

aws s3api create-bucket 
    --bucket prod-db-archive-immutable 
    --region us-east-1 
    --object-lock-enabled-for-bucket

다음으로 기본 보존 정책을 구성합니다. 데이터베이스 아카이브의 경우 30일 규정 준수 잠금이 표준 기준이며, 이를 통해 한 달 분량의 변경 불가능한 백업을 확보할 수 있습니다.

aws s3api put-object-lock-configuration 
    --bucket prod-db-archive-immutable 
    --object-lock-configuration '{
        "ObjectLockEnabled": "Enabled",
        "Rule": {
            "DefaultRetention": {
                "Mode": "COMPLIANCE",
                "Days": 30
            }
        }
    }'

데이터베이스 백업 스크립트나 에이전트가 이 버킷으로 파일을 푸시하면 S3는 객체 생성 타임스탬프에 30일을 더하여 Retain Until Date(보존 만료일)를 자동으로 계산합니다.

2. 온프레미스 불변성: ZFS 및 Linux 속성

데이터베이스를 온프레미스 Linux 백업 서버에 아카이빙하는 경우 chattr 명령을 사용하여 의사 불변성(pseudo-immutability)을 달성하거나, ZFS 스냅샷을 사용하여 진정한 불변성을 달성할 수 있습니다.

Linux chattr 사용:
+i (immutable) 플래그는 파일 수정, 삭제 또는 이름 변경을 방지합니다.

# 데이터베이스 덤프
pg_dump -U postgres -Fc mydb > /backups/mydb_$(date +%F).dump

# 백업을 불변으로 설정
sudo chattr +i /backups/mydb_$(date +%F).dump

# 속성 확인
lsattr /backups/mydb_$(date +%F).dump
# 출력: ----i---------e------- /backups/mydb_2023-10-27.dump

참고: chattr은 기본적인 랜섬웨어 스크립트를 막을 수 있지만, 루트 권한을 가진 정교한 공격자는 단순히 chattr -i를 실행할 수 있습니다. 따라서 이를 엄격한 RBAC 및 격리된 백업 네트워크와 결합해야 합니다.

ZFS 스냅샷 사용:
ZFS는 훨씬 더 강력한 방어를 제공합니다. 스냅샷을 찍고 그 위에 “hold(보류)”를 설정하면 스냅샷이 삭제되는 것을 방지할 수 있습니다.

# 백업 데이터셋의 스냅샷 생성
zfs snapshot tank/db_backups@archive_$(date +%F)

# 삭제 방지를 위해 스냅샷에 보류 설정
zfs hold keep_30_days tank/db_backups@archive_$(date +%F)

# 루트 사용자라도 보류를 해제하지 않으면 이 스냅샷을 삭제할 수 없음
zfs destroy tank/db_backups@archive_$(date +%F)
# 출력: cannot destroy 'tank/db_backups@archive_...': dataset is busy

데이터베이스별 아카이빙 전략

특정 시점 복구(PITR)를 달성하려면 트랜잭션 로그를 불변 스토리지에 지속적으로 아카이빙해야 합니다.

pgBackRest를 사용한 PostgreSQL WAL 아카이빙

pgBackRest는 S3 호환 스토리지를 기본적으로 지원하는 매우 신뢰할 수 있는 PostgreSQL용 백업 도구입니다. WAL(Write-Ahead Logs)을 보호하려면 pgBackRest가 불변 S3 버킷으로 직접 푸시하도록 구성하십시오.

pgbackrest.conf 설정 예시:

[global]
repo1-type=s3
repo1-s3-bucket=prod-db-archive-immutable
repo1-s3-region=us-east-1
repo1-s3-endpoint=s3.amazonaws.com
repo1-s3-key=AKIAIOSFODNN7EXAMPLE
repo1-s3-key-secret=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

# 보존 기간이 S3 Object Lock 구성과 일치하는지 확인
repo1-retention-full=2
repo1-retention-archive=2

[prod_cluster]
pg1-path=/var/lib/postgresql/14/main

중요 고려 사항: S3 버킷이 30일 규정 준수 잠금을 강제하는데 pgBackRestrepo1-retention-archive 설정에 따라 14일 후에 WAL 파일을 만료 및 삭제하려고 시도하면 삭제 API 호출이 실패합니다. 백업 소프트웨어의 보존 정책이 스토리지 수준의 불변 잠금 기간보다 크거나 같도록 설정해야 합니다.

Microsoft SQL Server: URL로 백업

SQL Server는 S3 호환 객체 스토리지로 직접 백업하는 기능을 기본적으로 지원합니다. SQL Server 에이전트 작업을 구성하여 .bak.trn 파일을 불변 버킷에 직접 기록할 수 있습니다.

CREATE CREDENTIAL [s3://prod-db-archive-immutable.s3.us-east-1.amazonaws.com]
WITH IDENTITY = 'S3 Access Key',
SECRET = 'AccessKeyID:SecretAccessKey';
GO

BACKUP DATABASE [ProductionDB]
TO URL = 's3://prod-db-archive-immutable.s3.us-east-1.amazonaws.com/ProductionDB_Full.bak'
WITH FORMAT, COMPRESSION, STATS = 10;
GO

CloudSave를 통한 자동화 및 오케스트레이션

사용자 지정 스크립트를 통해 불변 보존 플래그를 관리하고, 액세스 키를 순환하며, 데이터베이스 보존 정책과 스토리지 잠금 간의 동기화를 보장하는 작업은 오류가 발생하기 쉽습니다. 크론 작업이나 API 호출에서 단 한 번의 잘못된 구성만으로도 아카이브가 노출되거나, 고아(orphaned) 상태로 잠긴 객체로 인해 클라우드 스토리지 비용이 급증할 수 있습니다.

CloudSave와 같은 엔터프라이즈 백업 플랫폼은 이러한 아키텍처를 단순화합니다. CloudSave는 AWS S3 Object Lock, Azure Blob Immutable Storage 및 온프레미스 S3 호환 API와 기본적으로 통합됩니다.

CloudSave에서 데이터베이스 백업 계획을 구성할 때:
1. 플랫폼은 SQL Server의 VSS(Volume Shadow Copy Service) 정지 또는 PostgreSQL의 pg_start_backup() API를 자동으로 처리합니다.
2. 중복 제거 및 암호화된 백업 데이터를 스토리지 대상으로 직접 스트리밍합니다.
3. CloudSave는 객체별로 WORM API 호출(예: PutObjectRetention)을 동적으로 적용하여 스토리지 잠금 기간을 정책에 정의된 보존 일정과 완벽하게 일치시킵니다.
4. 공격자가 CloudSave 관리 콘솔을 손상시키더라도 규정 준수 잠금은 백업 소프트웨어가 아닌 기본 스토리지 인프라에 의해 강제되므로 백업을 삭제할 수 없습니다.

불변 데이터베이스 아카이브를 위한 모범 사례

불변 아키텍처의 진정한 복원력을 보장하려면 다음 시스템 엔지니어링 모범 사례를 준수하십시오:

1. 엄격한 NTP 동기화

불변 잠금은 수학적으로 타임스탬프에 묶여 있습니다. 스토리지 어레이나 백업 서버의 NTP(Network Time Protocol) 서비스가 손상되거나 시간이 어긋나면 잠금이 조기에 만료되거나 아예 만료되지 않을 수 있습니다. 스토리지 인프라가 인증된 중복 NTP 소스를 사용하도록 하십시오.

2. IAM 역할 및 자격 증명 격리

불변 버킷에 기록하는 데 사용되는 자격 증명에는 s3:PutObjects3:PutObjectRetention 권한만 있어야 합니다. s3:DeleteObject 또는 s3:PutBucketObjectLockConfiguration 권한은 절대 부여해서는 안 됩니다.

데이터베이스 백업 에이전트를 위한 최소 권한 IAM 정책 예시:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetBucketObjectLockConfiguration"
            ],
            "Resource": [
                "arn:aws:s3:::prod-db-archive-immutable",
                "arn:aws:s3:::prod-db-archive-immutable/*"
            ]
        }
    ]
}

3. 보존 기간 설정

기본적인 빠른 복구 계층에 너무 긴 기간(예: 규정 준수를 위한 7년) 동안 규정 준수 잠금을 설정하지 마십시오. 데이터베이스는 방대한 양의 WAL/트랜잭션 로그 데이터를 생성합니다. 이 데이터를 수년간 잠그면 스토리지 비용이 기하급수적으로 증가합니다.
대신 계층화된 접근 방식을 사용하십시오:
* 운영 복구 계층: 전체 백업 및 로그에 대해 14~30일의 불변 보존.
* 장기 아카이브 계층: Vault Lock을 사용하여 1~7년 동안 Glacier/Deep Archive로 이동된 월간 전체 백업.

4. 에어갭(Air-gapped) VPC에서의 정기적인 복구 테스트

불변성은 데이터가 삭제되지 않음을 보장하지만, 데이터에 논리적 손상이 없음을 보장하지는 않습니다. 불변 데이터베이스 아카이브를 격리된 에어갭 VPC 또는 VLAN으로 복원하는 과정을 자동화해야 합니다. 복원된 데이터에 대해 DBCC CHECKDB(SQL Server) 또는 pg_amcheck(PostgreSQL)를 실행하여 구조적 무결성을 확인하십시오.

결론

랜섬웨어 방어는 침해를 가정하는 것에서 시작됩니다. SIEM에서 경고가 발생할 때쯤이면 위협 행위자는 이미 백업 인프라를 손상시키려 시도했을 가능성이 높습니다. 규정 준수 모드에서 불변 스토리지를 사용하여 데이터베이스 아카이브를 설계함으로써 공격자의 주요 레버리지를 제거할 수 있습니다. 기본 클라우드 API, ZFS 보류 또는 CloudSave와 같은 엔터프라이즈 오케스트레이션 플랫폼 중 무엇을 사용하든 WORM 스토리지 구현은 이제 선택 사항이 아니라 현대 데이터베이스 관리 및 재해 복구의 필수 기둥입니다.