はじめに
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)
ロケーション
Artifact Registry は リージョン、マルチリージョン が選択可能で、
リージョンを選択すれば日本国内 (asia-northeast1, asia-norteast2) に限定することが可能 (2021.09.04 時点、デュアルリージョン (ASIA1 etc.) は選択できなかった)
※ Container Registry は US
, EU
, ASIA
でのマルチリージョンのみ選択可能で、日本国内・特定リージョンに限定にできない
セキュリティ
アクセス制御 (権限)
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) を有効化する
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 -> リポジトリ を開いて、+リポジトリの作成
をクリック
必要項目を入力して作成
完了すると、一覧に表示される
下記は terrform code 例 (google_artifact_registry_repositoryはprovider = 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) を有効化する
# 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 が有効化もされる
以上で、Artifact Registry, 脆弱性スキャン(自動)の設定完了
認証設定
docker push / pull する端末側の設定を実施する
- 前提条件
- docker をインストール済み Installation methods
- gcloud (Google Cloud SDK) をインストール済み Installation methods
sudo なしで docker コマンド操作が必要なので、下記を実施してなければ実施すること (環境によっては、再ログインや reboot が必要)
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形式でカンマ区切りで複数指定可能)
gcloud auth configure-docker us-east1-docker.pkg.dev,asia-northeast1-docker.pkg.dev
下記、実施出力例
% 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
下記実施例
% 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
が追加される
名前(ここではnginx
)をクリックすると詳細がみれる
脆弱性スキャン(containerscanning.googleapis.com
)を有効化していると、脆弱性スキャンが実施されスキャン結果が見れる
pull は push 同様にリポジトリ指定して 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
をインストールする
sudo yum install google-cloud-sdk-local-extract --enablerepo=google-cloud-sdk
コンテナレジストリがあるプロジェクトの On-Demand Scanning API を有効化する
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
をつけることで、ローカルではないイメージのスキャンになる(つけないとローカルイメージのスキャン)
gcloud --project [PROJECT_NAME]/ artifacts docker images scan us-east1-docker.pkg.dev/[PROJECT_NAME]/my-repository/nginx --remote
下記実施出力例 (リモート実施を明確化するために、最初にローカルの同名イメージを削除してから実施した)
% 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 イメージだとスキャンは失敗する
% 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 で、スキャン結果でデプロイしていいイメージを制御するのも試したい
参考