LoginSignup
12
2

More than 1 year has passed since last update.

Artifact Registry と Container Analysis を試す

Posted at

はじめに

Artifact Registry を利用する機会があったので、確認した内容と実際に試した設定を記載する
また、Container Analysis についても Artifact Registry に対して Automatic scanning (Container Scanning API) と、Artifact Registry とローカルイメージへの Manual scanning (On-Demand Scanning API) を試したのでその内容も記載する

Artifact Registry

概要

Artifact Registry は従来の Container Registry の機能を拡張したもので、
Docker イメージに加えて、言語・OSパッケージ管理も提供している
Container Registry と違い、1つのプロジェクト内に複数のリポジトリを作成可能で、その他にも様々な拡張がされている

レジストリ形式

提供しているレジストリ機能は 2021.09.04 時点で、下記の通り (ドキュメント・サポートされている形式)
Docker V2, OCI, Helm, Java(Preview), Node.js(Preview), Python(Preview), Debian(Preview), RPM(Preview)

スクリーンショット 2021-09-04 15.01.18.png

ロケーション

Artifact Registry は リージョンマルチリージョン選択可能で、
リージョンを選択すれば日本国内 (asia-northeast1, asia-norteast2) に限定することが可能 (2021.09.04 時点、デュアルリージョン (ASIA1 etc.) は選択できなかった)
※ Container Registry は US, EU, ASIA でのマルチリージョンのみ選択可能で、日本国内・特定リージョンに限定にできない

スクリーンショット 2021-09-04 14.59.25.png

セキュリティ

アクセス制御 (権限)

Artifact Registry 用の Role は下記 4つ用意されており、詳細の権限はドキュメントを参照
下に行くほど権限が強くなる (上ロールの権限を下のロールは全て含む)

  • roles/artifactregistry.reader
  • roles/artifactregistry.writer
  • roles/artifactregistry.repoAdmin
  • roles/artifactregistry.admin
GKE クラスタでの Artifact Registry 利用

GKE クラスタは、次の要件がすべて満たされていれば、追加設定なしでコンテナを pull できる(ドキュメント)

  • GKE が Artifact Registry と同じプロジェクトにある
  • ノードはデフォルトのサービス アカウントを使用している
  • サポートされているバージョンの GKE を実行している

カスタム サービス アカウント を利用している場合は、必要な権限をユーザアカウントと同じく付与する

セキュリティスキャン / Container Analysis

Container Analysis を使用してコンテナの脆弱性スキャンが可能
オンデマンドスキャン (On-Demand Scanning API)と自動スキャン(Container Scanning API)がある

オンデマンドスキャンは、gcloud ツールを使用して、ローカルまたはリモートのレジストリ(Artifact / Container Registry) 内のコンテナイメージをスキャンできる

自動スキャンは、Artifact Registry および Container Registry のコンテナイメージに対して自動で脆弱性スキャンを実行できる
また、継続的に分析も実施し、新たな脆弱性に対しても対応する

脆弱性情報のソース(Vulnerability sources)や、サポートしているOS(Supported versions)は他コンテナセキュリティ製品と比較すると限定的な印象

Binary Authorization

Binary Authorization と連携可能
Binary Authorization を使用すると、GKE などに信頼できるコンテナイメージのみデプロイ可能に制限することが可能

データ保護

VPC Service Controls に対応しており、保護境界線(Perimeter) を設けて、API 保護によるデータ保護が可能
他プロジェクトやオンプレミス接続(VPN or Interconnect) 以外からのアクセスを deny など可能で、アクセス制御が可能

暗号化

デフォルト設定で Google が管理する暗号鍵で暗号化され、顧客管理の暗号鍵 CMEK も設定可能(ドキュメント)

ログ

監査ログ (Audit log) に出力される (常に有効で、無効化できない)
対応しているレジストリは Docker のみ (2021.09.04時点)
詳細はドキュメント参照

コスト

利用で必要になる費用は下記の通り (2021.09.05時点)

ストレージは 0.5GB/月 の無料枠があり、0.5GB 超えたら $0.10/GB
ネットワーク費用など細かいのはドキュメント先を参照

コンテナスキャンは $0.26/image (ドキュメント) (無料枠はない)

設定

コンテナレジストリ (Dockerリポジトリ) を作成して、イメージの push / pull および脆弱性スキャンを試す

API 有効化

Arififact Registry API (artifactregistry.googleapis.com) を有効化する

スクリーンショット 2021-09-04 14.53.34.png

スクリーンショット 2021-09-04 14.43.21.png

Terraform のコード例は下記の通り

# Arififact Registry API 有効化
resource "google_project_service" "artifactregistry" {
  project                    = google_project.your_project.id
  disable_dependent_services = true
  service                    = "artifactregistry.googleapis.com"
}

gcloud だと下記 (プロジェクト指定時は --project [your_project name] を付ける)

gcloud services enable artifactregistry.googleapis.com

コンテナレジストリの作成

Artifact Registry -> リポジトリ を開いて、+リポジトリの作成をクリック

スクリーンショット 2021-09-05 15.03.15.png

必要項目を入力して作成

スクリーンショット 2021-09-05 15.08.03.png

完了すると、一覧に表示される

スクリーンショット 2021-09-05 15.09.18.png

下記は terrform code 例 (google_artifact_registry_repositoryprovider = google-betaである必要がある(2021.09.05時点))

resource "google_artifact_registry_repository" "my-repo" {
  provider     = google-beta
  project      = google_project.your-project.name

  location      = "us-east1"
  repository_id = "my-repository"
  description   = "my docker repository"
  format        = "DOCKER"
}

必要に応じて、権限を付与する (roleの種類・権限詳細はドキュメントを参照)

下記は terraform で、admin権限(roles/artifactregistry.admin)を付与する例

resource "google_artifact_registry_repository_iam_member" "test-iam" {
  provider         = google-beta
  project      = google_project.your-project.name

  location     = google_artifact_registry_repository.my-repo.location
  repository = google_artifact_registry_repository.my-repo.name
  role           = "roles/artifactregistry.admin"
  member         = "serviceAccount:${google_service_account.your-account.email}"
}

脆弱性スキャンの有効化

Container Analysis の API (Container Analysis API) と、
脆弱性スキャン(自動)の API (Container Scanning API) を有効化する

スクリーンショット 2021-09-05 20.23.02.png

スクリーンショット 2021-09-04 16.08.06.png

# Container Analysis API 有効化
resource "google_project_service" "containeranalysis" {
  project                    = google_project.your_project.id
  disable_dependent_services = true
  service                    = "containeranalysis.googleapis.com"
}

# Container Scanning API 有効化
resource "google_project_service" "containerscanning" {
  project                    = google_project.your_project.id
  disable_dependent_services = true
  service                    = "containerscanning.googleapis.com"
}

また、下記 Artifact Registry の設定画面でのオンにするをクリックすれば API が有効化もされる

スクリーンショット 2021-09-04 15.53.15.png

以上で、Artifact Registry, 脆弱性スキャン(自動)の設定完了

認証設定

docker push / pull する端末側の設定を実施する

sudo なしで docker コマンド操作が必要なので、下記を実施してなければ実施すること (環境によっては、再ログインや reboot が必要)

linux
sudo usermod -a -G docker ${USER}

認証方法は複数あるが、ここでは gcloud で認証する方法(推奨)で進める

gcloud での認証がまだの場合は、下記のユーザアカウント認証もしくはサービスアカウント認証のどちらかを実施

ユーザアカウント認証
gcloud auth login
サービスアカウント認証
gcloud auth activate-service-account ACCOUNT --key-file=KEY-FILE 

下記、利用するゾーンに対する docker コンフィグ生成を実施する([ZONE_NAME]-docker.pkg.dev形式でカンマ区切りで複数指定可能)

認証(ここではus-east1,asia-northeast1を指定する例)
gcloud auth configure-docker us-east1-docker.pkg.dev,asia-northeast1-docker.pkg.dev

下記、実施出力例

configure-docker例(途中でY入力が必要)
% gcloud auth configure-docker us-east1-docker.pkg.dev,asia-northeast1-docker.pkg.dev

Adding credentials for: us-east1-docker.pkg.dev,asia-northeast1-docker.pkg.dev
After update, the following will be written to your Docker config file
 located at [/home/[USR_NAME]/.docker/config.json]:
 {
  "credHelpers": {
    "us-east1-docker.pkg.dev": "gcloud",
    "asia-northeast1-docker.pkg.dev": "gcloud"
  }
}

Do you want to continue (Y/n)?  Y

Docker configuration file updated.


To take a quick anonymous survey, run:
  $ gcloud survey

以上で、docker pull / push する準備完了

image push pull scan

実際に、docker の push / pull および自動脆弱性スキャンの結果の確認を実施する (例として nginx コンテナイメージで進める)

試験用の nginx を落とす

% docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a330b6cecb98: Pull complete 
5ef80e6f29b5: Pull complete 
f699b0db74e3: Pull complete 
0f701a34c55e: Pull complete 
3229dce7b89c: Pull complete 
ddb78cb2d047: Pull complete 
Digest: sha256:a05b0cdd4fc1be3b224ba9662ebdf98fe44c09c0c9215b45f84344c12867002e
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
% docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    822b7ec2aaf2   47 hours ago   133MB

作成したコンテナレジストリへ push するために tag で名前を変える

docker tag nginx us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx

下記 tag 実施例

出力
% docker tag nginx us-east1-docker.pkg.dev/suzuyu-service295-dev/my-repository/nginx
% docker images                                                                     
REPOSITORY                                                          TAG       IMAGE ID       CREATED        SIZE
nginx                                                               latest    822b7ec2aaf2   47 hours ago   133MB
us-east1-docker.pkg.dev/suzuyu-service295-dev/my-repository/nginx   latest    822b7ec2aaf2   47 hours ago   133MB

docker push で作成したコンテナレジストリへアップロードする

docker push us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx

下記実施例

push実施例
% docker push us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx                        
Using default tag: latest
The push refers to repository [us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx]
d47e4d19ddec: Pushed 
8e58314e4a4f: Pushed 
ed94af62a494: Pushed 
875b5b50454b: Pushed 
63b5f2c0d071: Pushed 
d000633a5681: Pushed 
latest: digest: sha256:6bf47794f923462389f5a2cda49cf5777f736db8563edc3ff78fb9d87e6e22ec size: 1570

push が完了すると、作成したリポジトリにnginxが追加される

スクリーンショット 2021-09-05 15.47.49.png

名前(ここではnginx)をクリックすると詳細がみれる

スクリーンショット 2021-09-05 15.48.04.png

脆弱性スキャン(containerscanning.googleapis.com)を有効化していると、脆弱性スキャンが実施されスキャン結果が見れる

スクリーンショット 2021-09-05 19.01.44.png

pull は push 同様にリポジトリ指定して pull する

pull実施例
% docker pull us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx
Using default tag: latest
latest: Pulling from [PROJECT_NAME]/my-repository/nginx
Digest: sha256:6bf47794f923462389f5a2cda49cf5777f736db8563edc3ff78fb9d87e6e22ec
Status: Image is up to date for us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx:latest
us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx:latest

ondemand scaning

コンテナスキャンは自動だけではなく、オンデマンドでのスキャンも可能
オンデマンドスキャンを使用することで、実際にコンテナをレジストリへ push する前にスキャンを実施して、実際に push するかを判断できる
下記、オンデマンドスキャンの環境準備と有効化、実施内容を記載する

設定

docker 操作をする環境に google-cloud-sdk-local-extractをインストールする

RedHat/Fedora/CentOSの場合
sudo yum install google-cloud-sdk-local-extract --enablerepo=google-cloud-sdk

コンテナレジストリがあるプロジェクトの On-Demand Scanning API を有効化する

スクリーンショット 2021-09-05 16.13.43.png

terraform の場合は下記

# Container Scanning API 有効化
resource "google_project_service" "ondemandscanning" {
  project                    = google_project.your_project.id
  disable_dependent_services = true
  service                    = "ondemandscanning.googleapis.com"
}

オンデマンドスキャンの実施 (gcloud artifacts docker images scan)

オンデマンドスキャンについては gcloud コマンドで実施する (ドキュメント)

gcloud --project [PROJECT_NAME] artifacts docker images scan [ローカルイメージ名]

スキャンした結果は、上記の最後の行の scna: [SCAN_NAME] を指定して確認可能 (ドキュメント

gcloud artifacts docker images list-vulnerabilities SCAN_NAME [--limit=X]
ローカルスキャン

下記、実施した際の出力例
まずは、ローカルイメージに対して(push前/Artifact Registry 保存無) 脆弱性スキャンをして、結果を確認した
※脆弱性結果はここでは2個だけ表示だが、実際は36個あった.severity: HIGH は 1つ (CVE-2021-33574)だった (2021.09.05時点)

% docker image pull debian                                                   
Using default tag: latest
latest: Pulling from library/debian
955615a668ce: Pull complete 
Digest: sha256:08db48d59c0a91afb802ebafc921be3154e200c452e4d0b19634b426b03e0e25
Status: Downloaded newer image for debian:latest
docker.io/library/debian:latest

% gcloud --project [PROJECT_NAME] artifacts docker images scan debian 
✓ Scanning container image                                                                                                                                                                 
  ✓ Locally extracting packages and versions from local container image                                                                                                                    
  ✓ Remotely initiating analysis of packages and versions                                                                                                                                  
  ✓ Waiting for analysis operation to complete [projects/[PROJECT_NAME]/locations/us/operations/fd8c93ec-0ff1-4d30-b8bf-603b85879bdb]                                               
Done.                                                                                                                                                                                      
done: true
metadata:
  '@type': type.googleapis.com/google.cloud.ondemandscanning.v1.AnalyzePackagesMetadata
  createTime: '2021-09-05T10:19:11.511893Z'
  resourceUri: debian
name: projects/[PROJECT_NAME]/locations/us/operations/fd8c93ec-0ff1-4d30-b8bf-603b85879bdb
response:
  '@type': type.googleapis.com/google.cloud.ondemandscanning.v1.AnalyzePackagesResponse
  scan: projects/[PROJECT_NAME]/locations/us/scans/ae0c35bc-6793-4c3d-b54d-60c160d74c95

% gcloud artifacts docker images list-vulnerabilities projects/[PROJECT_NAME]/locations/us/scans/ae0c35bc-6793-4c3d-b54d-60c160d74c95 --limit=2
---
createTime: '2021-09-05T10:19:12.233540Z'
kind: VULNERABILITY
name: projects/[PROJECT_NAME]/locations/us/occurrences/0410fcb8-dbd1-4637-bb7e-8bfe43859320
noteName: projects/goog-vulnz/notes/CVE-2013-4392
resourceUri: debian
updateTime: '2021-09-05T10:19:12.233540Z'
vulnerability:
  cvssScore: 3.3
  effectiveSeverity: LOW
  packageIssue:
  - affectedCpeUri: cpe:/o:debian:debian_linux:11
    affectedPackage: systemd
    affectedVersion:
      kind: NORMAL
      name: '247.3'
      revision: '6'
    effectiveSeverity: LOW
    fixedCpeUri: cpe:/o:debian:debian_linux:11
    fixedPackage: systemd
    fixedVersion:
      kind: MAXIMUM
  severity: LOW
---
createTime: '2021-09-05T10:19:12.233540Z'
kind: VULNERABILITY
name: projects/[PROJECT_NAME]/locations/us/occurrences/04eb37b6-2d81-42c1-ac51-974d633e546b
noteName: projects/goog-vulnz/notes/CVE-2017-18018
resourceUri: debian
updateTime: '2021-09-05T10:19:12.233540Z'
vulnerability:
  cvssScore: 1.9
  effectiveSeverity: LOW
  packageIssue:
  - affectedCpeUri: cpe:/o:debian:debian_linux:11
    affectedPackage: coreutils
    affectedVersion:
      kind: NORMAL
      name: '8.32'
      revision: '4'
    effectiveSeverity: LOW
    fixedCpeUri: cpe:/o:debian:debian_linux:11
    fixedPackage: coreutils
    fixedVersion:
      kind: MAXIMUM
  severity: LOW
リモート(レジストリ)スキャン

次に、ローカルではなくすでに Artifact Registry に格納済みのイメージへのスキャンを実施する
--remoteをつけることで、ローカルではないイメージのスキャンになる(つけないとローカルイメージのスキャン)

例で作成したnginxの場合(ArtifactRegistry側の実施)
gcloud --project [PROJECT_NAME]/ artifacts docker images scan us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx --remote

下記実施出力例 (リモート実施を明確化するために、最初にローカルの同名イメージを削除してから実施した)

ondemandscan出力例
% docker image rm us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx
Untagged: us-east1-docker.pkg.dev/s[PROJECT_NAME]/my-repository/nginx:latest
Untagged: us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx@sha256:6bf47794f923462389f5a2cda49cf5777f736db8563edc3ff78fb9d87e6e22ec

% gcloud --project [PROJECT_NAME] artifacts docker images scan us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx --remote
✓ Scanning container image                                                                                                                                                                
  ✓ Locally extracting packages and versions from remote container image                                                                                                                  
  ✓ Remotely initiating analysis of packages and versions                                                                                                                                 
  ✓ Waiting for analysis operation to complete [projects/[PROJECT_NAME]/locations/us/operations/a4e493f9-669a-4ec5-9b93-48456dbe6ebe]                                              
Done.                                                                                                                                                                                     
done: true
metadata:
  '@type': type.googleapis.com/google.cloud.ondemandscanning.v1.AnalyzePackagesMetadata
  createTime: '2021-09-05T10:54:57.568581Z'
  resourceUri: us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx
name: projects/[PROJECT_NAME]/locations/us/operations/a4e493f9-669a-4ec5-9b93-48456dbe6ebe
response:
  '@type': type.googleapis.com/google.cloud.ondemandscanning.v1.AnalyzePackagesResponse
  scan: projects/[PROJECT_NAME]/locations/us/scans/79bdf741-ea61-4225-906a-996b20d88fb6
オンデマンドスキャン実施_出力例
% gcloud artifacts docker images list-vulnerabilities  projects/[PROJECT_NAME]/locations/us/scans/79bdf741-ea61-4225-906a-996b20d88fb6 --limit=2
---
createTime: '2021-09-05T10:54:59.324273Z'
kind: VULNERABILITY
name: projects/[PROJECT_NAME]/locations/us/occurrences/0974b53b-761e-4ce9-95a0-642b60ddf692
noteName: projects/goog-vulnz/notes/CVE-2020-13776
resourceUri: us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx
updateTime: '2021-09-05T10:54:59.324273Z'
vulnerability:
  cvssScore: 6.2
  effectiveSeverity: LOW
  packageIssue:
  - affectedCpeUri: cpe:/o:debian:debian_linux:10
    affectedPackage: systemd
    affectedVersion:
      kind: NORMAL
      name: '241'
      revision: 7~deb10u8
    effectiveSeverity: LOW
    fixedCpeUri: cpe:/o:debian:debian_linux:10
    fixedPackage: systemd
    fixedVersion:
      kind: MAXIMUM
  severity: MEDIUM
---
createTime: '2021-09-05T10:54:59.324273Z'
kind: VULNERABILITY
name: projects/[PROJECT_NAME]/locations/us/occurrences/13a0a324-25ee-43ca-ac5a-4365880cad9c
noteName: projects/goog-vulnz/notes/CVE-2010-4052
resourceUri: us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx
updateTime: '2021-09-05T10:54:59.324273Z'
vulnerability:
  cvssScore: 5.0
  effectiveSeverity: LOW
  packageIssue:
  - affectedCpeUri: cpe:/o:debian:debian_linux:10
    affectedPackage: glibc
    affectedVersion:
      kind: NORMAL
      name: '2.28'
      revision: '10'
    effectiveSeverity: LOW
    fixedCpeUri: cpe:/o:debian:debian_linux:10
    fixedPackage: glibc
    fixedVersion:
      kind: MAXIMUM
  severity: MEDIUM

以上で、オンデマンドスキャンのテスト実行完了

また、対象外の OS イメージだとスキャンは失敗する

scan失敗例
% gcloud artifacts docker images scan busybox
X Scanning container image                                                                                                                                                                 
  X Locally extracting packages and versions from local container image                                                                                                                    
  . Remotely initiating analysis of packages and versions                                                                                                                                  
  . Waiting for analysis operation to complete                                                                                                                                             
Failed.                                                                                                                                                                                    
ERROR: (gcloud.artifacts.docker.images.scan) Extraction failed: could not detect operating system of image, scan aborted

おわりに

Artifact Registry の内容を確認して、実際に試験実施までできた
Container Registry もあるが、基本的に Artifact Registry を使うのが良い
今後は Binary Authorization で、スキャン結果でデプロイしていいイメージを制御するのも試したい

参考

12
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
2