로깅 데이터 내보내기 시나리오: 보안 및 액세스 분석

이 시나리오에서는 조직의 클라우드 인프라 환경의 보안 및 분석 요구사항을 충족하기 위해 Cloud Logging에서 BigQuery로 로그를 내보내는 방법을 보여줍니다. 조직은 종종 분석 도구를 사용하여 승인되지 않은 구성 변경과 데이터에 대한 부적절한 액세스를 식별합니다. 이러한 보안 및 분석 요구사항을 충족하는 데 도움이 되도록 Cloud Logging은 관리자 활동 로그와 데이터 액세스 로그라는 두 가지 유형의 감사 로그를 캡처 할 수 있습니다.

이 시나리오에서 내보낸 로그는 내보내기 중에 구성하는 BigQuery의 데이터세트로 전달됩니다. 로그 액세스를 제한하기 위해 필요에 따라 권한을 부여합니다. 내보낸 데이터를 날짜 분할 테이블로 정리하여 데이터 관리 및 쿼리를 단순화할 수 있습니다. 이러한 접근 방법은 쿼리 중에 스캔되는 데이터 양을 줄임으로써 쿼리 비용을 낮추는 데 도움이 될 수 있습니다. 파티션 나누기가 가진 장점 중 하나는 파티션에 대해 만료일을 설정하여 필요한 기간 동안만 로깅 데이터를 유지할 수 있다는 것입니다. 예를 들어 감사 로깅 데이터를 3년 동안 유지하고 이후에는 삭제할 수 있습니다.

이 시나리오는 Cloud Logging 내보내기를 위한 설계 패턴 시리즈의 일부입니다.

로깅 내보내기 설정

다음 다이어그램은 BigQuery로 로깅 내보내기를 사용 설정하는 단계를 보여줍니다.

  • BigQuery에서 로깅 내보내기 데이터세트를 설정합니다.
  • 모든 Google Cloud 서비스에 감사 로깅을 사용 설정합니다.
  • 로깅 내보내기 구성
  • BigQuery 데이터세트에 대한 IAM 정책 권한 설정

BigQuery에 로그 내보내기 사용 설정

BigQuery에서 데이터세트 설정

내보낸 로그를 호스팅하는 데이터세트 설정 안내를 따릅니다. 집계된 로그를 사용하는 경우 BigQuery 데이터세트가 조직 내 Google Cloud 프로젝트 중 하나에 있어야 합니다. 단일 프로젝트를 위한 로그 내보내기를 사용하는 경우 BigQuery 데이터세트가 동일한 프로젝트에 있어야 합니다.

권장사항: 테이블을 생성할 때 로깅 내보내기 스토리지 크기 및 시간 경과에 따른 누적 스토리지 비용을 제한하기 위해 파티션 만료를 설정합니다.

모든 서비스에 감사 로깅 적용

데이터 액세스 감사 로그는 BigQuery를 제외하고 기본적으로 사용 중지되어 있습니다. 모든 감사 로그를 사용 설정하려면 감사 정책 문서에 나와 있는 구성으로 IAM 정책을 업데이트하는 방법 안내를 따르세요. 그 절차는 다음과 같습니다.

  • 현재 IAM 정책을 파일로 다운로드
  • 감사 로그 정책 JSON 또는 YAML 객체를 현재 정책 파일에 추가
  • 업데이트된 정책 파일로 프로젝트 업데이트

다음은 모든 서비스의 모든 감사 로그를 사용 설정하는 JSON 객체의 예입니다.

"auditConfigs": [
    {
        "service": "allServices",
        "auditLogConfigs": [
            { "logType": "ADMIN_READ" },
            { "logType": "DATA_READ"  },
            { "logType": "DATA_WRITE" },
        ]
    },
]

로깅 내보내기 구성

집계된 내보내기 또는 로그 내보내기를 설정한 후에는 감사 로그를 내보내도록 로깅 필터를 세분화해야 합니다. 다음 로깅 필터에는 관리자 활동 및 데이터 액세스 감사 로그와 특정 리소스 유형에 대한 로그가 포함되어 있습니다.

logName:"/logs/cloudaudit.googleapis.com" OR
resource.type:gce OR
resource.type=gcs_bucket OR
resource.type=cloudsql_database OR
resource.type=bigquery_resource

gcloud 명령줄 도구에서 gcloud logging sinks create 명령어 또는 organizations.sinks.create API 호출을 사용하여 적절한 필터로 싱크를 만듭니다. 아래의 gcloud 예시 명령어는 조직에 gcp_logging_sink_gcs라는 싱크를 만듭니다. 이 싱크는 모든 하위 프로젝트를 포함하며 특정 감사 로그를 선택하기 위한 필터링을 지정합니다.

gcloud logging sinks create gcp_logging_sink_bq22 \
     bigquery.googleapis.com/projects/compliance-logging-export/datasets/gcp_logging_export \
     --log-filter='logName:"/logs/cloudaudit.googleapis.com"' \
     --include-children \
     --organization=324989855333

명령어 결과는 다음과 비슷합니다.

Created [https://logging.googleapis.com/v2/organizations/324989855333/sinks/gcp_logging_sink_bq].
Please remember to grant `serviceAccount:gcp-logging-sink-bq@logging-o324989855333.iam.gserviceaccount.com` the WRITER role on the dataset..
More information about sinks can be found at /logging/docs/export/configure_export

API 호출에서 반환된 serviceAccount 항목에서 gcp-logging-sink-bq@logging-o324989855333.iam.gserviceaccount.com이라는 ID가 응답에 포함되어 있습니다. 이 ID는 내보내기를 위해 생성된 Google Cloud 서비스 계정을 나타냅니다. 이 ID에 대상에 대한 쓰기 액세스 권한을 부여할 때까지는 이 싱크의 로그 항목 내보내기가 실패합니다. 자세한 내용은 다음 섹션 또는 BigQuery 데이터세트에 필요한 권한을 참조하세요.

BigQuery 데이터세트에 대한 IAM 정책 권한 설정

편집자 권한이있는 gcp_logging_export 데이터세트에 서비스 계정 gcp-logging-sink-bq@logging-o324989855333.iam.gserviceaccount.com을 추가하면 서비스 계정에 대상에 쓸 수 있는 권한이 부여됩니다. 이러한 권한을 추가할 때까지는 싱크 내보내기가 실패합니다.

서비스 계정에 이 권한을 추가하려면 다음 단계를 따르세요.

  1. Cloud Console에서 BigQuery로 이동합니다.

    BigQuery로 이동

  2. gcp_logging_export 데이터세트 옆의 를 클릭한 다음 데이터세트 공유를 클릭합니다.

  3. 사용자 추가 필드에 서비스 계정을 입력합니다.

    IAM 정책 권한 - 편집자

이 필터를 사용하여 로깅 내보내기를 만든 후에는 구성된 프로젝트에서 BigQuery 데이터세트가 로그 파일로 채워집니다.

권장사항: 니즈에 따라 최소 권한 정책을 구현합니다. 특정 Google Cloud 사용자 계정, Google 그룹스 또는 Google Cloud 서비스 계정을 기반으로 데이터세트 권한을 구성할 수 있습니다. IAM 권한을 사용하여 BigQuery 데이터세트에 대한 액세스 권한을 부여합니다.

예제 권한 집합으로 다음을 수행할 수 있습니다.

  • BigQuery 데이터세트 권한에서 중요하지 않은 모든 사용자를 삭제합니다.
  • BigQuery 관리자에게 전체 권한을 추가합니다.
  • 내보내기 사용자에게 내보내기 로그를 쓸 수 있는 권한을 부여합니다.
  • 다른 개별 사용자에게 Google Cloud 로깅 내보내기에 대한 뷰어 액세스 권한을 부여합니다.

gsutil 명령줄 유틸리티 또는 IAM API를 통해 Cloud Console에서 직접 데이터 세트에 대해 IAM 권한을 업데이트할 수 있습니다.

내보낸 로그 사용

로그를 BigQuery 데이터세트로 내보내면 Cloud Logging은 내보낸 로그 항목을 보관할 날짜가 지정된 테이블을 만듭니다. 로그 항목은 항목의 로그 이름과 일치하는 테이블에 배치됩니다.

날짜가 지정된 테이블

다음 샘플에 표시된 것처럼 테이블 목록에는 YYYYMMDD 서픽스가 표시됩니다.

테이블 목록

내보낸 로그는 감사 로그이므로 관리자 활동 및 데이터 액세스 로그는 protoPayload 형식을 사용하여 BigQuery에 로드됩니다.

외부 액세스 권한 부여

특정 사용자에게 내보낸 로그에 대한 액세스 권한(예: 보안 분석가, DevOps 팀, 감사자)을 부여할 수 있습니다. BigQuery는 로그에 보안 액세스 권한을 부여할 수 있는 여러 옵션을 제공합니다.

로그 위치 전략

BigQuery에서는 여러 옵션에 따라 사용자에게 표시할 로그를 선택할 수 있습니다.

  • 공유할 로그 복사본을 만듭니다.

    수동으로 또는 프로그래매틱 방식으로 개별 로그 테이블 복사본 또는 로그 테이블 집합을 만들고, 복사본을 개별 BigQuery 데이터세트에 배치합니다. 그런 후 필요에 따라 개별 BigQuery 데이터세트 권한을 사용해서 로그를 특정 사용자와 공유합니다.

    장점: 복사된 데이터에만 노출되는 데이터의 양을 제한할 수 있습니다.

    단점: 별도의 데이터세트와 권한을 생성, 공유, 관리해야 하므로 비용이 높아질 수 있습니다.

  • 모든 로그에 읽기 전용 액세스 권한을 부여합니다.

    수동으로 또는 프로그래매틱 방식으로 BigQuery 로깅 내보내기 테이블에 대한 뷰어 권한을 설정하여, 모든 로그 내보내기에 대한 액세스 권한을 부여합니다.

    장점: 액세스 권한 부여가 쉽습니다.

    단점: 특정 로그 파일이 아닌 모든 로그에 대한 액세스 권한을 부여해야 합니다.

사용자 액세스 제어 전략

BigQuery에서는 여러 옵션에 따라 로그에 대한 액세스 권한을 부여할 수 있습니다.

  • Google 그룹을 사용합니다.

    로깅 내보내기 BigQuery 데이터세트에 대한 읽기 전용 액세스 권한이 있는 auditors@example.com과 같은 Google 그룹을 만듭니다. 그런 후 Google 그룹에 감사자를 추가하거나 삭제하여 Google 계정 목록을 관리합니다.

    장점: 그룹을 통해 액세스를 쉽게 관리할 수 있습니다. 사용자 액세스 목적이 명확합니다.

    단점: 그룹의 멤버십을 보지 않으면 누가 액세스 권한이 있는지 알 수 없습니다.

  • 개별 Google 계정을 사용합니다.

    권한이 필요한 개별 사용자의 개별 Google 계정에 로깅 내보내기 BigQuery 데이터세트에 대한 액세스 권한을 부여합니다.

    장점: 각 사용자를 수동 또는 프로그래매틱 방식으로 쉽게 추가할 수 있습니다.

    단점: 다른 뷰어와 감사 사용자를 구분할 수 없습니다.

샘플 질문과 쿼리

감사 로그에는 다양한 쿼리를 실행할 수 있습니다. 이러한 쿼리는 분석을 수행하여 Google Cloud의 데이터에 액세스하는 사용자 또는 시간 경과에 따른 자동 확장 처리의 작동 방식을 파악합니다.

지난 주 데이터에 가장 많이 액세스한 사용자 확인

다음 쿼리는 Data Access Cloud 감사 로그를 사용하여 데이터 액세스 로그에 자주 표시되는 사용자 계정을 찾습니다.

SELECT
   protopayload_auditlog.authenticationInfo.principalEmail,
   COUNT(*) AS COUNTER
FROM
(TABLE_DATE_RANGE(
Logging_export.cloudaudit_googleapis_com_data_access_,
DATE_ADD(CURRENT_TIMESTAMP(),-7,'DAY'),
CURRENT_TIMESTAMP())
)
WHERE
  protopayload_auditlog.methodName = "jobservice.query"
GROUP BY
   protopayload_auditlog.authenticationInfo.principalEmail
ORDER BY
   protopayload_auditlog.authenticationInfo.principalEmail,
   COUNTER desc
LIMIT
  1000

지난 달 'accounts' 테이블에서 데이터에 액세스한 사용자

다음 쿼리는 Data Access Cloud Audit Logs 로그를 사용하여 'accounts' 테이블에 쿼리를 가장 많이 실행한 사용자 계정을 찾습니다. your-project-id는 프로젝트 ID로 바꿉니다.

SELECT
   protopayload_auditlog.authenticationInfo.principalEmail,
   COUNT(*) AS COUNTER
FROM
(TABLE_DATE_RANGE(logging_export.cloudaudit_googleapis_com_data_access_,DATE_ADD(CURRENT_TIMESTAMP(),-30,'DAY'),CURRENT_TIMESTAMP()))
WHERE
  protopayload_auditlog.methodName = "jobservice.query" AND
  protopayload_auditlog.authorizationInfo.permission = "bigquery.tables.getData"
AND
  protopayload_auditlog.authorizationInfo.resource = "projects/your-project-id/datasets/bqtesting/tables/accounts"
GROUP BY
   protopayload_auditlog.authenticationInfo.principalEmail
ORDER BY
   protopayload_auditlog.authenticationInfo.principalEmail,
   COUNTER desc
LIMIT
  1000

지난 주 가상 머신을 삭제한 사용자

다음 쿼리는 Admin Activity Cloud Audit Logs 로그를 사용하여 지난 주 가상 머신을 삭제한 사용자 계정을 찾습니다.

SELECT
  timestamp,
  resource.labels.instance_id,
  protopayload_auditlog.authenticationInfo.principalEmail,
  protopayload_auditlog.resourceName,
  protopayload_auditlog.methodName
FROM
(TABLE_DATE_RANGE(
logging_export.cloudaudit_googleapis_com_activity_,
DATE_ADD(CURRENT_TIMESTAMP(),-7,'DAY'),
CURRENT_TIMESTAMP())
)
WHERE
  resource.type = "gce_instance"
  AND operation.first IS TRUE
  AND protopayload_auditlog.methodName = "v1.compute.instances.delete"
ORDER BY
  timestamp,
  resource.labels.instance_id
LIMIT
  1000

다음 쿼리는 간단한 숫자로 계정을 요약하는 후속 쿼리입니다.

SELECT
  protopayload_auditlog.authenticationInfo.principalEmail,
  count(*) as counter
FROM
(TABLE_DATE_RANGE(
logging_export.cloudaudit_googleapis_com_activity_,
DATE_ADD(CURRENT_TIMESTAMP(),-7,'DAY'),
CURRENT_TIMESTAMP())
)
WHERE
  resource.type = "gce_instance"
  AND operation.first IS TRUE
  AND protopayload_auditlog.methodName = "v1.compute.instances.delete"
GROUP BY
  protopayload_auditlog.authenticationInfo.principalEmail
ORDER BY
  protopayload_auditlog.authenticationInfo.principalEmail,
  counter
LIMIT
  1000

다음 쿼리는 Admin Activity Cloud 감사 로그를 사용하여 지난 달 자동 확장이 사용된 횟수를 찾습니다.

SELECT
  protopayload_auditlog.methodName,
  COUNT(*) AS counter
FROM
(TABLE_DATE_RANGE(
logging_export.cloudaudit_googleapis_com_activity_,
DATE_ADD(CURRENT_TIMESTAMP(),-30,'DAY'),
CURRENT_TIMESTAMP())
)
WHERE
  resource.type = "gce_instance_group_manager"
GROUP BY
  protopayload_auditlog.methodName,
ORDER BY
  protopayload_auditlog.methodName
LIMIT
  1000

다음 쿼리를 사용하면 시간 경과에 따른 Compute Engine 인스턴스 관리자 작업의 추세를 시각화할 수 있습니다.

SELECT
  timestamp,
  protopayload_auditlog.methodName AS methodName,
  COUNT(*) AS counter
FROM
(TABLE_DATE_RANGE(
logging_export.cloudaudit_googleapis_com_activity_,
DATE_ADD(CURRENT_TIMESTAMP(),-30,'DAY'),
CURRENT_TIMESTAMP())
)
WHERE
  resource.type = "gce_instance_group_manager"
GROUP BY
  timestamp,
  methodName
ORDER BY
  timestamp,
  methodName

다음 그래프에 표시된 것처럼 이전 쿼리를 Google Data Studio에서 데이터 소스 커스텀 쿼리로 사용해서 시간 경과에 따른 추세를 시각화할 수 있습니다.

Data Studio 시각화

자세한 내용은 Data Studio 커스텀 쿼리를 참조하세요.

가장 많이 액세스된 데이터 세트와 액세스한 사용자

다음 쿼리는 Data Access Cloud 감사 로그를 사용해서 가장 많이 액세스된 BigQuery 데이터세트를 찾고 그러한 횟수와 연결된 사용자 계정을 표시합니다.

SELECT
  protopayload_auditlog.authorizationInfo.resource,
  protopayload_auditlog.authenticationInfo.principalEmail,
  COUNT(*) AS counter
FROM
(TABLE_DATE_RANGE(
logging_export.cloudaudit_googleapis_com_data_access_,
DATE_ADD(CURRENT_TIMESTAMP(),-30,'DAY'),
CURRENT_TIMESTAMP())
)
WHERE
  protopayload_auditlog.authorizationInfo.permission = "bigquery.tables.getData"
GROUP BY
  protopayload_auditlog.authorizationInfo.resource,
  protopayload_auditlog.authenticationInfo.principalEmail
ORDER BY
  protopayload_auditlog.authorizationInfo.resource,
  protopayload_auditlog.authenticationInfo.principalEmail,
  counter DESC
LIMIT
  1000

지난 주 BigQuery에서 수행된 최상위 10개 쿼리

다음 쿼리는 Data Access Cloud 감사 로그를 사용해서 가장 많이 수행된 쿼리를 찾습니다.

SELECT
  protopayload_auditlog.servicedata_v1_bigquery.jobQueryRequest.query,
  COUNT(*) AS counter
FROM
(TABLE_DATE_RANGE(
Logging_export.cloudaudit_googleapis_com_data_access_,
DATE_ADD(CURRENT_TIMESTAMP(),-7,'DAY'),
CURRENT_TIMESTAMP()))
WHERE
  protopayload_auditlog.methodName = "jobservice.query"
GROUP BY
  protopayload_auditlog.servicedata_v1_bigquery.jobQueryRequest.query
ORDER BY
  counter DESC
LIMIT
  1000

지난 30일 동안 데이터 액세스 로그에 기록된 가장 일반적인 작업

다음 쿼리는 Data Access Cloud 감사 로그를 사용해서 지난 30일 동안 기록된 가장 일반적인 작업을 찾습니다.

SELECT
  protopayload_auditlog.methodName,
  resource.type,
  COUNT(*) AS counter
FROM
(TABLE_DATE_RANGE(
logging_export.cloudaudit_googleapis_com_data_access_,
DATE_ADD(CURRENT_TIMESTAMP(),-30,'DAY'),
CURRENT_TIMESTAMP())
)
GROUP BY
  protopayload_auditlog.methodName,
  resource.type
ORDER BY
  COUNTER DESC
LIMIT
  1000

다음 단계